def test_add_route_with_content(self, LoadBalancer, nginx): self.storage.store_binding("inst", "app.host.com") lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.add_route("inst", "/somewhere", None, "location /x { something; }") LoadBalancer.find.assert_called_with("inst") binding_data = self.storage.find_binding("inst") self.assertDictEqual(binding_data, { "_id": "inst", "app_host": "app.host.com", "paths": [ { "path": "/", "destination": "app.host.com", }, { "path": "/somewhere", "destination": None, "content": "location /x { something; }", } ] }) nginx_manager = nginx.NginxDAV.return_value nginx_manager.update_binding.assert_any_call( lb.hosts[0].dns_name, "/somewhere", None, "location /x { something; }") nginx_manager.update_binding.assert_any_call( lb.hosts[1].dns_name, "/somewhere", None, "location /x { something; }")
def test_scale_instance_up_with_plan(self, nginx): lb = self.LoadBalancer.find.return_value lb.name = "x" lb.hosts = [mock.Mock(), mock.Mock()] self.storage.store_instance_metadata("x", plan_name=self.plan["name"], consul_token="abc-123") self.addCleanup(self.storage.remove_instance_metadata, "x") config = copy.deepcopy(self.config) config.update(self.plan["config"]) config[ "HOST_TAGS"] = "rpaas_service:test-suite-rpaas,rpaas_instance:x,consul_token:abc-123" manager = Manager(self.config) manager.scale_instance("x", 5) self.Host.create.assert_called_with("my-host-manager", "x", config) self.assertEqual(self.Host.create.call_count, 3) lb.add_host.assert_called_with(self.Host.create.return_value) self.assertEqual(lb.add_host.call_count, 3) nginx_manager = nginx.Nginx.return_value created_host = self.Host.create.return_value expected_calls = [ mock.call(created_host.dns_name, timeout=600), mock.call(created_host.dns_name, timeout=600), mock.call(created_host.dns_name, timeout=600) ] self.assertEqual(expected_calls, nginx_manager.wait_healthcheck.call_args_list)
def test_scale_instance_down(self): lb = self.LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.scale_instance("x", 1) lb.hosts[0].destroy.assert_called_once lb.remove_host.assert_called_once_with(lb.hosts[0])
def test_restore_instance_successfully(self, LoadBalancer, nginx): self.config["CLOUDSTACK_TEMPLATE_ID"] = "default_template" self.config["INSTANCE_EXTRA_TAGS"] = "x:y" self.storage.db[self.storage.plans_collection].insert({ "_id": "huge", "description": "some cool huge plan", "config": { "CLOUDSTACK_TEMPLATE_ID": "1234", "INSTANCE_EXTRA_TAGS": "a:b,c:d" } }) lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] lb.hosts[0].dns_name = '10.1.1.1' lb.hosts[0].id = 'xxx' lb.hosts[1].dns_name = '10.2.2.2' lb.hosts[1].id = 'yyy' self.storage.store_instance_metadata("x", plan_name="huge", consul_token="abc-123") manager = Manager(self.config) responses = [response for response in manager.restore_instance("x")] while "." in responses: responses.remove(".") expected_responses = [ "Restoring host xxx", ": successfully restored\n", "Restoring host yyy", ": successfully restored\n" ] self.assertListEqual(responses, expected_responses) self.assertDictContainsSubset(LoadBalancer.find.call_args[1], { 'CLOUDSTACK_TEMPLATE_ID': u'1234', 'HOST_TAGS': u'a:b,c:d' })
def test_node_status(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] lb.hosts[0].dns_name = '10.1.1.1' lb.hosts[1].dns_name = '10.2.2.2' manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.consul_manager.node_hostname.side_effect = ['vm-1', 'vm-2'] manager.consul_manager.node_status.return_value = { 'vm-1': 'OK', 'vm-2': 'DEAD' } node_status = manager.node_status("x") LoadBalancer.find.assert_called_with("x") self.assertDictEqual( node_status, { 'vm-1': { 'status': 'OK', 'address': '10.1.1.1' }, 'vm-2': { 'status': 'DEAD', 'address': '10.2.2.2' } })
def test_unbind_and_bind_instance_with_extra_path(self, LoadBalancer): self.storage.store_binding("inst", "app.host.com") self.storage.replace_binding_path("inst", "/me", "somewhere.com") lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.unbind("inst", "app.host.com") manager.bind("inst", "app2.host.com") binding_data = self.storage.find_binding("inst") self.assertDictEqual( binding_data, { "_id": "inst", "app_host": "app2.host.com", "paths": [{ "path": "/me", "destination": "somewhere.com", "content": None }, { "path": "/", "destination": "app2.host.com" }] }) LoadBalancer.find.assert_called_with("inst") manager.consul_manager.remove_location.assert_called_with("inst", "/") manager.consul_manager.write_location.assert_called_with( "inst", "/", destination="app2.host.com")
def test_add_route_with_content(self, LoadBalancer): self.storage.store_binding("inst", "app.host.com") lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.add_route("inst", "/somewhere", None, "location /x { something; }") LoadBalancer.find.assert_called_with("inst") binding_data = self.storage.find_binding("inst") self.assertDictEqual( binding_data, { "_id": "inst", "app_host": "app.host.com", "paths": [{ "path": "/", "destination": "app.host.com", }, { "path": "/somewhere", "destination": None, "content": "location /x { something; }", }] }) manager.consul_manager.write_location.assert_called_with( "inst", "/somewhere", destination=None, content="location /x { something; }")
def test_bind_instance_multiple_bind_hosts(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.bind("x", "apphost.com") binding_data = self.storage.find_binding("x") self.assertDictEqual( binding_data, { "_id": "x", "app_host": "apphost.com", "paths": [{ "path": "/", "destination": "apphost.com" }] }) LoadBalancer.find.assert_called_with("x") manager.consul_manager.write_location.assert_called_with( "x", "/", destination="apphost.com") manager.consul_manager.reset_mock() manager.bind("x", "apphost.com") self.assertEqual(0, len(manager.consul_manager.mock_calls)) with self.assertRaises(rpaas.manager.BindError): manager.bind("x", "another.host.com") self.assertEqual(0, len(manager.consul_manager.mock_calls))
def test_bind_instance_with_route(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] lb.hosts[0].dns_name = "h1" lb.hosts[1].dns_name = "h2" manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.add_route("x", "/somewhere", "my.other.host", None) manager.bind("x", "apphost.com") binding_data = self.storage.find_binding("x") self.assertDictEqual( binding_data, { "_id": "x", "app_host": "apphost.com", "paths": [{ "path": "/somewhere", "destination": "my.other.host", "content": None }, { "path": "/", "destination": "apphost.com" }] }) LoadBalancer.find.assert_called_with("x") manager.consul_manager.write_location.assert_any_call( "x", "/somewhere", destination="my.other.host", content=None) manager.consul_manager.write_location.assert_any_call( "x", "/", destination="apphost.com")
def test_unbind_and_bind_instance_with_extra_path(self, LoadBalancer, nginx): self.storage.store_binding("inst", "app.host.com") self.storage.replace_binding_path("inst", "/me", "somewhere.com") lb = LoadBalancer.find.return_value nginx_manager = nginx.NginxDAV.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.unbind("inst", "app.host.com") manager.bind("inst", "app2.host.com") binding_data = self.storage.find_binding("inst") self.assertDictEqual(binding_data, { "_id": "inst", "app_host": "app2.host.com", "paths": [ {"path": "/me", "destination": "somewhere.com", "content": None}, {"path": "/", "destination": "app2.host.com"} ] }) LoadBalancer.find.assert_called_with("inst") self.assertEqual(nginx_manager.delete_binding.call_count, 2) nginx_manager.delete_binding.assert_any_call(lb.hosts[0].dns_name, "/") nginx_manager.delete_binding.assert_any_call(lb.hosts[1].dns_name, "/") self.assertEqual(nginx_manager.update_binding.call_count, 2) nginx_manager.update_binding.assert_any_call(lb.hosts[0].dns_name, "/", "app2.host.com") nginx_manager.update_binding.assert_any_call(lb.hosts[1].dns_name, "/", "app2.host.com")
def test_remove_instance(self): self.storage.store_instance_metadata("x", plan_name="small", consul_token="abc-123") self.storage.store_le_certificate("x", "foobar.com") self.storage.store_le_certificate("x", "example.com") self.storage.store_le_certificate("y", "test.com") lb = self.LoadBalancer.find.return_value lb.hosts = [mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.remove_instance("x") config = copy.deepcopy(self.config) config.update(self.plan["config"]) self.LoadBalancer.find.assert_called_with("x", config) for h in lb.hosts: h.destroy.assert_called_once() lb.destroy.assert_called_once() self.assertEquals(self.storage.find_task("x").count(), 0) self.assertIsNone(self.storage.find_instance_metadata("x")) self.assertEquals([ cert for cert in self.storage.find_le_certificates({"name": "x"}) ], []) self.assertEquals([ cert['name'] for cert in self.storage.find_le_certificates({"name": "y"}) ][0], "y") manager.consul_manager.destroy_token.assert_called_with("abc-123") manager.consul_manager.destroy_instance.assert_called_with("x")
def test_info_with_plan(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.address = "192.168.1.1" self.storage.store_instance_metadata("x", plan_name="small") self.addCleanup(self.storage.remove_instance_metadata, "x") manager = Manager(self.config) info = manager.info("x") LoadBalancer.find.assert_called_with("x") self.assertItemsEqual(info, [ { "label": "Address", "value": "192.168.1.1" }, { "label": "Instances", "value": "0" }, { "label": "Routes", "value": "" }, { "label": "Plan", "value": "small" }, ]) self.assertEqual(manager.status("x"), "192.168.1.1")
def test_info_with_binding(self, LoadBalancer): self.storage.store_binding("inst", "app.host.com") self.storage.replace_binding_path("inst", "/arrakis", None, "location /x {\n}") lb = LoadBalancer.find.return_value lb.address = "192.168.1.1" lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) info = manager.info("inst") LoadBalancer.find.assert_called_with("inst") self.assertItemsEqual(info, [ { "label": "Address", "value": "192.168.1.1" }, { "label": "Instances", "value": "2" }, { "label": "Routes", "value": """path = / destination = app.host.com path = /arrakis content = location /x { }""" }, ]) self.assertEqual(manager.status("inst"), "192.168.1.1")
def test_restore_machine_invalid_dns_name(self, LoadBalancer): manager = Manager(self.config) lb = LoadBalancer.find.return_value lb.adress = "10.2.2.2" self.storage.store_instance_metadata("foo", consul_token="abc") with self.assertRaises(rpaas.manager.InstanceMachineNotFoundError): manager.restore_machine_instance('foo', '10.1.1.1')
def test_new_instance_with_plan(self, nginx): manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.consul_manager.generate_token.return_value = "abc-123" manager.new_instance("x", plan_name="small") host = self.Host.create.return_value config = copy.deepcopy(self.config) config.update(self.plan["config"]) config[ "HOST_TAGS"] = "rpaas_service:test-suite-rpaas,rpaas_instance:x,consul_token:abc-123" lb = self.LoadBalancer.create.return_value self.Host.create.assert_called_with("my-host-manager", "x", config) self.LoadBalancer.create.assert_called_with("my-lb-manager", "x", config) lb.add_host.assert_called_with(host) self.assertEquals(manager.storage.find_task("x").count(), 0) nginx.Nginx.assert_called_once_with(config) nginx_manager = nginx.Nginx.return_value nginx_manager.wait_healthcheck.assert_called_once_with(host.dns_name, timeout=600) metadata = manager.storage.find_instance_metadata("x") self.assertEqual( { "_id": "x", "plan_name": "small", "consul_token": "abc-123" }, metadata)
def test_delete_route_no_binding(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) with self.assertRaises(storage.InstanceNotFoundError): manager.delete_route("inst", "/zahadum") LoadBalancer.find.assert_called_with("inst")
def test_list_block(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.consul_manager.list_blocks.return_value = [{ u'block_name': 'server', u'content': 'something nice in server' }, { u'block_name': 'http', u'content': 'something nice in http' }] blocks = manager.list_blocks("inst") self.assertDictEqual(blocks[0], { 'block_name': 'server', 'content': 'something nice in server' }) self.assertDictEqual(blocks[1], { 'block_name': 'http', 'content': 'something nice in http' }) LoadBalancer.find.assert_called_with("inst") manager.consul_manager.list_blocks.assert_called_with("inst")
def test_update_instance_invalid_plan(self, LoadBalancer): LoadBalancer.find.return_value = "something" self.storage.store_instance_metadata("x", plan_name=self.plan["name"], consul_token="abc-123") manager = Manager(self.config) with self.assertRaises(storage.PlanNotFoundError): manager.update_instance("x", "large")
def test_remove_instance_remove_task_on_exception(self): self.storage.store_instance_metadata("x", plan_name="small") lb = self.LoadBalancer.find.return_value lb.hosts = [mock.Mock(side_effect=Exception("test"))] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.remove_instance("x") self.assertEquals(self.storage.find_task("x").count(), 0)
def test_new_instance_over_quota(self, nginx): manager = Manager(self.config) for name in ["a", "b", "c", "d", "e"]: manager.new_instance(name, "myteam") with self.assertRaises(QuotaExceededError) as cm: manager.new_instance("f", "myteam") self.assertEqual(str(cm.exception), "quota execeeded 5/5 used") manager.new_instance("f", "otherteam")
def test_restore_instance_service_instance_not_found( self, LoadBalancer, nginx): self.config["CLOUDSTACK_TEMPLATE_ID"] = "default_template" self.config["INSTANCE_EXTRA_TAGS"] = "x:y" LoadBalancer.find.return_value = None manager = Manager(self.config) responses = [host for host in manager.restore_instance("x")] self.assertListEqual(responses, ["instance x not found\n"])
def test_scale_instance_down(self): lb = self.LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] self.storage.store_instance_metadata("x", consul_token="abc-123") self.addCleanup(self.storage.remove_instance_metadata, "x") manager = Manager(self.config) manager.scale_instance("x", 1) lb.hosts[0].destroy.assert_called_once lb.remove_host.assert_called_once_with(lb.hosts[0])
def test_delete_route_error_no_route(self, LoadBalancer): self.storage.store_binding("inst", "app.host.com") lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) with self.assertRaises(storage.InstanceNotFoundError): manager.delete_route("inst", "/somewhere") LoadBalancer.find.assert_called_with("inst")
def test_delete_block(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.delete_block("inst", "http") LoadBalancer.find.assert_called_with("inst") manager.consul_manager.remove_block.assert_called_with("inst", "http")
def test_add_block_with_content(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.add_block("inst", "server", "location /x { something; }") LoadBalancer.find.assert_called_with("inst") manager.consul_manager.write_block.assert_called_with( "inst", "server", "location /x { something; }")
def test_remove_instance_decrement_quota(self, nginx): manager = Manager(self.config) for name in ["a", "b", "c", "d", "e"]: manager.new_instance(name) with self.assertRaises(QuotaExceededError): manager.new_instance("f") manager.remove_instance("e") manager.new_instance("f") manager.remove_instance("e") with self.assertRaises(QuotaExceededError): manager.new_instance("g")
def test_unbind_instance(self, LoadBalancer): self.storage.store_binding("inst", "app.host.com") lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.unbind("inst", "app.host.com") binding_data = self.storage.find_binding("inst") self.assertDictEqual(binding_data, {"_id": "inst", "paths": []}) LoadBalancer.find.assert_called_with("inst") manager.consul_manager.remove_location.assert_called_with("inst", "/")
def test_empty_list_blocks(self, LoadBalancer): lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.consul_manager.list_blocks.return_value = [] blocks = manager.list_blocks("inst") self.assertEqual(blocks, []) LoadBalancer.find.assert_called_with("inst") manager.consul_manager.list_blocks.assert_called_with("inst")
def test_new_instance_host_create_fail_and_raises(self, nginx): manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.consul_manager.generate_token.return_value = "abc-123" lb = self.LoadBalancer.create.return_value self.Host.create.side_effect = Exception("Host create failure") host = self.Host.create.return_value manager.new_instance("x") lb.add_host.assert_not_called() lb.destroy.assert_not_called() host.destroy.assert_not_called() self.assertEqual(self.storage.find_task("x").count(), 0)
def test_update_certificate(self, LoadBalancer): self.storage.store_binding("inst", "app.host.com") lb = LoadBalancer.find.return_value lb.hosts = [mock.Mock(), mock.Mock()] manager = Manager(self.config) manager.consul_manager = mock.Mock() manager.update_certificate("inst", "cert", "key") LoadBalancer.find.assert_called_with("inst") manager.consul_manager.set_certificate.assert_called_with( "inst", "cert", "key")