[tor-commits] [oonib/master] Improved RESTfulness of the bouncer API.

art at torproject.org art at torproject.org
Mon Sep 1 10:31:29 UTC 2014


commit fce1c169401ed3ec110c82eaeeade14f4aab8151
Author: kudrom <kudrom at riseup.net>
Date:   Fri Aug 29 18:43:14 2014 +0200

    Improved RESTfulness of the bouncer API.
---
 oonib/bouncer/api.py       |    8 +++--
 oonib/bouncer/handlers.py  |   46 ++++++++++++++++++++--------
 oonib/test/test_bouncer.py |   71 +++++++++++++++++++++++++++++++++++++-------
 3 files changed, 99 insertions(+), 26 deletions(-)

diff --git a/oonib/bouncer/api.py b/oonib/bouncer/api.py
index 42f53e1..666c708 100644
--- a/oonib/bouncer/api.py
+++ b/oonib/bouncer/api.py
@@ -1,6 +1,8 @@
 from oonib.bouncer import handlers
-#XXX: if bouncer is configured
+# XXX: if bouncer is configured
 bouncerAPI = [
-        #return a collector and helper of the requested type
-        (r"/bouncer", handlers.BouncerQueryHandler),
+    # return a collector and helper of the requested type
+    (r"/bouncer", handlers.BouncerQueryHandler),
+    (r"/bouncer/test-helpers", handlers.BouncerTestHelpers),
+    (r"/bouncer/net-tests", handlers.BouncerNetTests),
 ]
diff --git a/oonib/bouncer/handlers.py b/oonib/bouncer/handlers.py
index c49338e..c7914b5 100644
--- a/oonib/bouncer/handlers.py
+++ b/oonib/bouncer/handlers.py
@@ -165,27 +165,49 @@ class Bouncer(object):
         return {'net-tests': nettests}
 
 
-class BouncerQueryHandler(OONIBHandler):
-
+class BouncerHandlerBase(OONIBHandler):
     def initialize(self):
         self.bouncer = Bouncer(config.main.bouncer_file)
 
-    def post(self):
-        try:
-            query = json.loads(self.request.body)
-        except ValueError:
-            raise e.InvalidRequest
+    def load_query(self):
+        if not 'query' in dir(self):
+            try:
+                self.query = json.loads(self.request.body)
+            except ValueError:
+                raise e.InvalidRequest
+
 
-        if 'test-helpers' in query:
-            requested_helpers = query['test-helpers']
+class BouncerTestHelpers(BouncerHandlerBase):
+    def post(self):
+        self.load_query()
+        if 'test-helpers' in self.query:
+            requested_helpers = self.query['test-helpers']
             if not isinstance(requested_helpers, list):
                 raise e.InvalidRequest
             response = self.bouncer.filterHelperAddresses(requested_helpers)
+        else:
+            raise e.InvalidRequest
+
+        self.write(response)
 
-        elif 'net-tests' in query:
-            response = self.bouncer.filterByNetTests(query['net-tests'])
 
+class BouncerNetTests(BouncerHandlerBase):
+    def post(self):
+        self.load_query()
+        if 'net-tests' in self.query:
+            response = self.bouncer.filterByNetTests(self.query['net-tests'])
         else:
-            raise e.TestHelpersOrNetTestsKeyMissing
+            raise e.InvalidRequest
 
         self.write(response)
