[tor-commits] [ooni-probe/master] * Still working on NetTestAdaptor

isis at torproject.org isis at torproject.org
Sun Nov 4 13:50:41 UTC 2012


commit 743e6f57cf72058a253134cce092aad9ea95379a
Author: Isis Lovecruft <isis at torproject.org>
Date:   Sun Nov 4 12:28:36 2012 +0000

    * Still working on NetTestAdaptor
    * Fixed so many errors in pretty much everything that I can't even count.
---
 ooni/nettest.py          |  136 ++++++++++++++++++++++------------
 ooni/runner.py           |  187 ++++++++++++++-------------------------------
 ooni/templates/scapyt.py |    4 +-
 3 files changed, 148 insertions(+), 179 deletions(-)

diff --git a/ooni/nettest.py b/ooni/nettest.py
index 7f9f72c..03e391e 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -25,6 +25,7 @@ from ooni.utils import log
 
 pyunit = __import__('unittest')
 
+
 class InputTestSuite(pyunit.TestSuite):
     """
     This in an extension of a unittest test suite. It adds support for inputs
@@ -70,13 +71,14 @@ class NetTestAdaptor(unittest.TestCase):
     XXX fill me in
     """
 
-    @classmethod
-    def __new__(cls, *args, **kwargs):
-        if hasattr(cls, "setUpClass"):
-            super( NetTestAdaptor, cls ).setUpClass(cls)
-        else:
-            log.debug("NetTestAdaptor: constructor could not find setUpClass")
-        return super( NetTestAdaptor, cls ).__new__(cls, *args, **kwargs)
+    # @classmethod
+    # def __new__(cls, *args, **kwargs):
+    #     try:
+    #         setUpClass()
+    #     except Exception, e:
+    #         log.debug("NetTestAdaptor: constructor could not find setUpClass")
+    #         log.err(e)
+    #     return super( NetTestAdaptor, cls ).__new__(cls, *args, **kwargs)
 
     def __init__(self, *args, **kwargs):
         """
@@ -114,10 +116,12 @@ class NetTestAdaptor(unittest.TestCase):
         #self._input_parser = copyattr("inputParser", alt=__input_parser__)
         #self._nettest_name = copyattr("name", alt="NetTestAdaptor"))
 
-        if self.parsed_inputs:
-            self.inputs = self.parsed_inputs
-        else:
-            log.debug("Unable to find parsed inputs")
+        #self.setUpClass(self.__class__)
+
+        #if hasattr(self, parsed_inputs):
+        #    self.inputs = self.parsed_inputs
+        #else:
+        #    log.debug("Unable to find parsed inputs")
 
     @staticmethod
     def __copyattr__(obj, old, new=None, alt=None):
@@ -220,7 +224,8 @@ class NetTestAdaptor(unittest.TestCase):
                         pass       ## don't burn cycles on testing null inputs
                     else:
                         log.msg("Received direct inputs:\n%s" % cls._raw_inputs)
-                        parsed.extend([cls._input_parser(x) for x in cls._raw_inputs])
+                        parsed.extend(
+                            [cls._input_parser(x) for x in cls._raw_inputs])
             elif isinstance(cls._raw_inputs, str):
                 separated = cls._raw_inputs.translate(None, ',') ## space delineates
                 inputlist = separated.split(' ')
@@ -229,43 +234,83 @@ class NetTestAdaptor(unittest.TestCase):
                 log.debug("inputs not string or list; type: %s"
                           % type(cls._raw_inputs))
 
+        if cls.subarg_inputs:
+            log.debug("NetTestAdaptor: __get_inputs__ found subarg_inputs=%s"
+                      % cls.subarg_inputs)
+            parsed.extend([cls._input_parser(x) for x in cls.subarg_inputs])
+
         if cls._input_file:
             try:
-                log.debug("Opening input file")
+                log.debug("NetTestAdaptor: __get_inputs__ Opening input file")
                 fp = open(cls._input_file)
             except:
-                log.debug("Couldn't open input file")
+                log.debug("NetTestAdaptor: __get_inputs__ Couldn't open input file")
             else:
-                log.debug("Running input file processor")
+                log.debug("NetTestAdaptor: __get_inputs__ Running input file processor")
                 lines = [line.strip() for line in fp.readlines()]
                 fp.close()
 
                 ## add to what we've already parsed, if any:
-                log.debug("Parsing lines from input file")
+                log.debug("NetTestAdaptor: __get_inputs__ Parsing lines from input file")
                 parsed.extend([cls._input_parser(ln) for ln in lines])
         else:
-            log.debug("%s specified that it doesn't need inputFile."
+            log.debug("NetTestAdaptor: %s specified that it doesn't need inputFile."
                       % cls._nettest_name)
 
         return parsed
 
     @classmethod
-    def __optstruct__(cls):
+    def __getopt__(cls, parseArgs=None):
         """
         Constuctor for a custom t.p.usage.Options class, per NetTestCase.
