commit c44c5282dd1980fcf979a72ddd234758b05b0745 Author: Arturo Filastò art@fuffa.org Date: Fri Nov 9 02:00:18 2012 +0100
Finish refactor of the core of OONI. * Everything is passing * XXX there is a bug in blocking tests not making the reactor stop --- before_i_commit.sh | 4 ++-- bin/ooniprobe | 1 + nettests/core/url_list.py | 3 ++- ooni/config.py | 2 ++ ooni/nettest.py | 24 ++++++++++++++++-------- ooni/oonicli.py | 6 +++--- ooni/reporter.py | 6 ++++++ ooni/runner.py | 33 ++++++++++++++++++++++++--------- 8 files changed, 56 insertions(+), 23 deletions(-)
diff --git a/before_i_commit.sh b/before_i_commit.sh index e27fbd2..f08a5f5 100755 --- a/before_i_commit.sh +++ b/before_i_commit.sh @@ -18,11 +18,11 @@ find . -type f -name "*.py[co]" -delete
./bin/ooniprobe -l before_i_commit.log -o dns_tamper_test.yamloo nettests/core/dnstamper.py -t test_inputs/dns_tamper_test_resolvers.txt -f test_inputs/dns_tamper_file.txt
-./bin/ooniprobe -l before_i_commit.log -o captive_portal_test.yamloo nettests/core/captiveportal.py +#./bin/ooniprobe -l before_i_commit.log -o captive_portal_test.yamloo nettests/core/captiveportal.py
./bin/ooniprobe -l before_i_commit.log -o http_host.yamloo nettests/core/http_host.py -b http://ooni.nu/test -f test_inputs/http_host_file.txt
-./bin/ooniprobe -l before_i_commit.log -o keyword_filtering.yamloo nettests/core/keyword_filtering.py -b http://ooni.nu/test/ -f test_inputs/keyword_filtering_file.txt +./bin/ooniprobe -l before_i_commit.log -o http_keyword_filtering.yamloo nettests/core/http_keyword_filtering.py -b http://ooni.nu/test/ -f test_inputs/http_keyword_filtering_file.txt
./bin/ooniprobe -l before_i_commit.log -o url_lists.yamloo nettests/core/url_list.py -f test_inputs/url_lists_file.txt
diff --git a/bin/ooniprobe b/bin/ooniprobe index 18dab7d..9b9885f 100755 --- a/bin/ooniprobe +++ b/bin/ooniprobe @@ -12,6 +12,7 @@
import os, sys import copy_reg +from twisted.internet import reactor
# Hack to set the proper sys.path. Overcomes the export PYTHONPATH pain. sys.path[:] = map(os.path.abspath, sys.path) diff --git a/nettests/core/url_list.py b/nettests/core/url_list.py index a6ed269..43f819e 100644 --- a/nettests/core/url_list.py +++ b/nettests/core/url_list.py @@ -11,7 +11,8 @@ class URLList(httpt.HTTPTest): version = 0.1
inputFile = ['file', 'f', None, 'List of URLS to perform GET and POST requests to'] - + + requiredOptions = ['file'] def test_get(self): if self.input: self.url = self.input diff --git a/ooni/config.py b/ooni/config.py index 5880d69..d3907af 100644 --- a/ooni/config.py +++ b/ooni/config.py @@ -6,6 +6,8 @@ import os import yaml
+from twisted.internet import reactor + from ooni.utils import Storage
def get_root_path(): diff --git a/ooni/nettest.py b/ooni/nettest.py index 14d6ae2..289cd23 100644 --- a/ooni/nettest.py +++ b/ooni/nettest.py @@ -85,6 +85,7 @@ class NetTestCase(object): * requiredOptions: a list containing the name of the options that are required for proper running of a test.
+ * localOptions: contains the parsed command line arguments. """ name = "I Did Not Change The Name" author = "Jane Doe foo@example.com" @@ -103,7 +104,13 @@ class NetTestCase(object): requiredOptions = []
requiresRoot = False - parallelism = 1 + + localOptions = {} + def setUp(self): + """ + Place here your logic to be executed when the test is being setup. + """ + pass
def inputProcessor(self, fp): """ @@ -129,6 +136,12 @@ class NetTestCase(object): for x in fp.xreadlines(): yield x.strip() fp.close() + + def _checkRequiredOptions(self): + for required_option in self.requiredOptions: + log.debug("Checking if %s is present" % required_option) + if not self.localOptions[required_option]: + raise usage.UsageError("%s not specified!" % required_option)
def _processOptions(self, options=None): if self.inputFile: @@ -145,13 +158,8 @@ class NetTestCase(object): elif self.inputFile: raise usage.UsageError("No input file specified!")
- # XXX this is a bit hackish - if options: - for required_option in self.requiredOptions: - log.debug("Checking if %s is present" % required_option) - if not options[required_option]: - raise usage.UsageError("%s not specified!" % required_option) - + self._checkRequiredOptions() + # XXX perhaps we may want to name and version to be inside of a # different method that is not called options. return {'inputs': self.inputs, diff --git a/ooni/oonicli.py b/ooni/oonicli.py index b4d963e..be29b4c 100644 --- a/ooni/oonicli.py +++ b/ooni/oonicli.py @@ -23,7 +23,7 @@ from twisted.application import app from twisted.python import usage, failure from twisted.python.util import spewer
-from ooni import nettest, runner, reporter +from ooni import nettest, runner, reporter, config
from ooni.inputunit import InputUnitFactory from ooni.utils import log @@ -88,10 +88,10 @@ def run(): if cmd_line_options['debug-stacktraces']: defer.setDebugging(True)
+ log.start(cmd_line_options['logfile']) classes = runner.findTestClassesFromConfig(cmd_line_options) test_cases, options = runner.loadTestsAndOptions(classes, cmd_line_options) - log.start(cmd_line_options['logfile']) - + runner.runTestCases(test_cases, options, cmd_line_options) reactor.run()
diff --git a/ooni/reporter.py b/ooni/reporter.py index 52239dd..08a72b2 100644 --- a/ooni/reporter.py +++ b/ooni/reporter.py @@ -226,3 +226,9 @@ class OReporter(YamlReporter): def allDone(self): log.debug("Finished running everything") self.finish() + try: + reactor.stop() + except: + pass + return None + diff --git a/ooni/runner.py b/ooni/runner.py index 46f5a00..c67f2a7 100644 --- a/ooni/runner.py +++ b/ooni/runner.py @@ -46,7 +46,6 @@ def processTest(obj, cmd_line_options): if obj.optParameters or input_file \ or obj.usageOptions or obj.optFlags:
- options = None if not obj.optParameters: obj.optParameters = []
@@ -57,15 +56,25 @@ def processTest(obj, cmd_line_options): if input_file: obj.usageOptions.optParameters.append(input_file) options = obj.usageOptions() - + elif obj.optParameters: + log.debug("Got optParameters") + class Options(usage.Options): + optParameters = obj.optParameters + if obj.optFlags: + log.debug("Got optFlags") + optFlags = obj.optFlags + options = Options() + if options: options.parseOptions(cmd_line_options['subArgs']) obj.localOptions = options
if input_file and options: + log.debug("Got input file") obj.inputFile = options[input_file[0]]
try: + log.debug("processing options") tmp_test_case_object = obj() tmp_test_case_object._processOptions(options)
@@ -139,14 +148,22 @@ def loadTestsAndOptions(classes, cmd_line_options): def runTestWithInputUnit(test_class, test_method, input_unit, oreporter): + """ + test_class: the uninstantiated class of the test to be run + + test_method: a string representing the method name to be called + + input_unit: a generator that contains the inputs to be run on the test + + oreporter: ooni.reporter.OReporter instance + + returns a deferred list containing all the tests to be run at this time + """ def test_done(result, test_instance): oreporter.testDone(test_instance)
def test_error(error, test_instance): - print "Got this error: %s" % error - exc_type, exc_value, exc_traceback = sys.exc_info() - traceback.print_exc() - #oreporter.writeReportEntry(test) + log.err("%s\n" % error)
dl = [] for i in input_unit: @@ -157,9 +174,7 @@ def runTestWithInputUnit(test_class, test_instance._start_time = time.time() # call setup on the test test_instance.setUp() - test = getattr(test_instance, test_method) - d = defer.maybeDeferred(test) d.addCallback(test_done, test_instance) d.addErrback(test_error, test_instance) @@ -200,7 +215,7 @@ def runTestCases(test_cases, options, cmd_line_options): reportFile = open(report_filename, 'w+') oreporter = reporter.OReporter(reportFile) input_unit_factory = InputUnitFactory(test_inputs) - + yield oreporter.writeReportHeader(options) # This deferred list is a deferred list of deferred lists # it is used to store all the deferreds of the tests that