+
+
+class BouncerQueryHandler(BouncerNetTests, BouncerTestHelpers):
+    def post(self):
+        self.load_query()
+        if 'test-helpers' in self.query:
+            BouncerTestHelpers.post(self)
+        elif 'net-tests' in self.query:
+            BouncerNetTests.post(self)
+        else:
+            raise e.TestHelpersOrNetTestsKeyMissing
diff --git a/oonib/test/test_bouncer.py b/oonib/test/test_bouncer.py
index 2724947..0f4c5ef 100644
--- a/oonib/test/test_bouncer.py
+++ b/oonib/test/test_bouncer.py
@@ -125,7 +125,7 @@ class TestBouncer(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('error', response_body)
@@ -144,6 +144,35 @@ class TestBouncer(BaseTestBouncer):
             ]
         }
 
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
+        response_body = json.loads(response.body)
+
+        self.assertIn('net-tests', response_body)
+        self.assertEqual(len(response_body['net-tests']), 1)
+        self.assertIn('name', response_body['net-tests'][0])
+        self.assertEqual(response_body['net-tests'][0]['name'], 'fake_nettest')
+        self.assertIn('version', response_body['net-tests'][0])
+        self.assertEqual(response_body['net-tests'][0]['version'], '1.0')
+        self.assertIn('input-hashes', response_body['net-tests'][0])
+        self.assertEqual(len(response_body['net-tests'][0]['input-hashes']), 0)
+        self.assertIn('test-helpers', response_body['net-tests'][0])
+        self.assertEqual(len(response_body['net-tests'][0]['test-helpers']), 0)
+        self.assertIn('collector', response_body['net-tests'][0])
+        self.assertEqual(response_body['net-tests'][0]['collector'], 'fake_address')
+
+    @defer.inlineCallbacks
+    def test_backward_compatibility(self):
+        data = {
+            'net-tests': [
+                {
+                    "test-helpers": [],
+                    "input-hashes": [],
+                    "name": 'fake_nettest',
+                    "version": '1.0',
+                },
+            ]
+        }
+
         response = yield self.request('/bouncer', 'POST', data)
         response_body = json.loads(response.body)
 
@@ -179,7 +208,7 @@ class TestBouncer(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('net-tests', response_body)
@@ -202,7 +231,7 @@ class TestBouncer(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('error', response_body)
@@ -221,7 +250,7 @@ class TestBouncer(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('net-tests', response_body)
@@ -245,7 +274,7 @@ class TestBouncer(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('error', response_body)
@@ -264,7 +293,7 @@ class TestBouncer(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('net-tests', response_body)
@@ -288,7 +317,7 @@ class TestBouncer(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('error', response_body)
@@ -328,7 +357,7 @@ class TestDefaultCollector(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('net-tests', response_body)
@@ -366,7 +395,7 @@ class TestMultipleCollectors(BaseTestBouncer):
             ]
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/net-tests', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('net-tests', response_body)
@@ -396,7 +425,7 @@ class TestHelperTests(BaseTestBouncer):
         data = {
             'test-helpers': ['invalid_test_helper']
         }
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/test-helpers', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertIn('error', response_body)
@@ -408,6 +437,26 @@ class TestHelperTests(BaseTestBouncer):
             'test-helpers': ['fake_test_helper']
         }
 
+        response = yield self.request('/bouncer/test-helpers', 'POST', data)
+        response_body = json.loads(response.body)
+
+        self.assertEqual(len(response_body), 2)
+        self.assertIn('fake_test_helper', response_body)
+        self.assertIn('collector', response_body['fake_test_helper'])
+        self.assertIn(response_body['fake_test_helper']['collector'], ['fake_addressA', 'fake_addressB'])
+        self.assertIn('address', response_body['fake_test_helper'])
+        self.assertEqual('fake_hostname', response_body['fake_test_helper']['address'])
+
+        self.assertIn('default', response_body)
+        self.assertIn('collector', response_body['default'])
+        self.assertEqual('fake_addressB', response_body['default']['collector'])
+
+    @defer.inlineCallbacks
+    def test_backward_compatibility(self):
+        data = {
+            'test-helpers': ['fake_test_helper']
+        }
+
         response = yield self.request('/bouncer', 'POST', data)
         response_body = json.loads(response.body)
 
@@ -428,7 +477,7 @@ class TestHelperTests(BaseTestBouncer):
             'test-helpers': ['fake_test_helper', 'exotic_test_helper']
         }
 
-        response = yield self.request('/bouncer', 'POST', data)
+        response = yield self.request('/bouncer/test-helpers', 'POST', data)
         response_body = json.loads(response.body)
 
         self.assertEqual(len(response_body), 3)





More information about the tor-commits mailing list