+
+        old code from runner.py:
+            opts = Options()
+            opts.parseOptions(config['subArgs'])
+            cls.localOptions = opts
         """
-        #if cls._opt_parameters is None:
-        #    cls._opt_parameters = [ list() ]
+        if cls._testopt_params or cls._input_file:
+            if not cls._testopt_params:
+                cls._testopt_params = []
+
+            if cls._input_file:
+                cls._testopt_params.append(cls.input_file)
 
         class NetTestOptions(usage.Options):
             """Per NetTestCase Options class."""
-            optParameters = cls._testopt_params
-            optFlags      = cls._testopt_flags
-            subOptions    = cls._sub_options
-            subCommands   = cls._sub_command
+            optParameters     = cls._testopt_params
+            optFlags          = cls._testopt_flags
+            subOptions        = cls._sub_options
+            subCommands       = cls._sub_commands
+            defaultSubCommand = cls._default_subcmd
+            ## XXX i'm not sure if this part will work:
+            parseArgs         = lambda a: cls.subarg_inputs.append(a)
+
+            def opt_version(self):
+                """Display test version and exit."""
+                print "Test version: ", cls._nettest_version
+                sys.exit(0)
+
+        options = NetTestOptions()
+        return options
 
-    def buildUsageOptions(self, *args, **kwargs):
-        pass
+        #if cls._input_file:
+        #    cls._input_file = cls.options[cls._input_file[0]]
+
+    @classmethod
+    def addSubArgToInputs(cls, subarg):
+        cls.subarg_inputs.append(subarg)
+
+    @classmethod
+    def buildOptions(cls, from_global):
+        log.debug("NetTestAdaptor: getTestOptions called")
+        options = cls.__getopt__()
+        log.debug("NetTestAdaptor: getTestOptions: cls.options = %s"
+                  % options)
+        options.parseOptions(from_global)
+        setattr(cls, "local_options", options)
+        log.debug("NetTestAdaptor: getTestOptions: cls.local_options = %s"
+                  % cls.local_options)
 
     @classmethod
     def setUpClass(cls):
@@ -278,24 +323,29 @@ class NetTestAdaptor(unittest.TestCase):
         subclass of :class:`ooni.nettest.NetTestCase`, so that the calling
         functions during NetTestCase class setup can handle them correctly.
         """
+
+        log.debug("NetTestAdaptor: setUpClass called")
+
         ## These internal inputs are for handling inputs and inputFile
-        cls._raw_inputs   = __copyattr__(cls, "inputs")
-        cls._input_file   = __copyattr__(cls, "inputFile")
-        cls._input_parser = __copyattr__(cls, "inputParser", alt=__input_parser__)
-        cls._nettest_name = __copyattr__(cls, "name", alt="NetTestAdaptor")
+        cls._raw_inputs   = cls.__copyattr__(cls, "inputs")
+        cls._input_file   = cls.__copyattr__(cls, "inputFile")
+        cls._input_parser = cls.__copyattr__(cls, "inputParser",
+                                             alt=cls.__input_parser__)
+        cls._nettest_name = cls.__copyattr__(cls, "name", alt="NetTestAdaptor")
 
         ## This creates a class attribute with all of the parsed inputs,
         ## which the instance will later set to be `self.inputs`.
