class TestRPCClient(unittest.TestCase): def setUp(self): r = Router.load({'clients': 'eth0'}) # Start the service self.service = Service({}, r) time.sleep(0.2) # Safety # Configure app configure(app) def tearDown(self): # Hack to force close RPCClient.clean() self.service.stop() def test_normal_operation(self): """Request some attributes from the RPC service""" threads = [] self.i = 0 def work(): RPCClient.call("interfaces") self.i = self.i + 1 for c in range(1, 10): t = threading.Thread(target=work) threads.append(t) t.start() for t in threads: t.join() self.assertEqual(self.i, 9) def test_reconnection(self): """Check if we can reconnect""" RPCClient.call("interfaces") self.tearDown() self.setUp() RPCClient.call("interfaces") self.tearDown() with self.assertRaises(IOError): RPCClient.call("interfaces") self.setUp() def test_exception(self): """Check that we get exceptions""" with self.assertRaises(RPCException) as e: RPCClient.call("unknown") str(e.exception)
class TestRPCClient(unittest.TestCase): def setUp(self): r = Router.load({'clients': 'eth0'}) # Start the service self.service = Service({}, r) time.sleep(0.2) # Safety # Configure app configure(app) def tearDown(self): # Hack to force close RPCClient.clean() self.service.stop() def test_normal_operation(self): """Request some attributes from the RPC service""" threads = [] self.i = 0 def work(): RPCClient.call("interfaces") self.i = self.i + 1 for c in range(1,10): t = threading.Thread(target=work) threads.append(t) t.start() for t in threads: t.join() self.assertEqual(self.i, 9) def test_reconnection(self): """Check if we can reconnect""" RPCClient.call("interfaces") self.tearDown() self.setUp() RPCClient.call("interfaces") self.tearDown() with self.assertRaises(IOError): RPCClient.call("interfaces") self.setUp() def test_exception(self): """Check that we get exceptions""" with self.assertRaises(RPCException) as e: RPCClient.call("unknown") str(e.exception)
class TestApi(unittest.TestCase): def setUp(self): r = Router.load(yaml.load(""" clients: eth0 interfaces: eth1: name: LAN description: "My first interface" qos: - qos1 - qos2 eth2: name: WAN description: "My second interface" password: 1234 qos: - qos1 qos: qos1: name: 100M description: "My first QoS" bandwidth: 100mbps netem: delay 100ms 10ms distribution experimental qos2: name: 10M description: "My second QoS" bandwidth: 10mbps netem: delay 200ms 10ms """)) self.service = Service({}, r) # helper configure(app, dict(web=dict(expire=2))) self.app = app.test_client() # web time.sleep(0.1) def tearDown(self): RPCClient.clean() self.service.stop()
class TestPersistency(unittest.TestCase): def setUp(self): self.temp = tempfile.mkdtemp() self.config = yaml.load(""" clients: eth0 interfaces: eth1: name: LAN description: "My first interface" qos: - qos1 - qos2 qos: qos1: name: 100M description: "My first QoS" bandwidth: 100mbps netem: delay 100ms 10ms distribution experimental qos2: name: 10M description: "My second QoS" bandwidth: 10mbps netem: delay 200ms 10ms """) self.realSetup() def realSetup(self): self.router = Router.load(self.config) # Start the service in a separate process self.service = Service( dict(helper=dict(save=os.path.join(self.temp, "save.pickle"))), self.router) time.sleep(0.2) # Safety def test_persistency(self): """Test the use of persistency""" self.assertEqual(self.router.clients, {}) self.router.bind("192.168.1.15", "eth1", "qos1") self.router.bind("192.168.1.16", "eth1", "qos2") self.router.bind("192.168.1.17", "eth1", "qos2") self.router.unbind("192.168.1.17") self.assertEqual(self.router.clients["192.168.1.15"], ("eth1", "qos1")) self.assertEqual(self.router.clients["192.168.1.16"], ("eth1", "qos2")) self.service.stop() self.realSetup() # Clients should have been restored self.assertEqual(self.router.clients["192.168.1.15"], ("eth1", "qos1")) self.assertEqual(self.router.clients["192.168.1.16"], ("eth1", "qos2")) def test_persistency_ipv6(self): """Test the use of persistency with an IPv6 address""" self.assertEqual(self.router.clients, {}) self.router.bind("2001:db8::1", "eth1", "qos1") self.router.bind("2001:db8::2", "eth1", "qos2") self.assertEqual(self.router.clients["2001:db8::1"], ("eth1", "qos1")) self.assertEqual(self.router.clients["2001:db8::2"], ("eth1", "qos2")) self.service.stop() self.realSetup() # Clients should have been restored self.assertEqual(self.router.clients["2001:db8::1"], ("eth1", "qos1")) self.assertEqual(self.router.clients["2001:db8::2"], ("eth1", "qos2")) def test_partial_persistency(self): """Test the use of persistency when configuration has changed""" self.router.bind("192.168.1.15", "eth1", "qos1") self.router.bind("192.168.1.16", "eth1", "qos2") self.service.stop() self.config['interfaces']['eth1']['qos'].remove('qos2') del self.config['qos']['qos2'] self.realSetup() self.assertEqual(self.router.clients["192.168.1.15"], ("eth1", "qos1")) self.assertNotIn("192.168.1.16", self.router.clients) def tearDown(self): self.service.stop() shutil.rmtree(self.temp)
class TestRPCService(unittest.TestCase): def setUp(self): r = Router.load( yaml.load(""" clients: eth0 interfaces: eth1: name: LAN description: "My first interface" qos: - qos1 - qos2 eth2: name: WAN description: "My second interface" qos: - qos1 - qos3 qos: qos1: name: 100M description: "My first QoS" bandwidth: 100mbps netem: delay 100ms 10ms distribution experimental qos2: name: 10M description: "My second QoS" bandwidth: 10mbps netem: delay 200ms 10ms qos3: name: 1M description: "My third QoS" bandwidth: 1mbps netem: delay 500ms 30ms """)) # Start the service in a separate process self.service = Service({}, r) time.sleep(0.2) # Safety def test_service_multiple_clients(self): """Check if the service is running and accept several clients""" clients = [] threads = [] for c in range(1, 8): # Open connection to RPC sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 18861)) clients.append(sock) self.i = 0 def work(c): read, write = c.makefile('rb'), c.makefile('wb', 0) # ping write.write("%s\n" % json.dumps(("ping", ))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) # bind_client write.write("%s\n" % json.dumps( ("bind_client", "192.168.1.5", "eth1", "qos1"))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) # client write.write("%s\n" % json.dumps(("client", "192.168.1.5"))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) self.assertEqual(answer["value"], ["eth1", "qos1"]) c.close() self.i = self.i + 1 # global lock # Try outside a thread just to check work(clients.pop()) next = clients.pop() for c in clients: threads.append(threading.Thread(target=work, args=(c, ))) for t in threads: t.start() for t in threads: t.join() work(next) self.assertEqual(self.i, 7) def test_service_router(self): """Grab router information from the service""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 18861)) read, write = sock.makefile('rb'), sock.makefile('wb', 0) write.write("%s\n" % json.dumps(("interfaces", ))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) # We need to compare strings because we cannot compare local # and remote dictionary. Rely on sorting self.assertEqual( answer["value"], { "eth1": { 'name': 'LAN', 'description': "My first interface", 'qos': { 'qos1': { 'name': '100M', 'description': "My first QoS", "bandwidth": "100mbps", "netem": "delay 100ms 10ms distribution experimental" }, 'qos2': { 'name': '10M', 'description': "My second QoS", "bandwidth": "10mbps", "netem": "delay 200ms 10ms" } } }, "eth2": { 'name': 'WAN', 'description': "My second interface", 'qos': { 'qos1': { 'name': '100M', 'description': "My first QoS", "bandwidth": "100mbps", "netem": "delay 100ms 10ms distribution experimental" }, 'qos3': { 'name': '1M', 'description': "My third QoS", "bandwidth": "1mbps", "netem": "delay 500ms 30ms" } } } }) sock.close() def test_bind_client(self): """Bind clients""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 18861)) read, write = sock.makefile('rb'), sock.makefile('wb', 0) def bind(ip, eth, qos): write.write("%s\n" % json.dumps(("bind_client", ip, eth, qos))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) def unbind(ip): write.write("%s\n" % json.dumps(("unbind_client", ip))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) def check(ip, value): write.write("%s\n" % json.dumps(("client", ip))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) self.assertEqual(answer["value"], value) def stats(): write.write("%s\n" % json.dumps(("stats", ))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) return answer['value'] self.assertEqual( stats(), { 'eth1': { 'clients': 0, 'details': {} }, 'eth2': { 'clients': 0, 'details': {} } }) bind("192.168.1.1", "eth2", "qos3") check("192.168.1.1", ["eth2", "qos3"]) self.assertEqual( stats(), { 'eth1': { 'clients': 0, 'details': {} }, 'eth2': { 'clients': 1, 'details': { '192.168.1.1': {} } } }) bind('192.168.1.1', 'eth2', 'qos1') check('192.168.1.1', ['eth2', 'qos1']) bind('192.168.1.2', 'eth2', 'qos1') check('192.168.1.2', ['eth2', 'qos1']) self.assertEqual( stats(), { 'eth1': { 'clients': 0, 'details': {} }, 'eth2': { 'clients': 2, 'details': { '192.168.1.1': {}, '192.168.1.2': {} } } }) bind('192.168.1.3', 'eth1', 'qos1') check('192.168.1.3', ['eth1', 'qos1']) self.assertEqual( stats(), { 'eth1': { 'clients': 1, 'details': { '192.168.1.3': {} } }, 'eth2': { 'clients': 2, 'details': { '192.168.1.1': {}, '192.168.1.2': {} } } }) # IPv6 bind('2001:db8::1', 'eth1', 'qos1') check('2001:db8::1', ['eth1', 'qos1']) self.assertEqual( stats(), { 'eth1': { 'clients': 2, 'details': { '192.168.1.3': {}, '2001:db8::1': {} } }, 'eth2': { 'clients': 2, 'details': { '192.168.1.1': {}, '192.168.1.2': {} } } }) check('192.168.1.4', None) unbind('192.168.1.4') check('192.168.1.4', None) unbind('192.168.1.1') check('192.168.1.1', None) sock.close() def test_stats(self): """Grab stats""" # We won't get much since no real binder is attached sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 18861)) read, write = sock.makefile('rb'), sock.makefile('wb', 0) def tearDown(self): self.service.stop()
class TestPersistency(unittest.TestCase): def setUp(self): self.temp = tempfile.mkdtemp() self.config = yaml.load(""" clients: eth0 interfaces: eth1: name: LAN description: "My first interface" qos: - qos1 - qos2 qos: qos1: name: 100M description: "My first QoS" bandwidth: 100mbps netem: delay 100ms 10ms distribution experimental qos2: name: 10M description: "My second QoS" bandwidth: 10mbps netem: delay 200ms 10ms """) self.realSetup() def realSetup(self): self.router = Router.load(self.config) # Start the service in a separate process self.service = Service(dict(helper=dict(save=os.path.join(self.temp, "save.pickle"))), self.router) time.sleep(0.2) # Safety def test_persistency(self): """Test the use of persistency""" self.assertEqual(self.router.clients, {}) self.router.bind("192.168.1.15", "eth1", "qos1") self.router.bind("192.168.1.16", "eth1", "qos2") self.router.bind("192.168.1.17", "eth1", "qos2") self.router.unbind("192.168.1.17") self.assertEqual(self.router.clients["192.168.1.15"], ("eth1", "qos1")) self.assertEqual(self.router.clients["192.168.1.16"], ("eth1", "qos2")) self.service.stop() self.realSetup() # Clients should have been restored self.assertEqual(self.router.clients["192.168.1.15"], ("eth1", "qos1")) self.assertEqual(self.router.clients["192.168.1.16"], ("eth1", "qos2")) def test_persistency_ipv6(self): """Test the use of persistency with an IPv6 address""" self.assertEqual(self.router.clients, {}) self.router.bind("2001:db8::1", "eth1", "qos1") self.router.bind("2001:db8::2", "eth1", "qos2") self.assertEqual(self.router.clients["2001:db8::1"], ("eth1", "qos1")) self.assertEqual(self.router.clients["2001:db8::2"], ("eth1", "qos2")) self.service.stop() self.realSetup() # Clients should have been restored self.assertEqual(self.router.clients["2001:db8::1"], ("eth1", "qos1")) self.assertEqual(self.router.clients["2001:db8::2"], ("eth1", "qos2")) def test_partial_persistency(self): """Test the use of persistency when configuration has changed""" self.router.bind("192.168.1.15", "eth1", "qos1") self.router.bind("192.168.1.16", "eth1", "qos2") self.service.stop() self.config['interfaces']['eth1']['qos'].remove('qos2') del self.config['qos']['qos2'] self.realSetup() self.assertEqual(self.router.clients["192.168.1.15"], ("eth1", "qos1")) self.assertNotIn("192.168.1.16", self.router.clients) def tearDown(self): self.service.stop() shutil.rmtree(self.temp)
class TestRPCService(unittest.TestCase): def setUp(self): r = Router.load(yaml.load(""" clients: eth0 interfaces: eth1: name: LAN description: "My first interface" qos: - qos1 - qos2 eth2: name: WAN description: "My second interface" qos: - qos1 - qos3 qos: qos1: name: 100M description: "My first QoS" bandwidth: 100mbps netem: delay 100ms 10ms distribution experimental qos2: name: 10M description: "My second QoS" bandwidth: 10mbps netem: delay 200ms 10ms qos3: name: 1M description: "My third QoS" bandwidth: 1mbps netem: delay 500ms 30ms """)) # Start the service in a separate process self.service = Service({}, r) time.sleep(0.2) # Safety def test_service_multiple_clients(self): """Check if the service is running and accept several clients""" clients = [] threads = [] for c in range(1, 8): # Open connection to RPC sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 18861)) clients.append(sock) self.i = 0 def work(c): read, write = c.makefile('rb'), c.makefile('wb', 0) # ping write.write("%s\n" % json.dumps(("ping",))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) # bind_client write.write("%s\n" % json.dumps( ("bind_client", "192.168.1.5", "eth1", "qos1"))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) # client write.write("%s\n" % json.dumps( ("client", "192.168.1.5"))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) self.assertEqual(answer["value"], ["eth1", "qos1"]) c.close() self.i = self.i + 1 # global lock # Try outside a thread just to check work(clients.pop()) next = clients.pop() for c in clients: threads.append(threading.Thread(target=work, args=(c,))) for t in threads: t.start() for t in threads: t.join() work(next) self.assertEqual(self.i, 7) def test_service_router(self): """Grab router information from the service""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 18861)) read, write = sock.makefile('rb'), sock.makefile('wb', 0) write.write("%s\n" % json.dumps(("interfaces",))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) # We need to compare strings because we cannot compare local # and remote dictionary. Rely on sorting self.assertEqual(answer["value"], { "eth1": { 'name': 'LAN', 'description': "My first interface", 'qos': { 'qos1': { 'name': '100M', 'description': "My first QoS", "bandwidth": "100mbps", "netem": "delay 100ms 10ms distribution experimental" }, 'qos2': { 'name': '10M', 'description': "My second QoS", "bandwidth": "10mbps", "netem": "delay 200ms 10ms" } } }, "eth2": { 'name': 'WAN', 'description': "My second interface", 'qos': { 'qos1': { 'name': '100M', 'description': "My first QoS", "bandwidth": "100mbps", "netem": "delay 100ms 10ms distribution experimental" }, 'qos3': { 'name': '1M', 'description': "My third QoS", "bandwidth": "1mbps", "netem": "delay 500ms 30ms" } } } }) sock.close() def test_bind_client(self): """Bind clients""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 18861)) read, write = sock.makefile('rb'), sock.makefile('wb', 0) def bind(ip, eth, qos): write.write("%s\n" % json.dumps(("bind_client", ip, eth, qos))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) def unbind(ip): write.write("%s\n" % json.dumps(("unbind_client", ip))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) def check(ip, value): write.write("%s\n" % json.dumps(("client", ip))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) self.assertEqual(answer["value"], value) def stats(): write.write("%s\n" % json.dumps(("stats",))) answer = json.loads(read.readline()) self.assertEqual(answer["status"], 0) return answer['value'] self.assertEqual(stats(), {'eth1': {'clients': 0, 'details': {}}, 'eth2': {'clients': 0, 'details': {}}}) bind("192.168.1.1", "eth2", "qos3") check("192.168.1.1", ["eth2", "qos3"]) self.assertEqual(stats(), {'eth1': {'clients': 0, 'details': {}}, 'eth2': {'clients': 1, 'details': {'192.168.1.1': {}}}}) bind('192.168.1.1', 'eth2', 'qos1') check('192.168.1.1', ['eth2', 'qos1']) bind('192.168.1.2', 'eth2', 'qos1') check('192.168.1.2', ['eth2', 'qos1']) self.assertEqual(stats(), {'eth1': {'clients': 0, 'details': {}}, 'eth2': {'clients': 2, 'details': {'192.168.1.1': {}, '192.168.1.2': {}}}}) bind('192.168.1.3', 'eth1', 'qos1') check('192.168.1.3', ['eth1', 'qos1']) self.assertEqual(stats(), {'eth1': {'clients': 1, 'details': {'192.168.1.3': {}}}, 'eth2': {'clients': 2, 'details': {'192.168.1.1': {}, '192.168.1.2': {}}}}) # IPv6 bind('2001:db8::1', 'eth1', 'qos1') check('2001:db8::1', ['eth1', 'qos1']) self.assertEqual(stats(), {'eth1': {'clients': 2, 'details': {'192.168.1.3': {}, '2001:db8::1': {}}}, 'eth2': {'clients': 2, 'details': {'192.168.1.1': {}, '192.168.1.2': {}}}}) check('192.168.1.4', None) unbind('192.168.1.4') check('192.168.1.4', None) unbind('192.168.1.1') check('192.168.1.1', None) sock.close() def test_stats(self): """Grab stats""" # We won't get much since no real binder is attached sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 18861)) read, write = sock.makefile('rb'), sock.makefile('wb', 0) def tearDown(self): self.service.stop()