[tor-commits] [ooni-probe/master] Add loadNetTest to NetTest
isis at torproject.org
isis at torproject.org
Sun Mar 10 01:57:01 UTC 2013
commit c3fcff4e4a68ad98507e2abb18b64790e7239c70
Author: aagbsn <aagbsn at extc.org>
Date: Sat Jan 12 12:05:32 2013 +0000
Add loadNetTest to NetTest
loadNetTest populates the test_cases from a file on disk or a file-like object
like StringIO
(cherry picked from commit c1cabc5a0e510cf38a59a5591630c61cb0983978)
Conflicts:
ooni/measurements.py
---
ooni/measurements.py | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 161 insertions(+), 0 deletions(-)
diff --git a/ooni/measurements.py b/ooni/measurements.py
new file mode 100644
index 0000000..86d6f84
--- /dev/null
+++ b/ooni/measurements.py
@@ -0,0 +1,161 @@
+from .tasks import TaskWithTimeout
+from inspect import getmembers
+from ooni.nettest import NetTestCase
+from ooni.ratelimiting import StaticRateLimiter
+from twisted.python.reflect import prefixedMethodNames
+from twisted.trial.runner import filenameToModule
+from StringIO import StringIO
+from os.path import isfile
+
+class Measurement(TaskWithTimeout):
+ def __init__(self, test_class, test_method, test_input, net_test):
+ """
+ test_class:
+ is the class, subclass of NetTestCase, of the test to be run
+
+ test_method:
+ is a string representing the test method to be called to perform
+ this measurement
+
+ test_input:
+ is the input to the test
+ """
+ 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)
+
+ def succeeded(self):
+ self.net_test.measurementSuccess()
+
+ def failed(self):
+ self.net_test.measurementFailed()
+
+ def timedOut(self):
+ self.net_test.measurementTimeOut()
+
+ def run(self):
+ d = defer.maybeDeferred(self.test)
+ d.addCallback(self.succeeded)
+ d.addErrback(self.failed)
+ return d
+
+class NetTest(object):
+ director = None
+ method_prefix = 'test'
+
+ def __init__(self, net_test_file, inputs, options, report):
+ """
+ net_test_file:
+ is a file object containing the test to be run.
+
+ inputs:
+ is a generator containing the inputs to the net test.
+
+ options:
+ is a dict containing the options to be passed to the net test.
+ """
+ self.test_cases = self.loadNetTest(net_test_file)
+ self.inputs = inputs
+ self.options = options
+
+ def loadNetTest(self, net_test_object):
+ """
+ Creates all the necessary test_cases (a list of tuples containing the
+ NetTestCase (test_class, test_method))
+
+ example:
+ [(test_classA, test_method1),
+ (test_classA, test_method2),
+ (test_classA, test_method3),
+ (test_classA, test_method4),
+ (test_classA, test_method5),
+
+ (test_classB, test_method1),
+ (test_classB, test_method2)]
+
+ Note: the inputs must be valid for test_classA and test_classB.
+
+ net_test_object:
+ is a file like object that will be used to generate the test_cases.
+ """
+ try:
+ if isfile(net_test_object):
+ return 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)
+
+ def _loadNetTestString(self, net_test_string):
+ """
+ Load NetTest from a string
+ """
+ ns = {}
+ test_cases = []
+ exec net_test_string.read() in ns
+ for item in ns.itervalues():
+ test_cases.extend(self._get_test_methods(item))
+ return test_cases
+
+ def _loadNetTestFile(self, net_test_file):
+ """
+ Load NetTest from a file
+ """
+ test_cases = []
+ module = filenameToModule(net_test_file)
+ for __, item in getmembers(module):
+ test_cases.extend(self._get_test_methods(item))
+ return test_cases
+
+ def _get_test_methods(self, item):
+ """
+ Look for test_ methods in subclasses of NetTestCase
+ """
+ test_cases = []
+ try:
+ assert issubclass(item, NetTestCase)
+ methods = prefixedMethodNames(item, self.method_prefix)
+ for method in methods:
+ test_cases.append((item, self.method_prefix + method))
+ except (TypeError, AssertionError):
+ pass
+ return test_cases
+
+ def timedOut(self, measurement):
+ """
+ This gets called when a measurement has timed out. This may or may not
+ trigger a retry inside of MeasurementsTracker.
+ """
+ self.director.measurementTimedOut(measurement)
+
+ def failed(self, measurement, failure):
+ """
+ This gets called when a measurement has failed in the sense that all
+ the retries have failed at successfully running the test.
+ This means that it's a definitive failure and we will no longer make
+ any attempts at re-running the measurement.
+ """
+ self.director.measurementFailed(measurement, failure)
+
+ def succeeded(self, measurement):
+ """
+ This gets called when a measurement has failed.
+ """
+ self.report.write(measurement)
+
+ def generateMeasurements(self):
+ """
+ This is a generator that yields measurements and sets their timeout
+ value and their netTest attribute.
+ """
+ for test_input in self.inputs:
+ for test_class, test_method in self.test_cases:
+ measurement = Measurement(test_class, test_method, test_input)
+ measurement.netTest = self
+ measurement.timeout = self.rateLimiter.timeout
+ yield measurement
+
More information about the tor-commits
mailing list