-        cls.parsed_inputs = __get_inputs__(cls)
+        cls.parsed_inputs = cls.__get_inputs__()
+        cls.subarg_inputs = cls.__copyattr__(cls, "subarg_inputs",
+                                             alt=[])
 
         ## XXX we should handle options generation here
-        cls._testopt_params  = __copyattr__(cls, "optParameters")
-        cls._testopt_flags   = __copyattr__(cls, "optFlags")
-        cls._sub_options     = __copyattr__(cls, "subOptions")
-        cls._sub_command     = __copyattr__(cls, "subCommand")
-        cls._default_subcmd  = __copyattr__(cls, "defaultSubCommand")
-        cls._nettest_version = __copyattr__(cls, "version")
-
+        cls._testopt_params  = cls.__copyattr__(cls, "optParameters")
+        cls._testopt_flags   = cls.__copyattr__(cls, "optFlags")
+        cls._sub_options     = cls.__copyattr__(cls, "subOptions")
+        cls._sub_commands    = cls.__copyattr__(cls, "subCommands")
+        cls._default_subcmd  = cls.__copyattr__(cls, "defaultSubCommand")
+        cls._nettest_version = cls.__copyattr__(cls, "version")
 
 class NetTestCase(NetTestAdaptor):
     """
@@ -376,15 +426,6 @@ class NetTestCase(NetTestAdaptor):
         return inputs
 
     def getOptions(self):
-        '''
-        for attr in attributes:
-            if not attr.name is 'optParameters' or attr.name is 'optFlags':
-                continue
-            elif attr.name is 'optParameters':
-                cls._optParameters = attr.object
-            else:
-                log.debug("How did we get here? attr.name = %s" % attr.name)
-        '''
         log.debug("Getting options for test")
 
         if self.localOptions:
@@ -408,4 +449,3 @@ class NetTestCase(NetTestAdaptor):
 
     def __repr__(self):
         return "<%s inputs=%s>" % (self.__class__, self.inputs)
-
diff --git a/ooni/runner.py b/ooni/runner.py
index a7973dc..f6db105 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -25,6 +25,13 @@ from ooni.utils import log, date
 from ooni.utils.legacy import LegacyOONITest
 from ooni.utils.legacy import start_legacy_test, adapt_legacy_test
 
+
+def isTemplate(obj):
+    origin = obj.__module__
+    if origin.find('templates') >= 0:
+        return True
+    return False
+
 def isLegacyTest(obj):
     """
     Returns True if the test in question is written using the OONITest legacy
@@ -36,48 +43,6 @@ def isLegacyTest(obj):
     except TypeError:
         return False
 
