commit 2d31d5f14a0f3a7518d47fe748c1677cbd885828 Author: Arturo Filastò arturo@filasto.net Date: Tue Sep 18 11:52:41 2012 +0000
Get all the pieces together and have a working trial based oonicli --- ooni/nettest.py | 48 +--------------------------------- ooni/oonicli.py | 38 ++++++---------------------- ooni/runner.py | 75 ++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 104 deletions(-)
diff --git a/ooni/nettest.py b/ooni/nettest.py index 097e947..0c8858b 100644 --- a/ooni/nettest.py +++ b/ooni/nettest.py @@ -1,3 +1,4 @@ +import itertools
from twisted.python import log from twisted.trial import unittest, itrial @@ -42,49 +43,4 @@ class TestSuite(pyunit.TestSuite): return result
class TestCase(unittest.TestCase): - """ - A test case represents the minimum - """ - def run(self, result): - """ - Run the test case, storing the results in C{result}. - - First runs C{setUp} on self, then runs the test method (defined in the - constructor), then runs C{tearDown}. As with the standard library - L{unittest.TestCase}, the return value of these methods is disregarded. - In particular, returning a L{Deferred} has no special additional - consequences. - - @param result: A L{TestResult} object. - """ - log.msg("--> %s <--" % (self.id())) - new_result = itrial.IReporter(result, None) - if new_result is None: - result = PyUnitResultAdapter(result) - else: - result = new_result - result.startTest(self) - if self.getSkip(): # don't run test methods that are marked as .skip - result.addSkip(self, self.getSkip()) - result.stopTest(self) - return - - self._passed = False - self._warnings = [] - - self._installObserver() - # All the code inside _runFixturesAndTest will be run such that warnings - # emitted by it will be collected and retrievable by flushWarnings. - unittest._collectWarnings(self._warnings.append, self._runFixturesAndTest, result) - - # Any collected warnings which the test method didn't flush get - # re-emitted so they'll be logged or show up on stdout or whatever. - for w in self.flushWarnings(): - try: - warnings.warn_explicit(**w) - except: - result.addError(self, failure.Failure()) - - result.stopTest(self) - - + name = "DefaultTestName" diff --git a/ooni/oonicli.py b/ooni/oonicli.py index 8eabfb1..fa7742f 100644 --- a/ooni/oonicli.py +++ b/ooni/oonicli.py @@ -116,6 +116,7 @@ class Options(usage.Options, app.ReactorSelectionMixin): ]
optParameters = [ + ["reportfile", "o", "report.yaml", "report file name"], ["logfile", "l", "test.log", "log file name"], ["random", "z", None, "Run tests in random order using the specified seed"], @@ -292,7 +293,7 @@ def _initialDebugSetup(config):
-def _getSuite(config): +def _getSuites(config): loader = _getLoader(config) recurse = not config['no-recurse'] print "loadByNames %s" % config['tests'] @@ -300,7 +301,7 @@ def _getSuite(config):
def _getLoader(config): - loader = runner.TestLoader() + loader = runner.NetTestLoader() if config['random']: randomer = random.Random() randomer.seed(config['random']) @@ -309,7 +310,6 @@ def _getLoader(config): return loader
- def _makeRunner(config): mode = None if config['debug']: @@ -318,6 +318,7 @@ def _makeRunner(config): mode = runner.OONIRunner.DRY_RUN print "using %s" % config['reporter'] return runner.OONIRunner(config['reporter'], + reportfile=config["reportfile"], mode=mode, profile=config['profile'], logfile=config['logfile'], @@ -328,24 +329,6 @@ def _makeRunner(config): forceGarbageCollection=config['force-gc'])
-if 0: - loader = runner.TestLoader() - loader.suiteFactory = TestSuite - - for inputUnit in InputUnitFactory(FooTest.inputs): - print inputUnit - - suite = loader.loadClass(FooTest) - - reporterFactory = ReporterFactory(open('reporting.log', 'a+'), testSuite=suite) - reporterFactory.writeHeader() - #testUnitReport = OONIReporter(open('reporting.log', 'a+')) - #testUnitReport.writeHeader(FooTest) - for inputUnit in InputUnitFactory(FooTest.inputs): - testUnitReport = reporterFactory.create() - suite(testUnitReport, inputUnit) - testUnitReport.done() - def run(): if len(sys.argv) == 1: sys.argv.append("--help") @@ -354,15 +337,10 @@ def run(): config.parseOptions() except usage.error, ue: raise SystemExit, "%s: %s" % (sys.argv[0], ue) + _initialDebugSetup(config) trialRunner = _makeRunner(config) - suite = _getSuite(config) - print suite - test_result = trialRunner.run(suite) - if config.tracer: - sys.settrace(None) - results = config.tracer.results() - results.write_results(show_missing=1, summary=False, - coverdir=config.coverdir().path) - sys.exit(not test_result.wasSuccessful()) + suites = _getSuites(config) + for suite in suites: + test_result = trialRunner.run(suite)
diff --git a/ooni/runner.py b/ooni/runner.py index a8485af..12ab9ad 100644 --- a/ooni/runner.py +++ b/ooni/runner.py @@ -1,13 +1,18 @@ +import os +import sys import types import time import inspect
from twisted.internet import defer -from twisted.python import reflect +from twisted.python import reflect, log, failure from twisted.trial import unittest from twisted.trial.runner import TrialRunner, TestLoader -from twisted.trial.runner import isPackage, isTestCase +from twisted.trial.runner import isPackage, isTestCase, ErrorHolder +from twisted.trial.runner import filenameToModule, _importFromFile
+from ooni.reporter import ReporterFactory +from ooni.input import InputUnitFactory from ooni import nettest from ooni.plugoo import tests as oonitests
@@ -34,6 +39,7 @@ def adaptLegacyTest(obj): pass
+ class LoggedSuite(nettest.TestSuite): """ Any errors logged in this suite will be reported to the L{TestResult} @@ -98,17 +104,8 @@ class NetTestLoader(object):
def __init__(self): self.suiteFactory = nettest.TestSuite - self.sorter = name self._importErrors = []
- def sort(self, xs): - """ - Sort the given things using L{sorter}. - - @param xs: A list of test cases, class or modules. - """ - return sorted(xs, key=self.sorter) -
def findTestClasses(self, module): classes = [] @@ -180,12 +177,12 @@ class NetTestLoader(object): if not isTestCase(klass): raise ValueError("%r is not a test case" % (klass,)) names = self.getTestCaseNames(klass) - print "Names %s" % names - tests = self.sort([self._makeCase(klass, self.methodPrefix+name) - for name in names]) - print "Tests %s" % tests + tests = [] + for name in names: + tests.append(self._makeCase(klass, self.methodPrefix+name)) + suite = self.suiteFactory(tests) - print "Suite: %s" % suite + suite.inputs = klass.inputs return suite loadTestsFromTestCase = loadClass
@@ -289,17 +286,25 @@ class NetTestLoader(object):
@return: A C{TestCase} or C{TestSuite}. """ + print "Loading anything! %s" % thing + ret = None if isinstance(thing, types.ModuleType): if isPackage(thing): - return self.loadPackage(thing, recurse) - return self.loadModule(thing) + ret = self.loadPackage(thing, recurse) + ret = self.loadModule(thing) elif isinstance(thing, types.ClassType): - return self.loadClass(thing) + ret = self.loadClass(thing) elif isinstance(thing, type): - return self.loadClass(thing) + ret = self.loadClass(thing) elif isinstance(thing, types.MethodType): - return self.loadMethod(thing) - raise TypeError("No loader for %r. Unrecognized type" % (thing,)) + ret = self.loadMethod(thing) + if not ret: + raise TypeError("No loader for %r. Unrecognized type" % (thing,)) + try: + ret.inputs = ret.inputs + except: + ret.inputs = [None] + return ret
def loadByName(self, name, recurse=False): """ @@ -312,6 +317,7 @@ class NetTestLoader(object):
@param name: The fully-qualified name of a Python object. """ + print "Load by Name!" try: thing = self.findByName(name) except: @@ -326,6 +332,7 @@ class NetTestLoader(object): suite returned will have no duplicate tests, even if the same object is named twice. """ + print "Load by Names!" things = [] errors = [] for name in names: @@ -336,7 +343,8 @@ class NetTestLoader(object): suites = [self.loadAnything(thing, recurse) for thing in self._uniqueTests(things)] suites.extend(errors) - return self.suiteFactory(suites) + return suites + #return self.suiteFactory(suites)
def _uniqueTests(self, things): @@ -355,8 +363,6 @@ class NetTestLoader(object): return [entry[0] for entry in set(entries)]
- - class OONIRunner(object): """ A specialised runner that is used by the ooniprobe frontend to run tests. @@ -407,6 +413,7 @@ class OONIRunner(object): return reporter
def __init__(self, reporterFactory, + reportfile="report.yaml", mode=None, logfile='test.log', stream=sys.stdout, @@ -417,6 +424,7 @@ class OONIRunner(object): workingDirectory=None, forceGarbageCollection=False): self.reporterFactory = reporterFactory + self._reportfile = reportfile self.logfile = logfile self.mode = mode self.stream = stream @@ -449,12 +457,21 @@ class OONIRunner(object): self._logFileObserver = log.FileLogObserver(logFile) log.startLoggingWithObserver(self._logFileObserver.emit, 0)
- def run(self, test, inputs): + def run(self, test): """ Run the test or suite and return a result object. """ - for input in inputs: - self._runWithInput(test, input) + print test + inputs = test.inputs + reporterFactory = ReporterFactory(open(self._reportfile, 'a+'), + testSuite=test) + reporterFactory.writeHeader() + #testUnitReport = OONIReporter(open('reporting.log', 'a+')) + #testUnitReport.writeHeader(FooTest) + for inputUnit in InputUnitFactory(inputs): + testUnitReport = reporterFactory.create() + test(testUnitReport, inputUnit) + testUnitReport.done()
def _runWithInput(self, test, input): """ @@ -482,3 +499,5 @@ class OONIRunner(object): done = getattr(result, 'done', None) result.done() return result + +