commit 377be01de996948e5b8b40f57406c522b2e297c6 Author: Arturo Filastò arturo@filasto.net Date: Tue Jun 28 13:52:07 2016 +0200
Add more unittests for backend_client --- ooni/tests/test_backend_client.py | 217 ++++++++++++++++++++++++++++++++++++++ ooni/tests/test_director.py | 1 - ooni/tests/test_oonibclient.py | 144 ------------------------- 3 files changed, 217 insertions(+), 145 deletions(-)
diff --git a/ooni/tests/test_backend_client.py b/ooni/tests/test_backend_client.py new file mode 100644 index 0000000..212abb6 --- /dev/null +++ b/ooni/tests/test_backend_client.py @@ -0,0 +1,217 @@ +import os +import shutil +import socket + +from twisted.internet import defer +from twisted.web import error + +from ooni import errors as e +from ooni.settings import config +from ooni.backend_client import CollectorClient, BouncerClient +from ooni.backend_client import WebConnectivityClient +from ooni.tests.bases import ConfigTestCase + +from mock import MagicMock + +input_id = '37e60e13536f6afe47a830bfb6b371b5cf65da66d7ad65137344679b24fdccd1' +deck_id = 'd4ae40ecfb3c1b943748cce503ab8233efce7823f3e391058fc0f87829c644ed' + + +class TestEnd2EndBackendClient(ConfigTestCase): + def setUp(self): + super(TestEnd2EndBackendClient, self).setUp() + host = '127.0.0.1' + port = 8889 + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + s.connect((host, port)) + s.shutdown(2) + + data_dir = '/tmp/testooni' + config.advanced.data_dir = data_dir + + if os.path.exists(data_dir): + shutil.rmtree(data_dir) + os.mkdir(data_dir) + os.mkdir(os.path.join(data_dir, 'inputs')) + os.mkdir(os.path.join(data_dir, 'decks')) + except Exception: + self.skipTest("OONIB must be listening on port 8888 to run this test (tor_hidden_service: false)") + self.collector_client = CollectorClient('http://' + host + ':' + str(port)) + + @defer.inlineCallbacks + def test_query(self): + res = yield self.collector_client.queryBackend('GET', '/policy/input') + self.assertTrue(isinstance(res, list)) + + @defer.inlineCallbacks + def test_get_input_list(self): + input_list = yield self.collector_client.getInputList() + self.assertTrue(isinstance(input_list, list)) + + @defer.inlineCallbacks + def test_get_input_descriptor(self): + input_descriptor = yield self.collector_client.getInput(input_id) + for key in ['name', 'description', + 'version', 'author', 'date', 'id']: + self.assertTrue(hasattr(input_descriptor, key)) + + @defer.inlineCallbacks + def test_download_input(self): + yield self.collector_client.downloadInput(input_id) + + @defer.inlineCallbacks + def test_get_deck_list(self): + deck_list = yield self.collector_client.getDeckList() + self.assertTrue(isinstance(deck_list, list)) + + @defer.inlineCallbacks + def test_get_deck_descriptor(self): + deck_descriptor = yield self.collector_client.getDeck(deck_id) + for key in ['name', 'description', + 'version', 'author', 'date', 'id']: + self.assertTrue(hasattr(deck_descriptor, key)) + + @defer.inlineCallbacks + def test_download_deck(self): + yield self.collector_client.downloadDeck(deck_id) + + def test_lookup_invalid_helpers(self): + bouncer_client = BouncerClient('http://127.0.0.1:8888') + return self.failUnlessFailure( + bouncer_client.lookupTestHelpers([ + 'sdadsadsa', 'dns' + ]), e.CouldNotFindTestHelper) + + @defer.inlineCallbacks + def test_lookup_no_test_helpers(self): + bouncer_client = BouncerClient('http://127.0.0.1:8888') + required_helpers = [] + helpers = yield bouncer_client.lookupTestHelpers(required_helpers) + self.assertTrue('default' in helpers.keys()) + + @defer.inlineCallbacks + def test_lookup_test_helpers(self): + bouncer_client = BouncerClient('http://127.0.0.1:8888') + required_helpers = [u'http-return-json-headers', u'dns'] + helpers = yield bouncer_client.lookupTestHelpers(required_helpers) + self.assertEqual(set(helpers.keys()), set(required_helpers + [u'default'])) + self.assertTrue(helpers['http-return-json-headers']['address'].startswith('http')) + self.assertTrue(int(helpers['dns']['address'].split('.')[0])) + + @defer.inlineCallbacks + def test_input_descriptor_not_found(self): + yield self.assertFailure(self.collector_client.queryBackend('GET', + '/input/' + 'a'*64), e.OONIBInputDescriptorNotFound) + + @defer.inlineCallbacks + def test_http_errors(self): + yield self.assertFailure(self.collector_client.queryBackend('PUT', + '/policy/input'), error.Error) + + @defer.inlineCallbacks + def test_create_report(self): + res = yield self.collector_client.queryBackend('POST', '/report', { + 'software_name': 'spam', + 'software_version': '2.0', + 'probe_asn': 'AS0', + 'probe_cc': 'ZZ', + 'test_name': 'foobar', + 'test_version': '1.0', + 'input_hashes': [] + }) + assert isinstance(res['report_id'], unicode) + + @defer.inlineCallbacks + def test_report_lifecycle(self): + res = yield self.collector_client.queryBackend('POST', '/report', { + 'software_name': 'spam', + 'software_version': '2.0', + 'probe_asn': 'AS0', + 'probe_cc': 'ZZ', + 'test_name': 'foobar', + 'test_version': '1.0', + 'input_hashes': [] + }) + report_id = str(res['report_id']) + + res = yield self.collector_client.queryBackend('POST', '/report/' + report_id, { + 'content': '---\nspam: ham\n...\n' + }) + + res = yield self.collector_client.queryBackend('POST', '/report/' + report_id, { + 'content': '---\nspam: ham\n...\n' + }) + + res = yield self.collector_client.queryBackend('POST', '/report/' + report_id + + '/close') + + +class TestBackendClient(ConfigTestCase): + @defer.inlineCallbacks + def test_web_connectivity_client_is_reachable(self): + wcc = WebConnectivityClient( + 'https://web-connectivity.th.ooni.io') + wcc.queryBackend = MagicMock() + wcc.queryBackend.return_value = defer.succeed({"status": "ok"}) + result = yield wcc.isReachable() + self.assertEqual(result, True) + + @defer.inlineCallbacks + def test_web_connectivity_client_is_not_reachable(self): + wcc = WebConnectivityClient( + 'https://web-connectivity.th.ooni.io') + wcc.queryBackend = MagicMock() + wcc.queryBackend.return_value = defer.fail(Exception()) + result = yield wcc.isReachable() + self.assertEqual(result, False) + + + @defer.inlineCallbacks + def test_web_connectivity_client_control(self): + wcc = WebConnectivityClient( + 'https://web-connectivity.th.ooni.io') + wcc.queryBackend = MagicMock() + wcc.queryBackend.return_value = defer.succeed({}) + yield wcc.control("http://example.com/", ["127.0.0.1:8080", + "127.0.0.1:8082"]) + wcc.queryBackend.assert_called_with( + 'POST', '/', + query={ + "http_request": "http://example.com/", + "tcp_connect": ["127.0.0.1:8080", "127.0.0.1:8082"] + }) + + + @defer.inlineCallbacks + def test_bouncer_client_lookup_collector(self): + bcc = BouncerClient('https://bouncer.ooni.io') + bcc.queryBackend = MagicMock() + bcc.queryBackend.return_value = defer.succeed({}) + yield bcc.lookupTestCollector(["foo"]) + bcc.queryBackend.assert_called_with("POST", + "/bouncer/net-tests", + query={'net-tests': ["foo"]}) + + + @defer.inlineCallbacks + def test_bouncer_client_lookup_test_helpers(self): + bcc = BouncerClient('https://bouncer.ooni.io') + bcc.queryBackend = MagicMock() + bcc.queryBackend.return_value = defer.succeed({'spam': 'ham'}) + yield bcc.lookupTestHelpers(["foo"]) + bcc.queryBackend.assert_called_with("POST", + "/bouncer/test-helpers", + query={'test-helpers': ["foo"]}) + + + def test_backend_client_validates_url(self): + raised = False + try: + cc = CollectorClient(settings={ + "type": "onion", "address": "http://invalid.onion" + }) + except Exception as exc: + raised = True + self.assertIsInstance(exc, e.InvalidAddress) + self.assertTrue(raised) diff --git a/ooni/tests/test_director.py b/ooni/tests/test_director.py index 0cc740a..18377f5 100644 --- a/ooni/tests/test_director.py +++ b/ooni/tests/test_director.py @@ -2,7 +2,6 @@ from mock import patch, MagicMock
from ooni.settings import config from ooni.director import Director -from ooni.nettest import NetTestLoader from ooni.tests.bases import ConfigTestCase
from ooni.nettest import NetTestLoader diff --git a/ooni/tests/test_oonibclient.py b/ooni/tests/test_oonibclient.py deleted file mode 100644 index a14a881..0000000 --- a/ooni/tests/test_oonibclient.py +++ /dev/null @@ -1,144 +0,0 @@ -import os -import shutil -import socket - -from twisted.internet import defer -from twisted.web import error - -from ooni import errors as e -from ooni.settings import config -from ooni.backend_client import CollectorClient, BouncerClient -from ooni.tests.bases import ConfigTestCase - -input_id = '37e60e13536f6afe47a830bfb6b371b5cf65da66d7ad65137344679b24fdccd1' -deck_id = 'd4ae40ecfb3c1b943748cce503ab8233efce7823f3e391058fc0f87829c644ed' - - -class TestOONIBClient(ConfigTestCase): - def setUp(self): - super(TestOONIBClient, self).setUp() - host = '127.0.0.1' - port = 8889 - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - s.connect((host, port)) - s.shutdown(2) - - data_dir = '/tmp/testooni' - config.advanced.data_dir = data_dir - - if os.path.exists(data_dir): - shutil.rmtree(data_dir) - os.mkdir(data_dir) - os.mkdir(os.path.join(data_dir, 'inputs')) - os.mkdir(os.path.join(data_dir, 'decks')) - except Exception: - self.skipTest("OONIB must be listening on port 8888 to run this test (tor_hidden_service: false)") - self.collector_client = CollectorClient('http://' + host + ':' + str(port)) - - @defer.inlineCallbacks - def test_query(self): - res = yield self.collector_client.queryBackend('GET', '/policy/input') - self.assertTrue(isinstance(res, list)) - - @defer.inlineCallbacks - def test_get_input_list(self): - input_list = yield self.collector_client.getInputList() - self.assertTrue(isinstance(input_list, list)) - - @defer.inlineCallbacks - def test_get_input_descriptor(self): - input_descriptor = yield self.collector_client.getInput(input_id) - for key in ['name', 'description', - 'version', 'author', 'date', 'id']: - self.assertTrue(hasattr(input_descriptor, key)) - - @defer.inlineCallbacks - def test_download_input(self): - yield self.collector_client.downloadInput(input_id) - - @defer.inlineCallbacks - def test_get_deck_list(self): - deck_list = yield self.collector_client.getDeckList() - self.assertTrue(isinstance(deck_list, list)) - - @defer.inlineCallbacks - def test_get_deck_descriptor(self): - deck_descriptor = yield self.collector_client.getDeck(deck_id) - for key in ['name', 'description', - 'version', 'author', 'date', 'id']: - self.assertTrue(hasattr(deck_descriptor, key)) - - @defer.inlineCallbacks - def test_download_deck(self): - yield self.collector_client.downloadDeck(deck_id) - - def test_lookup_invalid_helpers(self): - bouncer_client = BouncerClient('http://127.0.0.1:8888') - return self.failUnlessFailure( - bouncer_client.lookupTestHelpers([ - 'sdadsadsa', 'dns' - ]), e.CouldNotFindTestHelper) - - @defer.inlineCallbacks - def test_lookup_no_test_helpers(self): - bouncer_client = BouncerClient('http://127.0.0.1:8888') - required_helpers = [] - helpers = yield bouncer_client.lookupTestHelpers(required_helpers) - self.assertTrue('default' in helpers.keys()) - - @defer.inlineCallbacks - def test_lookup_test_helpers(self): - bouncer_client = BouncerClient('http://127.0.0.1:8888') - required_helpers = [u'http-return-json-headers', u'dns'] - helpers = yield bouncer_client.lookupTestHelpers(required_helpers) - self.assertEqual(set(helpers.keys()), set(required_helpers + [u'default'])) - self.assertTrue(helpers['http-return-json-headers']['address'].startswith('http')) - self.assertTrue(int(helpers['dns']['address'].split('.')[0])) - - @defer.inlineCallbacks - def test_input_descriptor_not_found(self): - yield self.assertFailure(self.collector_client.queryBackend('GET', - '/input/' + 'a'*64), e.OONIBInputDescriptorNotFound) - - @defer.inlineCallbacks - def test_http_errors(self): - yield self.assertFailure(self.collector_client.queryBackend('PUT', - '/policy/input'), error.Error) - - @defer.inlineCallbacks - def test_create_report(self): - res = yield self.collector_client.queryBackend('POST', '/report', { - 'software_name': 'spam', - 'software_version': '2.0', - 'probe_asn': 'AS0', - 'probe_cc': 'ZZ', - 'test_name': 'foobar', - 'test_version': '1.0', - 'input_hashes': [] - }) - assert isinstance(res['report_id'], unicode) - - @defer.inlineCallbacks - def test_report_lifecycle(self): - res = yield self.collector_client.queryBackend('POST', '/report', { - 'software_name': 'spam', - 'software_version': '2.0', - 'probe_asn': 'AS0', - 'probe_cc': 'ZZ', - 'test_name': 'foobar', - 'test_version': '1.0', - 'input_hashes': [] - }) - report_id = str(res['report_id']) - - res = yield self.collector_client.queryBackend('POST', '/report/' + report_id, { - 'content': '---\nspam: ham\n...\n' - }) - - res = yield self.collector_client.queryBackend('POST', '/report/' + report_id, { - 'content': '---\nspam: ham\n...\n' - }) - - res = yield self.collector_client.queryBackend('POST', '/report/' + report_id + - '/close')