-def processTest(obj, config):
-    """
-    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 config:
-        A configured and instantiated :class:`twisted.python.usage.Options`
-        class.
-    """
-
-    input_file = obj.inputFile
-    if obj.requiresRoot:
-        if os.getuid() != 0:
-            raise Exception("This test requires root to run")
-
-    if obj.optParameters or input_file:
-        if not obj.optParameters:
-            obj.optParameters = []
-
-        if input_file:
-            obj.optParameters.append(input_file)
-
-        class Options(usage.Options):
-            optParameters = obj.optParameters
-
-        options = Options()
-        options.parseOptions(config['subArgs'])
-        obj.localOptions = options
-
-        if input_file:
-            obj.inputFile = options[input_file[0]]
-        try:
-            tmp_obj = obj()
-            tmp_obj.getOptions()
-        except usage.UsageError:
-            options.opt_help()
-
-    return obj
-
 def findTestClassesFromConfig(config):
     """
     Takes as input the command line config parameters and returns the test
@@ -98,24 +63,32 @@ def findTestClassesFromConfig(config):
     module = filenameToModule(filename)
     for name, val in inspect.getmembers(module):
         if isTestCase(val):
-            log.debug("Detected TestCase %s" % val)
-            classes.append(val)
+            if val != NetTestCase and not isTemplate(val):
+                log.debug("findTestClassesFromConfig: detected %s"
+                          % val.__name__)
+                classes.append(val)
         elif isLegacyTest(val):
             log.debug("Detected Legacy Test %s" % val)
             classes.append(adapt_legacy_test(val, config))
     return classes
 
-def makeTestCases(klass, tests, method_prefix):
+def makeTestCases(klass, tests, method_prefix=None):
     """
     Takes a class some tests and returns the test cases. method_prefix is how
     the test case functions should be prefixed with.
     """
+    if not method_prefix:
+        method_prefix = 'test'
+
     cases = []
     for test in tests:
-        cases.append(klass(method_prefix+test))
+        log.debug("makeTestCases: making test case for %s" % test)
+        method_name = str(method_prefix)+str(test)
+        log.debug("makeTestCases: using methodName=%s" % method_name)
+        cases.append(klass(methodName=method_name))
     return cases
 
-def processTestOptions(cls, config):
+def getTestOptions(cls, subargs):
     """
     Process the parameters and :class:`twisted.python.usage.Options` of a
     :class:`ooni.nettest.Nettest`.
@@ -126,48 +99,16 @@ def processTestOptions(cls, config):
         A configured and instantiated :class:`twisted.python.usage.Options`
         class.
     """
-    #if cls.optParameters or cls.inputFile:
-    if not cls.optParameters:
-        cls.optParameters = []
-
-    if cls.inputFile:
-        cls.optParameters.append(cls.inputFile)
-
-    log.debug("CLS IS %s" % cls)
-    log.debug("CLS OPTPARAM IS %s" % cls.optParameters)
-
-    #if not hasattr(cls, subCommands):
-    #    cls.subCommands = []
-
-    if not cls.subCommands:
-        cls.subCommands = []
-
-    class Options(usage.Options):
-        optParameters = cls.optParameters
-        parseArgs     = lambda a: cls.subCommands.append(a)
-
-    opts = Options()
-    opts.parseOptions(config['subArgs'])
-    cls.localOptions = opts
+    if cls.requiresRoot:
+        if os.getuid() != 0:
+            raise Exception("This test requires root to run")
 
-    if cls.inputFile:
-        cls.inputFile = opts[cls.inputFile[0]]
-    """
     try:
-        log.debug("%s: trying %s.localoptions.getOptions()..."
-                  % (__name__, cls.name))
-        try:
-            assert hasattr(cls, 'getOptions')
-        except AssertionError, ae:
-            options = opts.opt_help()
-            raise Exception, "Cannot find %s.getOptions()" % cls.name
-        else:
-            options = cls.getOptions()
-    except usage.UsageError:
-        options = opts.opt_help()
-    else:
-    """
-    return cls.localOptions
+        cls.buildOptions(subargs)
+    except Exception, e:
+        log.err(e)
+
+    return cls.local_options
 
 def loadTestsAndOptions(classes, config):
     """
@@ -184,15 +125,14 @@ def loadTestsAndOptions(classes, config):
 
     for klass in classes:
         if isinstance(klass, DEPRECATED):
-            #not issubclass(klass, TestCase):
             try:
                 cases, opts = processLegacyTest(klass, config)
                 if cases:
-                    log.debug("Processing cases: %s" % str(cases))
+                    log.debug("loadTestsAndOptions: processing cases %s"
+                              % str(cases))
                     return [], []
                 test_cases.append(cases)
-            except Exception, e:
-                log.err(e)
+            except Exception, e: log.err(e)
             else:
                 try:
                     opts = klass.local_options
