[tor-commits] [ooni-probe/master] Fixed bug 11858: ooni might not look at requiresTor?

art at torproject.org art at torproject.org
Thu Aug 7 15:15:26 UTC 2014


commit 90d39dab97309e0498e447d28cef1bd0b87aad86
Author: kudrom <kudrom at riseup.net>
Date:   Thu Aug 7 00:45:44 2014 +0200

    Fixed bug 11858: ooni might not look at requiresTor?
---
 ooni/director.py            |   12 ++++---
 ooni/oonicli.py             |   25 +++++++------
 ooni/settings.py            |   82 +++++++++++++++++++++----------------------
 ooni/tests/test_settings.py |   77 ++++++++++++++++++++++------------------
 4 files changed, 104 insertions(+), 92 deletions(-)

diff --git a/ooni/director.py b/ooni/director.py
index d48c18f..18b7cb2 100644
--- a/ooni/director.py
+++ b/ooni/director.py
@@ -122,11 +122,13 @@ class Director(object):
     def start(self, start_tor=False):
         self.netTests = self.getNetTests()
 
-        if config.advanced.start_tor and start_tor:
-            yield self.startTor()
-        elif config.tor.control_port:
-            log.msg("Connecting to Tor Control Port...")
-            yield self.getTorState()
+        if start_tor:
+            yield config.check_tor()
+            if config.advanced.start_tor:
+                yield self.startTor()
+            elif config.tor.control_port:
+                log.msg("Connecting to Tor Control Port...")
+                yield self.getTorState()
 
         if config.global_options['no-geoip']:
             aux = [False]
diff --git a/ooni/oonicli.py b/ooni/oonicli.py
index cd9f4a9..cfc7ddc 100644
--- a/ooni/oonicli.py
+++ b/ooni/oonicli.py
@@ -111,13 +111,10 @@ def runWithDirector(logging=True, start_tor=True):
     config.global_options = global_options
     config.set_paths()
     config.initialize_ooni_home()
-    d = config.read_config_file(check_incoherences=True)
-
-    @d.addErrback
-    def shutdown(failure):
-        failure.trap(errors.ConfigFileIncoherent)
-        log.err("Shutting down until ooniprobe.conf is coherent.")
-        reactor.callWhenRunning(reactor.stop)
+    try:
+        config.read_config_file(check_incoherences=True)
+    except errors.ConfigFileIncoherent:
+        sys.exit(6)
 
     if global_options['verbose']:
         config.advanced.debug = True
@@ -176,11 +173,11 @@ def runWithDirector(logging=True, start_tor=True):
 
     deck = Deck()
     deck.bouncer = global_options['bouncer']
-    start_tor = deck.requiresTor
+    conditions_to_start_tor = [False]
     if global_options['bouncer']:
-        start_tor = True
+        conditions_to_start_tor.append(True)
     if global_options['collector']:
-        start_tor = True
+        conditions_to_start_tor.append(True)
 
     try:
         if global_options['testdeck']:
@@ -207,6 +204,8 @@ def runWithDirector(logging=True, start_tor=True):
         log.err(e)
         sys.exit(5)
 
+    conditions_to_start_tor.append(deck.requiresTor)
+    start_tor = any(conditions_to_start_tor)
     d = director.start(start_tor=start_tor)
 
     def setup_nettest(_):
@@ -223,7 +222,8 @@ def runWithDirector(logging=True, start_tor=True):
                      errors.CouldNotFindTestHelper,
                      errors.CouldNotFindTestCollector,
                      errors.ProbeIPUnknown,
-                     errors.InvalidInputFile)
+                     errors.InvalidInputFile,
+                     errors.ConfigFileIncoherent)
 
         if isinstance(failure.value, errors.TorNotRunning):
             log.err("Tor does not appear to be running")
@@ -260,6 +260,9 @@ def runWithDirector(logging=True, start_tor=True):
         elif isinstance(failure.value, errors.InvalidInputFile):
             log.err("Invalid input file \"%s\"" % failure.value)
 
+        elif isinstance(failure.value, errors.ConfigFileIncoherent):
+            log.err("Incoherent config file")
+
         if config.advanced.debug:
             log.exception(failure)
 
diff --git a/ooni/settings.py b/ooni/settings.py
index cbf96cb..6f95536 100644
--- a/ooni/settings.py
+++ b/ooni/settings.py
@@ -99,7 +99,6 @@ class OConfig(object):
                     else:
                         w.write(line)
 
-    @defer.inlineCallbacks
     def read_config_file(self, check_incoherences=False):
         if not os.path.exists(self.config_file):
             print "Configuration file does not exist."
@@ -116,61 +115,60 @@ class OConfig(object):
                     getattr(self, setting)[k] = v
         self.set_paths()
 
-        # The incoherent checks must be performed after OConfig is in a valid state to runWithDirector
         if check_incoherences:
-            coherent = yield self.check_incoherences(configuration)
-            if not coherent:
-                raise errors.ConfigFileIncoherent
+            self.check_incoherences(configuration)
 
-    @defer.inlineCallbacks
     def check_incoherences(self, configuration):
         incoherent = []
-        deferreds = []
 
-        if not configuration['advanced']['start_tor']:
-            if not 'socks_port' in configuration['tor']:
+        if configuration['advanced']['interface'] != 'auto' and configuration['advanced']['interface'] not in get_if_list():
+            incoherent.append('advanced:interface')
+
+        self.log_incoherences(incoherent)
+
+    def log_incoherences(self, incoherences):
+        if len(incoherences) > 0:
+            if len(incoherences) > 1:
+                incoherent_pretty = ", ".join(incoherences[:-1]) + ' and ' + incoherences[-1]
+            else:
+                incoherent_pretty = incoherences[0]
+            log.err("You must set properly %s in %s." % (incoherent_pretty, self.config_file))
+            raise errors.ConfigFileIncoherent
+
+    @defer.inlineCallbacks
+    def check_tor(self):
+        """
+        Called only when we must start tor by director.start
+        """
+        incoherent = []
+        d = defer.Deferred()
+
+        if not self.advanced.start_tor:
+            if self.tor.socks_port is None:
                 incoherent.append('tor:socks_port')
-            if not 'control_port' in configuration['tor']:
+            if self.tor.control_port is None:
                 incoherent.append('tor:control_port')
-            if 'socks_port' in configuration['tor'] and 'control_port' in configuration['tor']:
+            if self.tor.socks_port is not None and self.tor.control_port is not None:
                 # Check if tor is listening in these ports
-                @defer.inlineCallbacks
-                def cb(state):
-                    timeout_call.cancel()
-                    result = yield state.protocol.get_info("net/listeners/socks")
-                    if result["net/listeners/socks"].split(':')[1] != str(configuration['tor']['socks_port']):
-                        incoherent.append('tor:socks_port')
-
-                def err(failure):
-                    incoherent.append('tor:socks_port')
-                    if timeout_call.active:
-                        timeout_call.cancel()
-
                 def timeout():
                     incoherent.append('tor:control_port')
                     if not d.called:
                         d.errback()
 
-                connection = TCP4ClientEndpoint(reactor, "localhost", configuration['tor']['control_port'])
-                d = txtorcon.build_tor_connection(connection)
-                d.addCallback(cb)
-                d.addErrback(err)
-                deferreds.append(d)
+                connection = TCP4ClientEndpoint(reactor, "localhost", self.tor.control_port)
                 timeout_call = reactor.callLater(30, timeout)
-
-        if configuration['advanced']['interface'] != 'auto' and configuration['advanced']['interface'] not in get_if_list():
-            incoherent.append('advanced:interface')
-
-        deferred_list = defer.DeferredList(deferreds)
-        yield deferred_list
-        if len(incoherent) > 0:
-            if len(incoherent) > 1:
-                incoherent_pretty = ", ".join(incoherent[:-1]) + ' and ' + incoherent[-1]
-            else:
-                incoherent_pretty = incoherent[0]
-            log.err("You must set properly %s in %s." % (incoherent_pretty, self.config_file))
-            defer.returnValue(False)
-        defer.returnValue(True)
+                try:
+                    d = txtorcon.build_tor_connection(connection)
+                    state = yield d
+                    result = yield state.protocol.get_info("net/listeners/socks")
+                    if result["net/listeners/socks"].split(':')[1] != str(self.tor.socks_port):
+                        incoherent.append('tor:socks_port')
+                except Exception:
+                    incoherent.append('tor:socks_port')
+                finally:
+                    if timeout_call.active:
+                        timeout_call.cancel()
+            self.log_incoherences(incoherent)
 
     def generate_pcap_filename(self, testDetails):
         test_name, start_time = testDetails['test_name'], testDetails['start_time']
diff --git a/ooni/tests/test_settings.py b/ooni/tests/test_settings.py
index b28c1b2..efde7b4 100644
--- a/ooni/tests/test_settings.py
+++ b/ooni/tests/test_settings.py
@@ -7,10 +7,13 @@ from scapy.all import get_if_list
 import txtorcon
 
 from ooni.settings import OConfig
+from ooni import errors
+from bases import ConfigTestCase
 
 
-class TestSettings(unittest.TestCase):
+class TestSettings(ConfigTestCase):
     def setUp(self):
