[tor-commits] [ooni-probe/master] Add support for displaying a summary of the test results to bridge reachability test.

art at torproject.org art at torproject.org
Mon Mar 24 15:02:47 UTC 2014


commit e7ac9808ac51ac0e06f8ef8091b83c1e30e7c9e5
Author: Arturo Filastò <art at fuffa.org>
Date:   Mon Mar 10 18:47:00 2014 +0100

    Add support for displaying a summary of the test results to bridge reachability test.
---
 ooni/nettest.py                               |   27 ++++++++++++-
 ooni/nettests/blocking/bridge_reachability.py |   54 ++++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/ooni/nettest.py b/ooni/nettest.py
index 235ad85..520fcf8 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -388,6 +388,9 @@ class NetTestLoader(object):
         self.testVersion = test_class.version
         self.testName = test_class_name_to_name(test_class.name)
         self.testCases = test_cases
+        self.testClasses = set([])
+        for test_class, test_method in self.testCases:
+            self.testClasses.add(test_class)
 
     def checkOptions(self):
         """
@@ -397,7 +400,7 @@ class NetTestLoader(object):
         for test_class, test_method in self.testCases:
             test_classes.add(test_class)
 
-        for klass in test_classes:
+        for klass in self.testClasses:
             options = self.usageOptions()
             options.parseOptions(self.options)
 
@@ -488,13 +491,25 @@ class NetTest(object):
         """
         self.report = report
         self.testCases = net_test_loader.testCases
+        self.testClasses = net_test_loader.testClasses
+        self.testDetails = net_test_loader.testDetails
+
+        self.summary = {}
 
         # This will fire when all the measurements have been completed and
         # all the reports are done. Done means that they have either completed
         # successfully or all the possible retries have been reached.
         self.done = defer.Deferred()
+        self.done.addCallback(self.doneNetTest)
 
         self.state = NetTestState(self.done)
+    
+    def doneNetTest(self, result):
+        print "Summary for %s" % self.testDetails['test_name']
+        print "------------" + "-"*len(self.testDetails['test_name'])
+        for test_class in self.testClasses:
+            test_instance = test_class()
+            test_instance.displaySummary(self.summary)
 
     def doneReport(self, report_results):
         """
@@ -556,6 +571,7 @@ class NetTest(object):
             for input in test_class.inputs:
                 measurements = []
                 test_instance = test_class()
+                test_instance.summary = self.summary
                 for method in test_methods:
                     log.debug("Running %s %s" % (test_class, method))
                     measurement = self.makeMeasurement(test_instance, method, input)
@@ -674,9 +690,18 @@ class NetTestCase(object):
         postProcessing works exactly like test methods, in the sense that
         anything that gets written to the object self.report[] will be added to
         the final test report.
+        You should also place in this method any logic that is required for
+        generating the summary.
         """
         raise e.NoPostProcessor
 
+    def displaySummary(self):
+        """
+        This gets called after the test has run to allow printing out of a
+        summary of the test run.
+        """
+        pass
+
     def inputProcessor(self, filename):
         """
         You may replace this with your own custom input processor. It takes as
diff --git a/ooni/nettests/blocking/bridge_reachability.py b/ooni/nettests/blocking/bridge_reachability.py
index 7c519ec..98d7e9a 100644
--- a/ooni/nettests/blocking/bridge_reachability.py
+++ b/ooni/nettests/blocking/bridge_reachability.py
@@ -34,12 +34,59 @@ class BridgeReachability(nettest.NetTestCase):
     def setUp(self):
         self.tor_progress = 0
         self.timeout = int(self.localOptions['timeout'])
+
         self.report['timeout'] = self.timeout
+        self.report['transport_name'] = 'vanilla'
+        self.report['tor_progress'] = None
+        self.report['tor_progress_tag'] = None
+        self.report['tor_progress_summary'] = None
+        self.report['bridge_address'] = None
+
         self.bridge = self.input
         if self.input.startswith('Bridge'):
             self.bridge = self.input.replace('Bridge ', '')
         self.pyobfsproxy_bin = find_executable('obfsproxy')
     
+    def postProcessor(self, measurements):
+        if 'successes' not in self.summary:
+            self.summary['successes'] = []
+        if 'failures' not in self.summary:
+            self.summary['failures'] = []
+
+        details = {
+            'address': self.report['bridge_address'],
+            'transport_name': self.report['transport_name']
+        }
+        if self.report['success']:
+            self.summary['successes'].append(details)
+        else:
+            self.summary['failures'].append(details)
+
+    def displaySummary(self, summary):
+        successful_count = {}
+        failure_count = {}
+        def count(results, counter):
+            for result in results:
+                if result['transport_name'] not in counter:
+                    counter[result['transport_name']] = 0
+                counter[result['transport_name']] += 1
+        count(summary['successes'], successful_count)
+        count(summary['failures'], failure_count)
+
+        working_bridges = ', '.join([x['address'] for x in summary['successes']])
+        failing_bridges = ', '.join([x['address'] for x in summary['failures']])
+
+        print "Total successes: %d" % len(summary['successes'])
+        print "Total failures: %d" % len(summary['failures'])
+
+        for transport, count in successful_count.items():
+            print "%s successes: %d" % (transport.title(), count)
+        for transport, count in failure_count.items():
+            print "%s failures: %d" % (transport.title(), count)
+
+        print "Working bridges: %s" % working_bridges
+        print "Failing bridges: %s" % failing_bridges
+
     def test_full_tor_connection(self):
         def getTransport(address):
             """
@@ -59,22 +106,25 @@ class BridgeReachability(nettest.NetTestCase):
         config = txtorcon.TorConfig()
         config.ControlPort = random.randint(2**14, 2**16)
         config.SocksPort = random.randint(2**14, 2**16)
-
+        
         transport_name = getTransport(self.bridge)
         if transport_name and self.pyobfsproxy_bin:
             config.ClientTransportPlugin = "%s exec %s managed" % (transport_name, self.pyobfsproxy_bin)
             self.report['transport_name'] = transport_name
+            self.report['bridge_address'] = self.bridge.split(' ')[1]
         elif transport_name and not self.pyobfsproxy_bin:
             log.err("Unable to test bridge because pyobfsproxy is not installed")
             self.report['success'] = None
             return
+        else:
+            self.report['bridge_address'] = self.bridge.split(' ')[0]
 
         config.Bridge = self.bridge
         config.UseBridges = 1
         config.save()
 
         def updates(prog, tag, summary):
-            log.msg("Tor progress: %s%%" % prog)
+            log.msg("%s: %s%%" % (self.bridge, prog))
             self.report['tor_progress'] = int(prog)
             self.report['tor_progress_tag'] = tag
             self.report['tor_progress_summary'] = summary





More information about the tor-commits mailing list