@@ -214,45 +154,37 @@ def loadTestsAndOptions(classes, config):
 
 def processNetTest(klass, config, method_prefix):
     try:
-        log.debug("Processing cases and options for OONI %s test"
-                  % (klass.name if hasattr(klass, 'name') else 'Network Test'))
+        klass.setUpClass()
+    except Exception, e:
+        log.err(e)
+
+    subargs_from_config = config['subArgs']
+    log.debug("processNetTest: received subargs from config: %s"
+              % str(subargs_from_config))
+    try:
+        opts = getTestOptions(klass, subargs_from_config)
+    except Exception, e:
+        opts = []
+        log.err(e)
 
+    try:
+        log.debug("processNetTest: processing cases for %s"
+                  % (klass.name if hasattr(klass, 'name') else 'Network Test'))
         tests = reflect.prefixedMethodNames(klass, method_prefix)
+    except Exception, e:
+        cases = []
+        opts = []
+        log.err(e)
+    else:
         if tests:
             cases = makeTestCases(klass, tests, method_prefix)
-            log.debug("loadTestsAndOptions(): test %s found cases=%s"% (tests, cases))
-            try:
-                k = klass()
-                opts = processTestOptions(k, config)
-            except Exception, e:
-                opts = []
-                log.err(e)
+            log.debug("processNetTest: test %s found cases %s"
+                      % (tests, cases))
         else:
             cases = []
-    except Exception, e:
-        log.err(e)
 
     return cases, opts
 
-'''
-    if hasattr(klass, 'optParameters') or hasattr(klass, 'inputFile'):
-        try:
-            opts = processTestOptions(klass, config)
-        except:
-            opts = []
-        finally:
-            try:
-                k = klass()
-                inputs = k._getInputs()
-            except Exception, e:
-                inputs = []
-                log.err(e)
-            else:
-                if opts and len(inputs) != 0:
-                    opts.append(['inputs', '', inputs, "cmdline inputs"])
-        log.debug("loadTestsAndOptions(): inputs=%s" % inputs)
-'''
-
 def processLegacyTest(klass, config):
     log.msg("Processing cases and options for legacy test %s"
             % ( klass.shortName if hasattr(klass, shortName) else 'oonitest' ))
@@ -277,22 +209,19 @@ def processLegacyTest(klass, config):
                 opts = {}
 
     elif hasattr(klass, local_options): ## we've been initialized already
-        log.debug("%s.local_options found" % klass)
+        log.debug("processLegacyTest: %s.local_options found" % str(klass))
         try:
-            assert klass.local_options is not None
             opts = klass.local_options
-        except AttributeError, ae:
-            opts = {}; log.err(ae)
+        except AttributeError, ae: opts = {}; log.err(ae)
+        log.debug("processLegacyTest: opts set to %s" % str(opts))
 
     try:
         cases = start_legacy_test(klass)
         ## XXX we need to get these results into the reporter
         if cases:
+            log.debug("processLegacyTest: found cases: %s" % str(cases))
             return [], []
-    except Exception, e:
-        cases = []; log.err(e)
-    finally:
-        log.debug(str(cases))
+    except Exception, e: cases = []; log.err(e)
 
     return cases, opts
 
diff --git a/ooni/templates/scapyt.py b/ooni/templates/scapyt.py
index f71ab57..1b19dbf 100644
--- a/ooni/templates/scapyt.py
+++ b/ooni/templates/scapyt.py
@@ -32,7 +32,7 @@ class ScapyTest(NetTestCase):
     receive = True
     timeout = 1
     pcapfile = None
-    input = IP()/TCP()
+    packet = IP()/TCP()
     reactor = None
     def setUp(self):
         if not self.reactor:
@@ -56,5 +56,5 @@ class ScapyTest(NetTestCase):
         """
         Override this method to build scapy packets.
         """
-        return self.input
+        return self.packet
 





More information about the tor-commits mailing list