[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