commit 77474ff012275df70cd63eb68c0e54bb3ab559a6
Author: kudrom <kudrom(a)riseup.net>
Date: Mon Aug 25 23:10:45 2014 +0200
Review of policy aware changes
---
data/bouncer.yaml | 2 +-
data/policy.yaml | 2 +-
oonib/test/handler_helpers.py | 19 +-
oonib/test/test_bouncer.py | 440 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 459 insertions(+), 4 deletions(-)
diff --git a/data/bouncer.yaml b/data/bouncer.yaml
index acf2a9a..eb30cc9 100644
--- a/data/bouncer.yaml
+++ b/data/bouncer.yaml
@@ -8,7 +8,7 @@ collector:
- {name: dns_consistency, version: '0.5'}
- {name: http_requests_test, version: 0.2.3}
- {name: tcp_connect, version: '0.1'}
- - {name: captivep, version: '0.2'}
+ - {name: captiveportal, version: '0.2'}
- {name: daphn3, version: '0.1'}
- {name: dns_spoof, version: '0.2'}
- {name: http_header_field_manipulation, version: 0.1.3}
diff --git a/data/policy.yaml b/data/policy.yaml
index fcc1df4..22a14e9 100644
--- a/data/policy.yaml
+++ b/data/policy.yaml
@@ -5,7 +5,7 @@ nettest:
- {name: dns_consistency, version: 0.5}
- {name: http_requests_test, version: 0.2.3}
- {name: tcp_connect, version: 0.1}
-- {name: captivep, version: 0.2}
+- {name: captiveportal, version: 0.2}
- {name: daphne3, version: 0.1}
- {name: dns_spoof, version: 0.2}
- {name: http_header_field_manipulation, version: 0.1.3}
diff --git a/oonib/test/handler_helpers.py b/oonib/test/handler_helpers.py
index 843d5c5..e6dc0ba 100644
--- a/oonib/test/handler_helpers.py
+++ b/oonib/test/handler_helpers.py
@@ -1,3 +1,4 @@
+import sys
import os
import socket
import json
@@ -6,6 +7,8 @@ import shutil
from twisted.internet import reactor, defer
from twisted.trial import unittest
+from oonib.config import config
+
from cyclone import httpclient
@@ -32,6 +35,7 @@ class HandlerTestCase(unittest.TestCase):
app = None
_port = None
_listener = None
+ config_filename = ''
@property
def port(self):
@@ -39,16 +43,27 @@ class HandlerTestCase(unittest.TestCase):
self._port = random_unused_port()
return self._port
+ def make_dir(self, dir):
+ if not os.path.exists(dir):
+ os.mkdir(dir)
+ self.directories.add(dir)
+
def setUp(self, *args, **kw):
self.filenames = set()
self.directories = set()
+ self.old_arguments = sys.argv
+ if self.config_filename != '':
+ sys.argv = ['test_oonib', '-c', self.config_filename]
+ config.load()
if self.app:
self._listener = reactor.listenTCP(self.port, self.app)
- return unittest.TestCase.setUp(self, *args, **kw)
+ return super(HandlerTestCase, self).setUp()
def tearDown(self):
+ sys.argv = self.old_arguments
for filename in self.filenames:
- os.remove(filename)
+ if os.path.exists(filename):
+ os.remove(filename)
for dir in self.directories:
shutil.rmtree(dir)
if self._listener:
diff --git a/oonib/test/test_bouncer.py b/oonib/test/test_bouncer.py
new file mode 100644
index 0000000..6785c2f
--- /dev/null
+++ b/oonib/test/test_bouncer.py
@@ -0,0 +1,440 @@
+# -*- encoding: utf8 -*-
+import json
+
+from twisted.internet import defer
+
+from cyclone import web
+
+from oonib.bouncer.api import bouncerAPI
+from oonib.test.handler_helpers import HandlerTestCase
+
+fake_bouncer_file = """
+collector:
+ fake_address:
+ policy:
+ input:
+ - {id: fake_id}
+ nettest:
+ - {name: fake_nettest, version: 1.0}
+ - {name: another_fake_nettest, version: 2.0}
+ test-helper: {fake_test_helper: 'fake_hostname'}
+"""
+
+fake_default_collector = """
+collector:
+ fake_address:
+ policy:
+ input:
+ - {id: fake_id}
+ nettest:
+ - {name: fake_nettest, version: 1.0}
+ - {name: another_fake_nettest, version: 2.0}
+ test-helper: {fake_test_helper: 'fake_hostname'}
+ default_collector:
+ test-helper: {fake_test_helper: 'fake_hostname'}
+"""
+
+fake_bouncer_file_multiple_collectors = """
+collector:
+ fake_addressA:
+ policy:
+ input:
+ - {id: fake_id}
+ nettest:
+ - {name: fake_nettest, version: 1.0}
+ - {name: another_fake_nettest, version: 2.0}
+ test-helper: {fake_test_helper: 'fake_hostname'}
+
+ fake_addressB:
+ policy:
+ input:
+ - {id: fake_id}
+ nettest:
+ - {name: fake_nettest, version: 1.0}
+ - {name: another_fake_nettest, version: 2.0}
+ test-helper: {fake_test_helper: 'fake_hostname'}
+"""
+
+fake_for_test_helper_request = """
+collector:
+ fake_addressA:
+ policy:
+ input:
+ - {id: fake_id}
+ nettest:
+ - {name: fake_nettest, version: 1.0}
+ test-helper: {fake_test_helper: 'fake_hostname', exotic_test_helper: 'fake_hostname'}
+
+ fake_addressB:
+ test-helper: {fake_test_helper: 'fake_hostname'}
+"""
+
+reports_dir = 'data/reports'
+archive_dir = 'data/archive'
+input_dir = 'data/inputs'
+decks_dir = 'data/decks'
+bouncer_filename = 'fake_bouncer_file.yaml'
+fake_config_file = """
+main:
+ report_dir: %s
+ archive_dir: %s
+ input_dir: %s
+ deck_dir: %s
+ bouncer_file: %s
+
+helpers:
+ fake_test_helper:
+ attribute: value
+""" % (reports_dir, archive_dir, input_dir, decks_dir, bouncer_filename)
+
+
+class BaseTestBouncer(HandlerTestCase):
+ def setUp(self, *args, **kw):
+ self.make_dir(reports_dir)
+ self.make_dir(archive_dir)
+ self.make_dir(input_dir)
+ self.make_dir(decks_dir)
+
+ self.config_filename = 'fake_config.conf'
+ with open(self.config_filename, 'w') as config_file:
+ config_file.write(fake_config_file)
+
+ super(BaseTestBouncer, self).setUp()
+ self.filenames.add(bouncer_filename)
+ self.filenames.add(self.config_filename)
+
+
+class TestBouncer(BaseTestBouncer):
+ app = web.Application(bouncerAPI, name='bouncerAPI')
+
+ def setUp(self, *args, **kw):
+ with open(bouncer_filename, 'w') as bouncer_file:
+ bouncer_file.write(fake_bouncer_file)
+ super(TestBouncer, self).setUp()
+
+ @defer.inlineCallbacks
+ def test_void_net_tests(self):
+ data = {
+ 'net-tests': [
+ {
+ "test-helpers": ['fake_test_helper'],
+ "input-hashes": [],
+ "name": '',
+ "version": '',
+ },
+ ]
+ }
+
+ response = yield self.request('/bouncer', 'POST', data)
+ response_body = json.loads(response.body)
+
+ self.assertIn('error', response_body)
+ self.assertEqual('collector-not-found', response_body['error'])
+
+ @defer.inlineCallbacks
+ def test_net_tests(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)
+
+ 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_multiple_net_tests(self):
+ data = {
+ 'net-tests': [
+ {
+ "test-helpers": [],
+ "input-hashes": [],
+ "name": 'fake_nettest',
+ "version": '1.0',
+ },
+ {
+ "test-helpers": [],
+ "input-hashes": [],
+ "name": 'another_fake_nettest',
+ "version": '1.0',
+ }
+ ]
+ }
+
+ response = yield self.request('/bouncer', 'POST', data)
+ response_body = json.loads(response.body)
+
+ self.assertIn('net-tests', response_body)
+ self.assertEqual(len(response_body['net-tests']), 2)
+ self.assertIn('name', response_body['net-tests'][0])
+ self.assertEqual(response_body['net-tests'][0]['name'], 'fake_nettest')
+ self.assertIn('name', response_body['net-tests'][1])
+ self.assertEqual(response_body['net-tests'][1]['name'], 'another_fake_nettest')
+
+ @defer.inlineCallbacks
+ def test_invalid_net_test(self):
+ data = {
+ 'net-tests': [
+ {
+ "test-helpers": [],
+ "input-hashes": [],
+ "name": 'invalid_nettest',
+ "version": '1.0',
+ },
+ ]
+ }
+
+ response = yield self.request('/bouncer', 'POST', data)
+ response_body = json.loads(response.body)
+
+ self.assertIn('error', response_body)
+ self.assertEqual('collector-not-found', response_body['error'])
+
+ @defer.inlineCallbacks
+ def test_net_tests_with_input(self):
+ data = {
+ 'net-tests': [
+ {
+ "test-helpers": [],
+ "input-hashes": ['fake_id'],
+ "name": 'fake_nettest',
+ "version": '1.0',
+ },
+ ]
+ }
+
+ response = yield self.request('/bouncer', '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('input-hashes', response_body['net-tests'][0])
+ self.assertEqual(len(response_body['net-tests'][0]['input-hashes']), 1)
+ self.assertEqual(response_body['net-tests'][0]['input-hashes'][0], 'fake_id')
+
+ @defer.inlineCallbacks
+ def test_net_tests_with_input(self):
+ data = {
+ 'net-tests': [
+ {
+ "test-helpers": [],
+ "input-hashes": ['invalid_id'],
+ "name": 'fake_nettest',
+ "version": '1.0',
+ },
+ ]
+ }
+
+ response = yield self.request('/bouncer', 'POST', data)
+ response_body = json.loads(response.body)
+
+ self.assertIn('error', response_body)
+ self.assertEqual('collector-not-found', response_body['error'])
+
+ @defer.inlineCallbacks
+ def test_net_tests_with_test_helper(self):
+ data = {
+ 'net-tests': [
+ {
+ "test-helpers": ['fake_test_helper'],
+ "input-hashes": [],
+ "name": 'fake_nettest',
+ "version": '1.0',
+ },
+ ]
+ }
+
+ response = yield self.request('/bouncer', '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('test-helpers', response_body['net-tests'][0])
+ self.assertEqual(len(response_body['net-tests'][0]['test-helpers']), 1)
+ self.assertEqual(response_body['net-tests'][0]['test-helpers']['fake_test_helper'], 'fake_hostname')
+
+ @defer.inlineCallbacks
+ def test_net_tests_with_invalid_test_helper(self):
+ data = {
+ 'net-tests': [
+ {
+ "test-helpers": ['invalid_test_helper'],
+ "input-hashes": [],
+ "name": 'fake_nettest',
+ "version": '1.0',
+ },
+ ]
+ }
+
+ response = yield self.request('/bouncer', 'POST', data)
+ response_body = json.loads(response.body)
+
+ self.assertIn('error', response_body)
+ self.assertEqual('collector-not-found', response_body['error'])
+
+ @defer.inlineCallbacks
+ def test_invalid_request(self):
+ data = {
+ 'something_weird': 'nsa'
+ }
+
+ response = yield self.request('/bouncer', 'POST', data)
+ response_body = json.loads(response.body)
+
+ self.assertIn('error', response_body)
+ self.assertEqual('test-helpers-or-net-test-key-missing', response_body['error'])
+
+
+class TestDefaultCollector(BaseTestBouncer):
+ app = web.Application(bouncerAPI, name='bouncerAPI')
+
+ def setUp(self, *args, **kw):
+ with open(bouncer_filename, 'w') as bouncer_file:
+ bouncer_file.write(fake_default_collector)
+ super(TestDefaultCollector, self).setUp()
+
+ @defer.inlineCallbacks
+ def test_default_collector(self):
+ data = {
+ 'net-tests': [
+ {
+ "test-helpers": [],
+ "input-hashes": [],
+ "name": 'imaginary_nettest',
+ "version": '1.0',
+ },
+ ]
+ }
+
+ response = yield self.request('/bouncer', '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'], 'imaginary_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'], 'default_collector')
+
+
+class TestMultipleCollectors(BaseTestBouncer):
+ app = web.Application(bouncerAPI, name='bouncerAPI')
+
+ def setUp(self, *args, **kw):
+ with open(bouncer_filename, 'w') as bouncer_file:
+ bouncer_file.write(fake_bouncer_file_multiple_collectors)
+ super(TestMultipleCollectors, self).setUp()
+
+ @defer.inlineCallbacks
+ def test_multiple_collectors(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)
+
+ 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.assertIn(response_body['net-tests'][0]['collector'], ['fake_addressA', 'fake_addressB'])
+
+
+class TestHelperTests(BaseTestBouncer):
+ app = web.Application(bouncerAPI, name='bouncerAPI')
+
+ def setUp(self, *args, **kw):
+ with open(bouncer_filename, 'w') as bouncer_file:
+ bouncer_file.write(fake_for_test_helper_request)
+ super(TestHelperTests, self).setUp()
+
+ @defer.inlineCallbacks
+ def test_invalid_helper(self):
+ data = {
+ 'test-helpers': ['invalid_test_helper']
+ }
+ response = yield self.request('/bouncer', 'POST', data)
+ response_body = json.loads(response.body)
+
+ self.assertIn('error', response_body)
+ self.assertEqual('test-helper-not-found', response_body['error'])
+
+ @defer.inlineCallbacks
+ def test_multiple_collectors(self):
+ data = {
+ 'test-helpers': ['fake_test_helper']
+ }
+
+ response = yield self.request('/bouncer', '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_multiple_helpers(self):
+ data = {
+ 'test-helpers': ['fake_test_helper', 'exotic_test_helper']
+ }
+
+ response = yield self.request('/bouncer', 'POST', data)
+ response_body = json.loads(response.body)
+
+ self.assertEqual(len(response_body), 3)
+ self.assertIn('fake_test_helper', response_body)
+ self.assertIn('exotic_test_helper', response_body)
+ self.assertIn('default', response_body)
+ self.assertIn(response_body['fake_test_helper']['collector'], ['fake_addressA', 'fake_addressB'])
+ self.assertEqual(response_body['exotic_test_helper']['collector'], 'fake_addressA')
+ self.assertEqual('fake_addressB', response_body['default']['collector'])