[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [ooni-probe/master] add processTest to NetTest class
commit f7a6a5229c859aa2cc66f307c0b2363ca00346db
Author: aagbsn <aagbsn@xxxxxxxx>
Date: Sat Jan 12 20:35:19 2013 +0000
add processTest to NetTest class
ripped out of runner.py and needs testing
---
ooni/nettest.py | 98 ++++++++++++++++++++++++++++++++++++++++--
ooni/nettesttask.py | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 212 insertions(+), 4 deletions(-)
diff --git a/ooni/nettest.py b/ooni/nettest.py
index ecf7765..511c3da 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -30,6 +30,12 @@ class NetTest(object):
self.report = report
+ def start(self):
+ """
+ Start tests and generate measurements.
+ """
+ raise NotImplementedError
+
def loadNetTest(self, net_test_object):
"""
Creates all the necessary test_cases (a list of tuples containing the
@@ -52,11 +58,16 @@ class NetTest(object):
"""
try:
if os.path.isfile(net_test_object):
- return self._loadNetTestFile(net_test_object)
+ test_cases = self._loadNetTestFile(net_test_object)
except TypeError:
if isinstance(net_test_object, StringIO) or \
isinstance(net_test_object, str):
- return self._loadNetTestString(net_test_object)
+ test_cases = self._loadNetTestString(net_test_object)
+
+ if not test_cases:
+ raise NoTestCasesFound
+
+ return test_cases
def _loadNetTestString(self, net_test_string):
"""
@@ -110,8 +121,79 @@ class NetTest(object):
measurement.netTest = self
yield measurement
-class NoPostProcessor(Exception):
- pass
+ def processTestCasesOptions(self):
+ self.options #XXX is this cmd_line_options?
+
+ # get set of unique classes
+ test_classes = set([])
+ for test_class, test_method in self.test_cases:
+ test_classes.add(test_class)
+
+ #XXX where should the options bound to a test_class get stashed?
+ for test_class in test_classes:
+ options = self._processOptions()
+
+ #XXX: is options passed to init the same as cmd_line_options???
+ def _processTest(self, nettest_test_case, cmd_line_options):
+ """
+ Process the parameters and :class:`twisted.python.usage.Options` of a
+ :class:`ooni.nettest.Nettest`.
+
+ :param obj:
+ An uninstantiated old test, which should be a subclass of
+ :class:`ooni.plugoo.tests.OONITest`.
+
+ :param cmd_line_options:
+ A configured and instantiated :class:`twisted.python.usage.Options`
+ class.
+
+ """
+ obj = nettest_test_case
+ if not hasattr(obj.usageOptions, 'optParameters'):
+ obj.usageOptions.optParameters = []
+
+ if obj.inputFile:
+ obj.usageOptions.optParameters.append(obj.inputFile)
+
+ if obj.baseParameters:
+ for parameter in obj.baseParameters:
+ obj.usageOptions.optParameters.append(parameter)
+
+ if obj.baseFlags:
+ if not hasattr(obj.usageOptions, 'optFlags'):
+ obj.usageOptions.optFlags = []
+ for flag in obj.baseFlags:
+ obj.usageOptions.optFlags.append(flag)
+
+ options = obj.usageOptions()
+
+ options.parseOptions(cmd_line_options['subargs'])
+ obj.localOptions = options
+
+ if obj.inputFile:
+ obj.inputFilename = options[obj.inputFile[0]]
+
+ try:
+ log.debug("processing options")
+ tmp_test_case_object = obj()
+ tmp_test_case_object._checkRequiredOptions()
+
+ except usage.UsageError, e:
+ test_name = tmp_test_case_object.name
+ log.err("There was an error in running %s!" % test_name)
+ log.err("%s" % e)
+ options.opt_help()
+ raise usage.UsageError("Error in parsing command line args for %s" % test_name)
+
+ # who checks for root?
+ if obj.requiresRoot:
+ try:
+ checkForRoot()
+ except NotRootError:
+ log.err("%s requires root to run" % obj.name)
+ sys.exit(1)
+
+ return obj
class NetTestCase(object):
"""
@@ -261,3 +343,11 @@ class NetTestCase(object):
def __repr__(self):
return "<%s inputs=%s>" % (self.__class__, self.inputs)
+class FailureToLoadNetTest(Exception):
+ pass
+class NoPostProcessor(Exception):
+ pass
+class InvalidOption(Exception):
+ pass
+class MissingRequiredOption(Exception):
+ pass
diff --git a/ooni/nettesttask.py b/ooni/nettesttask.py
new file mode 100644
index 0000000..48c5108
--- /dev/null
+++ b/ooni/nettesttask.py
@@ -0,0 +1,118 @@
+from twisted.internet.task import CooperativeTask
+from twisted.internet import defer
+from ooni.reporter import OONIBReporter, YAMLReporter, OONIBReportError
+from ooni.utils import log
+import time
+from twisted.internet.task import cooperate
+
+class NetTestTask(CooperativeTask):
+ """
+ The object produced by a NetTestTaskFactory.
+
+ A NetTestTask wraps a test_ callable with its options and input unit.
+
+ """
+ def __init__(self, test_case, test_input, oonib_reporter=None, yaml_reporter=None):
+ test_class, test_method = test_case
+ #log.debug("Running %s with %s..." % (test_method, test_input))
+ self.oonib_reporter = oonib_reporter
+ self.oonib_reporter = yaml_reporter
+ self.test_instance = test_class()
+ self.test_instance.input = test_input
+ self.test_instance.report = {}
+ self.test_instance._start_time = time.time()
+ self.test_instance._setUp()
+ self.test_instance.setUp()
+ self.test = getattr(self.test_instance, test_method)
+
+ # XXX: override CoordinatedTask methods
+ def start(self): #???
+ d = defer.maybeDeferred(self.test)
+ d.addCallback(self.test_done)
+ d.addErrback(self.test_error)
+ return d
+
+ def write_report(self):
+ if not self.oonib_reporter:
+ return self.yaml_reporter.testDone(self.test_instance, str(self.test))
+ d1 = self.oonib_reporter.testDone(self.test_instance, str(self.test))
+ d2 = self.yaml_reporter.testDone(self.test_instance, str(self.test))
+ dl = defer.DeferredList([d1, d2])
+ @dl.addErrback
+ def reportingFailed(failure):
+ log.err("Error in reporting %s" % self.test)
+ log.exception(failure)
+ return dl
+
+ def test_done(self, result):
+ log.msg("Finished running %s" % self.test)
+ log.debug("Deferred callback result: %s" % result)
+ return self.write_report()
+
+ def test_error(self, failure):
+ log.err("Error in running %s" % self.test)
+ log.exception(failure)
+ return self.write_report()
+
+ #XXX: does not implement tests_done!
+
+class NetTestTaskFactory(object):
+ def __init__(self, test_cases, input_unit_list):
+ self.input_unit_list = input_unit_list
+ self.inputs = self.generate_inputs()
+ self.test_cases = test_cases
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ return self.inputs.next()
+ # XXX: raise exception or fire callback when inputs are exhausted
+
+ def generate_inputs(self):
+ for input_unit in self.input_unit_list:
+ for test_case in self.test_cases:
+ yield NetTestTask(test_case, input_unit)
+
+@xxxxxxxxxxxxxxxxxxxxx
+def runTestCases(test_cases, options, cmd_line_options):
+
+ log.debug("Running %s" % test_cases)
+ log.debug("Options %s" % options)
+ log.debug("cmd_line_options %s" % dict(cmd_line_options))
+
+ test_inputs = options['inputs']
+
+ oonib_reporter = OONIBReporter(cmd_line_options)
+ yaml_reporter = YAMLReporter(cmd_line_options)
+
+ if cmd_line_options['collector']:
+ log.msg("Using remote collector, please be patient while we create the report.")
+ try:
+ yield oonib_reporter.createReport(options)
+ except OONIBReportError:
+ log.err("Error in creating new report")
+ log.msg("We will only create reports to a file")
+ oonib_reporter = None
+ else:
+ oonib_reporter = None
+
+ yield yaml_reporter.createReport(options)
+ log.msg("Reporting to file %s" % yaml_reporter._stream.name)
+
+ nettest_task_factory = NetTestTaskFactory(test_cases, test_inputs)
+
+ #XXX: resume is not supported!
+ try:
+ #XXX: override the default cooperator, set up own scheduler
+ #XXX: add callback when tasks are all exhausted
+ for nettest_task in nettest_task_factory.generate_inputs():
+ nettest_task.yaml_reporter = yaml_reporter
+ nettest_task.oonib_reporter = oonib_reporter
+ log.debug("Running %s with input unit %s" % (nettest_task,
+ nettest_task.test_instance.input))
+ # feed the cooperator
+ nettest_task.start()
+
+ except Exception:
+ log.exception("Problem in running test")
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits