[tor-commits] [ooni-probe/master] [refactoring] Change signature of Deck to be more robust

art at torproject.org art at torproject.org
Mon May 30 16:28:32 UTC 2016


commit aa8314973df0f6e458aa1e0de786faaad8264dc3
Author: Arturo Filastò <arturo at filasto.net>
Date:   Fri Apr 15 15:45:03 2016 +0200

    [refactoring] Change signature of Deck to be more robust
    
    Do more sanity checks on bouncer address at instantiation time
---
 ooni/deck.py                 | 30 ++++++++++++++----------------
 ooni/oonibclient.py          | 15 +++++++++++++--
 ooni/oonicli.py              |  4 ++--
 ooni/tests/mocks.py          |  3 +++
 ooni/tests/test_deck.py      | 14 +++++++-------
 ooni/tests/test_templates.py |  3 +++
 6 files changed, 42 insertions(+), 27 deletions(-)

diff --git a/ooni/deck.py b/ooni/deck.py
index b13385d..4b2c502 100644
--- a/ooni/deck.py
+++ b/ooni/deck.py
@@ -95,28 +95,27 @@ def nettest_to_path(path, allow_arbitrary_paths=False):
 
 
 class Deck(InputFile):
+    # this exists so we can mock it out in unittests
+    _OONIBClient = OONIBClient
+
     def __init__(self, deck_hash=None,
-                 deckFile=None,
+                 bouncer=None,
                  decks_directory=config.decks_directory,
                  no_collector=False):
         self.id = deck_hash
-        self.requiresTor = False
         self.no_collector = no_collector
-        self.bouncer = ''
+        self.bouncer = bouncer
+
+        self.requiresTor = False
+
         self.netTestLoaders = []
         self.inputs = []
 
-        self.oonibclient = OONIBClient(self.bouncer)
-
         self.decksDirectory = os.path.abspath(decks_directory)
-        self.deckHash = deck_hash
-
-        if deckFile:
-            self.loadDeck(deckFile)
 
     @property
     def cached_file(self):
-        return os.path.join(self.decksDirectory, self.deckHash)
+        return os.path.join(self.decksDirectory, self.id)
 
     @property
     def cached_descriptor(self):
@@ -124,7 +123,7 @@ class Deck(InputFile):
 
     def loadDeck(self, deckFile):
         with open(deckFile) as f:
-            self.deckHash = sha256(f.read()).hexdigest()
+            self.id = sha256(f.read()).hexdigest()
             f.seek(0)
             test_deck = yaml.safe_load(f)
 
@@ -175,7 +174,7 @@ class Deck(InputFile):
 
     @defer.inlineCallbacks
     def lookupCollectorAndTestHelpers(self):
-        self.oonibclient.address = self.bouncer
+        oonibclient = self._OONIBClient(self.bouncer)
 
         required_nettests = []
 
@@ -201,8 +200,7 @@ class Deck(InputFile):
         if not requires_test_helpers and not requires_collector:
             defer.returnValue(None)
 
-        log.debug("Looking up {}".format(required_nettests))
-        response = yield self.oonibclient.lookupTestCollector(required_nettests)
+        response = yield oonibclient.lookupTestCollector(required_nettests)
         provided_net_tests = response['net-tests']
 
         def find_collector_and_test_helpers(test_name, test_version, input_files):
@@ -240,10 +238,10 @@ class Deck(InputFile):
         for i in net_test_loader.inputFiles:
             if i['url']:
                 log.debug("Downloading %s" % i['url'])
-                self.oonibclient.address = i['address']
+                oonibclient = self._OONIBClient(i['address'])
 
                 try:
-                    input_file = yield self.oonibclient.downloadInput(i['hash'])
+                    input_file = yield oonibclient.downloadInput(i['hash'])
                 except:
                     raise e.UnableToLoadDeckInput
 
diff --git a/ooni/oonibclient.py b/ooni/oonibclient.py
index 388bb68..336ae4e 100644
--- a/ooni/oonibclient.py
+++ b/ooni/oonibclient.py
@@ -1,5 +1,7 @@
 import json
 
+from urlparse import urljoin
+
 from twisted.web.client import Agent
 from twisted.internet import defer, reactor
 from twisted.internet.endpoints import TCP4ClientEndpoint
@@ -15,6 +17,15 @@ class OONIBClient(object):
     retries = 3
 
     def __init__(self, address):
+        if address.startswith("https://"):
+            log.err("HTTPS bouncers are currently not supported!")
+            raise e.InvalidOONIBBouncerAddress
+        elif address.startswith("http://"):
+            log.msg("Warning using plaintext bouncer!")
+        elif address.startswith("httpo://"):
+            log.debug("Using Tor hidden service bouncer: {}".format(address))
+        else:
+            raise e.InvalidOONIBBouncerAddress
         self.address = address
 
     def _request(self, method, urn, genReceiver, bodyProducer=None):
@@ -30,7 +41,7 @@ class OONIBClient(object):
             raise e.InvalidOONIBBouncerAddress
 
         elif self.address.startswith('http://'):
-            log.msg("Warning using unencrypted backend")
+            log.msg("Warning using unencrypted bouncer")
             agent = Agent(reactor)
 
         attempts = 0
@@ -38,7 +49,7 @@ class OONIBClient(object):
         finished = defer.Deferred()
 
         def perform_request(attempts):
-            uri = address + urn
+            uri = urljoin(address, urn)
             d = agent.request(method, uri, bodyProducer=bodyProducer)
 
             @d.addCallback
diff --git a/ooni/oonicli.py b/ooni/oonicli.py
index e2d78e1..281ff46 100644
--- a/ooni/oonicli.py
+++ b/ooni/oonicli.py
@@ -245,8 +245,8 @@ def createDeck(global_options, url=None):
     if global_options['no-yamloo']:
         log.msg("Will not write to a yamloo report file")
 
-    deck = Deck(no_collector=global_options['no-collector'])
-    deck.bouncer = global_options['bouncer']
+    deck = Deck(bouncer=global_options['bouncer'],
+                no_collector=global_options['no-collector'])
 
     try:
         if global_options['testdeck']:
diff --git a/ooni/tests/mocks.py b/ooni/tests/mocks.py
index 4f51f32..19b4692 100644
--- a/ooni/tests/mocks.py
+++ b/ooni/tests/mocks.py
@@ -190,6 +190,9 @@ class MockTaskManager(TaskManager):
 
 
 class MockOONIBClient(object):
+    def __init__(self, *args, **kw):
+        pass
+
     def lookupTestHelpers(self, required_test_helpers):
         ret = {
             'default': {
diff --git a/ooni/tests/test_deck.py b/ooni/tests/test_deck.py
index 2c3bc04..3e2a322 100644
--- a/ooni/tests/test_deck.py
+++ b/ooni/tests/test_deck.py
@@ -127,14 +127,14 @@ class TestDeck(BaseTestCase):
             os.remove(self.filename)
 
     def test_open_deck(self):
-        deck = Deck(decks_directory=".")
-        deck.bouncer = "httpo://foo.onion"
+        deck = Deck(bouncer="httpo://foo.onion",
+                    decks_directory=".")
         deck.loadDeck(self.deck_file)
         assert len(deck.netTestLoaders) == 1
 
     def test_save_deck_descriptor(self):
-        deck = Deck(decks_directory=".")
-        deck.bouncer = "httpo://foo.onion"
+        deck = Deck(bouncer="httpo://foo.onion",
+                    decks_directory=".")
         deck.loadDeck(self.deck_file)
         deck.load({'name': 'spam',
                    'id': 'spam',
@@ -149,9 +149,9 @@ class TestDeck(BaseTestCase):
 
     @defer.inlineCallbacks
     def test_lookup_test_helpers_and_collector(self):
-        deck = Deck(decks_directory=".")
-        deck.bouncer = "httpo://foo.onion"
-        deck.oonibclient = MockOONIBClient()
+        deck = Deck(bouncer="httpo://foo.onion",
+                    decks_directory=".")
+        deck._OONIBClient = MockOONIBClient
         deck.loadDeck(self.deck_file)
 
         self.assertEqual(len(deck.netTestLoaders[0].missingTestHelpers), 1)
diff --git a/ooni/tests/test_templates.py b/ooni/tests/test_templates.py
index e7452df..5b2c77a 100644
--- a/ooni/tests/test_templates.py
+++ b/ooni/tests/test_templates.py
@@ -1,6 +1,7 @@
 from ooni.templates import httpt, dnst
 
 from ooni.tests import is_internet_connected
+
 from twisted.names import dns
 from twisted.internet.error import DNSLookupError
 from twisted.internet import reactor, defer, base
@@ -92,6 +93,8 @@ class TestDNST(unittest.TestCase):
 
     @defer.inlineCallbacks
     def test_perform_a_lookup(self):
+        if not is_internet_connected():
+            self.skipTest("You must be connected to the internet to run this test")
         dns_test = dnst.DNSTest()
         dns_test._setUp()
         result = yield dns_test.performALookup('example.com', dns_server=('8.8.8.8', 53))





More information about the tor-commits mailing list