[tor-commits] [ooni-probe/master] Make nettest and runner support test relative options.

art at torproject.org art at torproject.org
Sat Oct 6 10:47:27 UTC 2012


commit c99b1657c35a2c83126001282fe01ecaee57b66f
Author: Arturo Filastò <arturo at filasto.net>
Date:   Sat Oct 6 10:21:20 2012 +0000

    Make nettest and runner support test relative options.
---
 nettests/httphost.py     |  124 ++++++++++++++++++++++++++++++++++++++++++++++
 ooni/nettest.py          |    2 +
 ooni/plugins/httphost.py |  124 ----------------------------------------------
 ooni/runner.py           |   17 +++++-
 4 files changed, 140 insertions(+), 127 deletions(-)

diff --git a/nettests/httphost.py b/nettests/httphost.py
new file mode 100644
index 0000000..b57a50d
--- /dev/null
+++ b/nettests/httphost.py
@@ -0,0 +1,124 @@
+"""
+    HTTP Host based filtering
+    *************************
+
+    This test detect HTTP Host field
+    based filtering.
+"""
+import os
+from datetime import datetime
+
+import urllib2
+import httplib
+try:
+    from BeautifulSoup import BeautifulSoup
+except:
+    print "Beautiful Soup not installed. HTTPHost may not work"
+
+# XXX reduce boilerplating.
+from zope.interface import implements
+from twisted.python import usage
+from twisted.plugin import IPlugin
+
+from ooni.plugoo.assets import Asset
+from ooni.plugoo.tests import ITest, OONITest
+
+class HTTPHostArgs(usage.Options):
+    optParameters = [['asset', 'a', None, 'Asset file'],
+                     ['controlserver', 'c', 'google.com', 'Specify the control server'],
+                     ['resume', 'r', 0, 'Resume at this index'],
+                     ['other', 'o', None, 'Other arguments']]
+    def control(self, experiment_result, args):
+        print "Experiment Result:", experiment_result
+        print "Args", args
+        return experiment_result
+
+    def experiment(self, args):
+        import urllib
+        req = urllib.urlopen(args['asset'])
+        return {'page': req.readlines()}
+
+class HTTPHostAsset(Asset):
+    """
+    This is the asset that should be used by the Test. It will
+    contain all the code responsible for parsing the asset file
+    and should be passed on instantiation to the test.
+    """
+    def __init__(self, file=None):
+        self = Asset.__init__(self, file)
+
+    def parse_line(self, line):
+        return line.split(',')[1].replace('\n','')
+
+
+class HTTPHostTest(OONITest):
+    implements(IPlugin, ITest)
+
+    shortName = "httphost"
+    description = "HTTP Host plugin"
+    requirements = None
+    options = HTTPHostArgs
+    # Tells this to be blocking.
+    blocking = True
+
+    def check_response(self, response):
+        soup = BeautifulSoup(response)
+        if soup.head.title.string == "Blocked":
+            # Response indicates censorship
+            return True
+        else:
+            # Response does not indicate censorship
+            return False
+
+    def is_censored(self, response):
+        if response:
+            soup = BeautifulSoup(response)
+            censored = self.check_response(response)
+        else:
+            censored = "unreachable"
+        return censored
+
+    def urllib2_test(self, control_server, host):
+        req = urllib2.Request(control_server)
+        req.add_header('Host', host)
+        try:
+            r = urllib2.urlopen(req)
+            response = r.read()
+            censored = self.is_censored(response)
+        except Exception, e:
+            censored = "Error! %s" % e
+
+        return censored
+
+    def httplib_test(self, control_server, host):
+        censored = None
+        response = None
+        try:
+            conn = httplib.HTTPConnection(control_server)
+            conn.putrequest("GET", "", skip_host=True, skip_accept_encoding=True)
+            conn.putheader("Host", host)
+            conn.putheader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6")
+            conn.endheaders()
+            r = conn.getresponse()
+            response = r.read()
+            censored = self.is_censored(response)
+        except Exception, e:
+            censored = "Error! %s" % e
+
+        return (censored, response)
+
+    def experiment(self, args):
+        control_server = self.local_options['controlserver']
+        url = 'http://torproject.org/' if not 'asset' in args else args['asset']
+        censored = self.httplib_test(control_server, url)
+        return {'control': control_server,
+                'host': url,
+                'censored': censored}
+
+    def load_assets(self):
+        if self.local_options and self.local_options['asset']:
+            return {'asset': Asset(self.local_options['asset'])}
+        else:
+            return {}
+
+httphost = HTTPHostTest(None, None, None)
diff --git a/ooni/nettest.py b/ooni/nettest.py
index d88c044..a01050e 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -80,6 +80,8 @@ class TestCase(unittest.TestCase):
     report = {}
     report['errors'] = []
 
+    optParameters = None
+
     def getOptions(self):
         if self.inputFile:
             fp = open(self.inputFile)