+        super(ConfigTestCase, self).setUp()
         self.conf = OConfig()
         self.configuration = {'advanced': {'interface': 'auto',
                                            'start_tor': True},
@@ -19,6 +22,7 @@ class TestSettings(unittest.TestCase):
         self.tor_protocol = None
 
     def tearDown(self):
+        super(ConfigTestCase, self).tearDown()
         if self.silly_listener is not None:
             self.silly_listener.stopListening()
 
@@ -29,8 +33,8 @@ class TestSettings(unittest.TestCase):
             print '%s %s' % (prog, summary)
 
         config = txtorcon.TorConfig()
-        config.SocksPort = self.configuration['tor']['socks_port']
-        config.ControlPort = self.configuration['tor']['control_port']
+        config.SocksPort = self.conf.tor.socks_port
+        config.ControlPort = self.conf.tor.control_port
         d = txtorcon.launch_tor(config, reactor, progress_updates=progress)
         return d
 
@@ -42,33 +46,39 @@ class TestSettings(unittest.TestCase):
         class SillyFactory(Factory):
             protocol = SillyProtocol
 
-        self.silly_listener = reactor.listenTCP(self.configuration['tor']['socks_port'], SillyFactory())
+        self.silly_listener = reactor.listenTCP(self.conf.tor.socks_port, SillyFactory())
 
-    @defer.inlineCallbacks
     def test_vanilla_configuration(self):
-        ret = yield self.conf.check_incoherences(self.configuration)
-        self.assertEqual(ret, True)
+        self.conf.check_incoherences(self.configuration)
 
     @defer.inlineCallbacks
-    def test_check_incoherences_start_tor_missing_options(self):
-        self.configuration['advanced']['start_tor'] = False
-        ret = yield self.conf.check_incoherences(self.configuration)
-        self.assertEqual(ret, False)
-        self.configuration['tor'] = {'socks_port': 9999}
-        ret = yield self.conf.check_incoherences(self.configuration)
-        self.assertEqual(ret, False)
-        self.configuration['tor']['control_port'] = 9998
-        ret = yield self.conf.check_incoherences(self.configuration)
-        self.assertEqual(ret, False)
+    def test_check_tor_missing_options(self):
+        self.conf.advanced.start_tor = False
+        try:
+            yield self.conf.check_tor()
+        except errors.ConfigFileIncoherent:
+            pass
+
+        self.conf.tor.socks_port = 9999
+        try:
+            yield self.conf.check_tor()
+        except errors.ConfigFileIncoherent:
+            pass
+
+        self.conf.tor.socks_port = None
+        self.conf.tor.control_port = 9998
+        try:
+            yield self.conf.check_tor()
+        except errors.ConfigFileIncoherent:
+            pass
 
     @defer.inlineCallbacks
-    def test_check_incoherences_start_tor_correct(self):
-        self.configuration['advanced']['start_tor'] = False
-        self.configuration['tor'] = {'socks_port': 9999}
-        self.configuration['tor']['control_port'] = 9998
+    def test_check_tor_correct(self):
+        self.conf.advanced.start_tor = False
+        self.conf.tor.socks_port = 9999
+        self.conf.tor.control_port = 9998
         self.tor_process = yield self.run_tor()
-        ret = yield self.conf.check_incoherences(self.configuration)
-        self.assertEqual(ret, True)
+        yield self.conf.check_incoherences(self.configuration)
         self.tor_process.transport.signalProcess('TERM')
 
         d = defer.Deferred()
@@ -76,20 +86,19 @@ class TestSettings(unittest.TestCase):
         yield d
 
     @defer.inlineCallbacks
-    def test_check_incoherences_start_tor_silly_listener(self):
-        self.configuration['advanced']['start_tor'] = False
-        self.configuration['tor'] = {'socks_port': 9999}
-        self.configuration['tor']['control_port'] = 9998
+    def test_check_tor_silly_listener(self):
+        self.conf.advanced.start_tor = False
+        self.conf.tor.socks_port = 9999
+        self.conf.tor.control_port = 9998
         self.run_silly_server()
-        ret = yield self.conf.check_incoherences(self.configuration)
-        self.assertEqual(ret, False)
+        try:
+            yield self.conf.check_tor()
+        except errors.ConfigFileIncoherent:
+            pass
 
-    @defer.inlineCallbacks
     def test_check_incoherences_interface(self):
         self.configuration['advanced']['interface'] = 'funky'
-        ret = yield self.conf.check_incoherences(self.configuration)
-        self.assertEqual(ret, False)
+        self.assertRaises(errors.ConfigFileIncoherent, self.conf.check_incoherences, self.configuration)
 
         self.configuration['advanced']['interface'] = random.choice(get_if_list())
-        ret = yield self.conf.check_incoherences(self.configuration)
-        self.assertEqual(ret, True)
+        self.conf.check_incoherences(self.configuration)





More information about the tor-commits mailing list