diff --git a/ooni/plugins/httphost.py b/ooni/plugins/httphost.py
deleted file mode 100644
index 7c783a1..0000000
--- a/ooni/plugins/httphost.py
+++ /dev/null
@@ -1,124 +0,0 @@
-"""
-    HTTP Host based filtering
-    *************************
-
-    This test detect HTTP Host field
-    based filtering.
-"""
-import os
-from datetime import datetime
-
-import urllib2
-import httplib
-try:
-    from BeautifulSoup import BeautifulSoup
-except:
-    print "Beautiful Soup not installed. HTTPHost may not work"
-
-# XXX reduce boilerplating.
-from zope.interface import implements
-from twisted.python import usage
-from twisted.plugin import IPlugin
-
-from plugoo.assets import Asset
-from plugoo.tests import ITest, OONITest
-
-class HTTPHostArgs(usage.Options):
-    optParameters = [['asset', 'a', None, 'Asset file'],
-                     ['controlserver', 'c', 'google.com', 'Specify the control server'],
-                     ['resume', 'r', 0, 'Resume at this index'],
-                     ['other', 'o', None, 'Other arguments']]
-    def control(self, experiment_result, args):
-        print "Experiment Result:", experiment_result
-        print "Args", args
-        return experiment_result
-
-    def experiment(self, args):
-        import urllib
-        req = urllib.urlopen(args['asset'])
-        return {'page': req.readlines()}
-
-class HTTPHostAsset(Asset):
-    """
-    This is the asset that should be used by the Test. It will
-    contain all the code responsible for parsing the asset file
-    and should be passed on instantiation to the test.
-    """
-    def __init__(self, file=None):
-        self = Asset.__init__(self, file)
-
-    def parse_line(self, line):
-        return line.split(',')[1].replace('\n','')
-
-
-class HTTPHostTest(OONITest):
-    implements(IPlugin, ITest)
-
-    shortName = "httphost"
-    description = "HTTP Host plugin"
-    requirements = None
-    options = HTTPHostArgs
-    # Tells this to be blocking.
-    blocking = True
-
-    def check_response(self, response):
-        soup = BeautifulSoup(response)
-        if soup.head.title.string == "Blocked":
-            # Response indicates censorship
-            return True
-        else:
-            # Response does not indicate censorship
-            return False
-
-    def is_censored(self, response):
-        if response:
-            soup = BeautifulSoup(response)
-            censored = self.check_response(response)
-        else:
-            censored = "unreachable"
-        return censored
-
-    def urllib2_test(self, control_server, host):
-        req = urllib2.Request(control_server)
-        req.add_header('Host', host)
-        try:
-            r = urllib2.urlopen(req)
-            response = r.read()
-            censored = self.is_censored(response)
-        except Exception, e:
-            censored = "Error! %s" % e
-
-        return censored
-
-    def httplib_test(self, control_server, host):
-        censored = None
-        response = None
-        try:
-            conn = httplib.HTTPConnection(control_server)
-            conn.putrequest("GET", "", skip_host=True, skip_accept_encoding=True)
-            conn.putheader("Host", host)
-            conn.putheader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6")
-            conn.endheaders()
-            r = conn.getresponse()
-            response = r.read()
-            censored = self.is_censored(response)
-        except Exception, e:
-            censored = "Error! %s" % e
-
-        return (censored, response)
-
-    def experiment(self, args):
-        control_server = self.local_options['controlserver']
-        url = 'http://torproject.org/' if not 'asset' in args else args['asset']
-        censored = self.httplib_test(control_server, url)
-        return {'control': control_server,
-                'host': url,
-                'censored': censored}
-
-    def load_assets(self):
-        if self.local_options and self.local_options['asset']:
-            return {'asset': Asset(self.local_options['asset'])}
-        else:
-            return {}
-
-httphost = HTTPHostTest(None, None, None)
diff --git a/ooni/runner.py b/ooni/runner.py
index 8ed844d..c6958bc 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -5,7 +5,7 @@ import time
 import inspect
 
 from twisted.internet import defer, reactor
-from twisted.python import reflect, failure
+from twisted.python import reflect, failure, usage
 
 from twisted.trial import unittest
 from twisted.trial.runner import TrialRunner, TestLoader
@@ -91,6 +91,16 @@ def adaptLegacyTest(obj, config):
 
     return LegacyOONITest
 
+def processTest(obj, config):
+    if obj.optParameters:
+        class Options(usage.Options):
+            optParameters = obj.optParameters
+
+        options = Options()
+        options.parseOptions(config['subArgs'])
+
+        obj.localOptions = options
+    return obj
 
 def findTestClassesFromConfig(config):
     """
@@ -106,7 +116,7 @@ def findTestClassesFromConfig(config):
     module = filenameToModule(filename)
     for name, val in inspect.getmembers(module):
         if isTestCase(val):
-            classes.append(val)
+            classes.append(processTest(val, config))
         elif isLegacyTest(val):
             classes.append(adaptLegacyTest(val, config))
     return classes
@@ -135,7 +145,8 @@ def loadTestsAndOptions(classes):
     for klass in classes:
         try:
             k = klass()
-            options.append(k.getOptions())
+            opts = k.getOptions()
+            options.append(opts)
         except AttributeError:
             options.append([])
 





More information about the tor-commits mailing list