From 002eb5f68e608a3defb303cb4a2ca8d4dafd0e3a Mon Sep 17 00:00:00 2001 From: Akihiro Motoki Date: Thu, 4 Jan 2018 03:02:36 +0900 Subject: [PATCH] Switch project/admin routers tests to mock Partially-Implements: blueprint mock-framework-in-unit-tests Change-Id: I6aa7da58f640d65156f3592d93ba034c4fca3056 --- .../dashboards/admin/routers/tests.py | 299 ++-- .../dashboards/project/routers/tests.py | 1213 ++++++++++------- 2 files changed, 891 insertions(+), 621 deletions(-) diff --git a/openstack_dashboard/dashboards/admin/routers/tests.py b/openstack_dashboard/dashboards/admin/routers/tests.py index f2f6e01ae1..6b046ae6be 100644 --- a/openstack_dashboard/dashboards/admin/routers/tests.py +++ b/openstack_dashboard/dashboards/admin/routers/tests.py @@ -12,11 +12,9 @@ # License for the specific language governing permissions and limitations # under the License. -from django import http from django.urls import reverse -from mox3.mox import IgnoreArg -from mox3.mox import IsA +import mock from openstack_dashboard import api from openstack_dashboard.dashboards.project.routers import tests as r_test @@ -25,56 +23,91 @@ from openstack_dashboard.test import helpers as test INDEX_TEMPLATE = 'horizon/common/_data_table_view.html' -class RouterTests(test.BaseAdminViewTests, r_test.RouterTests): +class RouterMixin(r_test.RouterMixin): + + support_l3_agent = True + + def _get_detail(self, router, extraroute=True): + + supported_extensions = { + 'extraroute': extraroute, + 'router_availability_zone': True, + 'l3_agent_scheduler': self.support_l3_agent, + } + + def get_supported_extension(*args): + alias = args[1] + return supported_extensions[alias] + + self.mock_is_extension_supported.side_effect = get_supported_extension + + self.mock_router_get.return_value = router + self.mock_port_list.return_value = [self.ports.first()] + self._mock_external_network_get(router) + if self.support_l3_agent: + agent = self.agents.list()[1] + self.mock_list_l3_agent_hosting_router.return_value = [agent] + + res = self.client.get(reverse('horizon:%s' + ':routers:detail' % self.DASHBOARD, + args=[router.id])) + return res + + def _check_get_detail(self, router, extraroute=True): + super(RouterMixin, self)._check_get_detail(router, extraroute) + self.mock_is_extension_supported.assert_any_call( + test.IsHttpRequest(), 'l3_agent_scheduler') + if self.support_l3_agent: + self.mock_list_l3_agent_hosting_router.assert_called_once_with( + test.IsHttpRequest(), router.id) + else: + self.mock_list_l3_agent_hosting_router.assert_not_called() + + +class RouterTests(RouterMixin, r_test.RouterTestCase, test.BaseAdminViewTests): DASHBOARD = 'admin' INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD) DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD - def _get_detail(self, router, extraroute=True): - res = super(RouterTests, self)._get_detail(router, extraroute, - lookup_l3=True) - return res - - @test.create_stubs({api.neutron: ('router_list', 'network_list', + @test.create_mocks({api.neutron: ('router_list', + 'network_list', 'is_extension_supported'), api.keystone: ('tenant_list',)}) def test_index(self): tenants = self.tenants.list() - api.neutron.router_list( - IsA(http.HttpRequest)).AndReturn(self.routers.list()) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([tenants, False]) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_list.return_value = [tenants, False] + self.mock_is_extension_supported.return_value = True self._mock_external_network_list() - self.mox.ReplayAll() - res = self.client.get(self.INDEX_URL) self.assertTemplateUsed(res, INDEX_TEMPLATE) routers = res.context['table'].data self.assertItemsEqual(routers, self.routers.list()) - @test.create_stubs({api.neutron: ('router_list', - 'is_extension_supported'), - api.keystone: ('tenant_list',)}) + self.mock_router_list.assert_called_once_with(test.IsHttpRequest()) + self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), "router_availability_zone") + self._check_mock_external_network_list() + + @test.create_mocks({api.neutron: ('router_list', + 'is_extension_supported')}) def test_index_router_list_exception(self): - api.neutron.router_list( - IsA(http.HttpRequest)).AndRaise(self.exceptions.neutron) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) - self.mox.ReplayAll() + self.mock_router_list.side_effect = self.exceptions.neutron + self.mock_is_extension_supported.return_value = True res = self.client.get(self.INDEX_URL) self.assertTemplateUsed(res, INDEX_TEMPLATE) self.assertEqual(len(res.context['table'].data), 0) self.assertMessageCount(res, error=1) + self.mock_router_list.assert_called_once_with(test.IsHttpRequest()) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), "router_availability_zone") - @test.create_stubs({api.neutron: ('agent_list', + @test.create_mocks({api.neutron: ('agent_list', 'router_list_on_l3_agent', 'network_list', 'is_extension_supported'), @@ -82,21 +115,12 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests): def test_list_by_l3_agent(self): tenants = self.tenants.list() agent = self.agents.list()[1] - api.neutron.agent_list( - IsA(http.HttpRequest), - id=agent.id).AndReturn([agent]) - api.neutron.router_list_on_l3_agent( - IsA(http.HttpRequest), - agent.id, - search_opts=None).AndReturn(self.routers.list()) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([tenants, False]) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) + self.mock_agent_list.return_value = [agent] + self.mock_router_list_on_l3_agent.return_value = self.routers.list() + self.mock_tenant_list.return_value = [tenants, False] + self.mock_is_extension_supported.return_value = True self._mock_external_network_list() - self.mox.ReplayAll() l3_list_url = reverse('horizon:admin:routers:l3_agent_list', args=[agent.id]) res = self.client.get(l3_list_url) @@ -105,20 +129,25 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests): routers = res.context['table'].data self.assertItemsEqual(routers, self.routers.list()) - @test.create_stubs({api.neutron: ('router_list', 'network_list', + self.mock_agent_list.assert_called_once_with( + test.IsHttpRequest(), id=agent.id) + self.mock_router_list_on_l3_agent.assert_called_once_with( + test.IsHttpRequest(), agent.id, search_opts=None) + self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), "router_availability_zone") + self._check_mock_external_network_list() + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', 'is_extension_supported'), api.keystone: ('tenant_list',)}) def test_set_external_network_empty(self): router = self.routers.first() - api.neutron.router_list( - IsA(http.HttpRequest)).AndReturn([router]) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([self.tenants.list(), False]) + self.mock_router_list.return_value = [router] + self.mock_is_extension_supported.return_value = True + self.mock_tenant_list.return_value = [self.tenants.list(), False] self._mock_external_network_list(alter_ids=True) - self.mox.ReplayAll() res = self.client.get(self.INDEX_URL) @@ -129,36 +158,32 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests): self.assertTemplateUsed(res, INDEX_TEMPLATE) self.assertMessageCount(res, error=1) - @test.create_stubs({api.neutron: ('router_list', 'network_list', - 'port_list', 'router_delete', + self.mock_router_list.assert_called_once_with(test.IsHttpRequest()) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), "router_availability_zone") + self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) + self._check_mock_external_network_list() + + @test.create_mocks({api.neutron: ('list_l3_agent_hosting_router',)}) + def test_router_detail(self): + super(RouterTests, self).test_router_detail() + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', + 'port_list', + 'router_delete', 'is_extension_supported'), api.keystone: ('tenant_list',)}) def test_router_delete(self): router = self.routers.first() tenants = self.tenants.list() - api.neutron.router_list( - IsA(http.HttpRequest)).AndReturn(self.routers.list()) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([tenants, False]) - self._mock_external_network_list() - api.neutron.router_list( - IsA(http.HttpRequest)).AndReturn(self.routers.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .MultipleTimes().AndReturn(True) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([tenants, False]) - self._mock_external_network_list() - api.neutron.port_list(IsA(http.HttpRequest), - device_id=router.id, device_owner=IgnoreArg())\ - .AndReturn([]) - api.neutron.router_delete(IsA(http.HttpRequest), router.id) - api.neutron.router_list( - IsA(http.HttpRequest)).AndReturn(self.routers.list()) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([tenants, False]) - self._mock_external_network_list() - self.mox.ReplayAll() + + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_list.return_value = [tenants, False] + self._mock_external_network_list(count=3) + self.mock_is_extension_supported.return_value = True + self.mock_port_list.return_value = [] + self.mock_router_delete.return_value = None res = self.client.get(self.INDEX_URL) @@ -169,8 +194,25 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests): self.assertIn('Deleted Router: ' + router.name, res.content.decode('utf-8')) - @test.create_stubs({api.neutron: ('router_list', 'network_list', - 'port_list', 'router_remove_interface', + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_router_list, 3, + mock.call(test.IsHttpRequest())) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_list, 3, + mock.call(test.IsHttpRequest())) + self._check_mock_external_network_list(count=3) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_is_extension_supported, 3, + mock.call(test.IsHttpRequest(), 'router_availability_zone')) + self.mock_port_list.assert_called_once_with( + test.IsHttpRequest(), device_id=router.id, device_owner=mock.ANY) + self.mock_router_delete.assert_called_once_with( + test.IsHttpRequest(), router.id) + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', + 'port_list', + 'router_remove_interface', 'router_delete', 'is_extension_supported'), api.keystone: ('tenant_list',)}) @@ -178,32 +220,14 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests): router = self.routers.first() ports = self.ports.list() tenants = self.tenants.list() - api.neutron.router_list( - IsA(http.HttpRequest)).AndReturn(self.routers.list()) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([tenants, False]) - self._mock_external_network_list() - api.neutron.router_list( - IsA(http.HttpRequest)).AndReturn(self.routers.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .MultipleTimes().AndReturn(True) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([tenants, False]) - self._mock_external_network_list() - api.neutron.port_list(IsA(http.HttpRequest), - device_id=router.id, device_owner=IgnoreArg())\ - .AndReturn(ports) - for port in ports: - api.neutron.router_remove_interface(IsA(http.HttpRequest), - router.id, port_id=port.id) - api.neutron.router_delete(IsA(http.HttpRequest), router.id) - api.neutron.router_list( - IsA(http.HttpRequest)).AndReturn(self.routers.list()) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([tenants, False]) - self._mock_external_network_list() - self.mox.ReplayAll() + + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_list.return_value = [tenants, False] + self._mock_external_network_list(count=3) + self.mock_is_extension_supported.return_value = True + self.mock_port_list.return_value = ports + self.mock_router_remove_interface.return_value = None + self.mock_router_delete.return_value = None res = self.client.get(self.INDEX_URL) @@ -214,28 +238,44 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests): self.assertIn('Deleted Router: ' + router.name, res.content.decode('utf-8')) - @test.create_stubs({api.neutron: ('is_extension_supported',)}) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_router_list, 3, + mock.call(test.IsHttpRequest())) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_list, 3, + mock.call(test.IsHttpRequest())) + self._check_mock_external_network_list(count=3) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_is_extension_supported, 3, + mock.call(test.IsHttpRequest(), 'router_availability_zone')) + self.mock_port_list.assert_called_once_with( + test.IsHttpRequest(), device_id=router.id, device_owner=mock.ANY) + self.mock_router_remove_interface.assert_has_calls( + [mock.call(test.IsHttpRequest(), router.id, port_id=port.id) + for port in ports] + ) + self.mock_router_delete.assert_called_once_with( + test.IsHttpRequest(), router.id) + + @test.create_mocks({api.neutron: ('is_extension_supported',)}) @test.update_settings(FILTER_DATA_FIRST={'admin.routers': True}) def test_routers_list_with_admin_filter_first(self): - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .MultipleTimes().AndReturn(True) - self.mox.ReplayAll() + self.mock_is_extension_supported.return_value = True res = self.client.get(self.INDEX_URL) self.assertTemplateUsed(res, INDEX_TEMPLATE) routers = res.context['table'].data self.assertItemsEqual(routers, []) - @test.create_stubs({api.keystone: ('tenant_list',), - api.neutron: ('is_extension_supported',)}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + + @test.create_mocks({api.neutron: ('is_extension_supported',), + api.keystone: ('tenant_list',)}) def test_routers_list_with_non_exist_tenant_filter(self): - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .MultipleTimes().AndReturn(True) - api.keystone.tenant_list(IsA(http.HttpRequest))\ - .AndReturn([self.tenants.list(), False]) - self.mox.ReplayAll() + self.mock_is_extension_supported.return_value = True + self.mock_tenant_list.return_value = [self.tenants.list(), False] + self.client.post( self.INDEX_URL, data={'routers__filter_admin_routers__q_field': 'project', @@ -245,19 +285,28 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests): routers = res.context['table'].data self.assertItemsEqual(routers, []) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_is_extension_supported, 2, + mock.call(test.IsHttpRequest(), "router_availability_zone")) + self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) + class RouterTestsNoL3Agent(RouterTests): - def _get_detail(self, router, extraroute=True): - return super(RouterTests, self)._get_detail(router, extraroute, - lookup_l3=True, - support_l3_agent=False) + + support_l3_agent = False -class RouterRouteTest(test.BaseAdminViewTests, r_test.RouterRouteTests): +class RouterRouteTests(RouterMixin, + r_test.RouterRouteTestCase, + test.BaseAdminViewTests): DASHBOARD = 'admin' INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD) DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD - def _get_detail(self, router, extraroute=True): - return super(RouterRouteTest, self)._get_detail(router, extraroute, - lookup_l3=True) + @test.create_mocks({api.neutron: ('list_l3_agent_hosting_router',)}) + def test_extension_hides_without_routes(self): + super(RouterRouteTests, self).test_extension_hides_without_routes() + + @test.create_mocks({api.neutron: ('list_l3_agent_hosting_router',)}) + def test_routerroute_detail(self): + super(RouterRouteTests, self).test_routerroute_detail() diff --git a/openstack_dashboard/dashboards/project/routers/tests.py b/openstack_dashboard/dashboards/project/routers/tests.py index 71d6a4f7bc..3b389d0aab 100644 --- a/openstack_dashboard/dashboards/project/routers/tests.py +++ b/openstack_dashboard/dashboards/project/routers/tests.py @@ -13,11 +13,9 @@ # under the License. import copy -from django import http from django.urls import reverse -from mox3.mox import IgnoreArg -from mox3.mox import IsA +import mock import six from openstack_dashboard import api @@ -28,86 +26,76 @@ INDEX_TEMPLATE = 'horizon/common/_data_table_view.html' class RouterMixin(object): - @test.create_stubs({ - api.neutron: ('router_get', 'port_list', - 'network_get', 'is_extension_supported', - 'list_l3_agent_hosting_router'), - }) - def _get_detail(self, router, extraroute=True, lookup_l3=False, - support_l3_agent=True): - api.neutron.is_extension_supported(IsA(http.HttpRequest), 'extraroute')\ - .MultipleTimes().AndReturn(extraroute) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .MultipleTimes().AndReturn(True) - if lookup_l3: - api.neutron.is_extension_supported(IsA(http.HttpRequest), - 'l3_agent_scheduler')\ - .AndReturn(support_l3_agent) - api.neutron.router_get(IsA(http.HttpRequest), router.id)\ - .AndReturn(router) - api.neutron.port_list(IsA(http.HttpRequest), - device_id=router.id)\ - .AndReturn([self.ports.first()]) + + def _get_detail(self, router, extraroute=True): + + supported_extensions = { + 'extraroute': extraroute, + 'router_availability_zone': True, + } + + def get_supported_extension(*args): + alias = args[1] + return supported_extensions[alias] + + self.mock_is_extension_supported.side_effect = get_supported_extension + + self.mock_router_get.return_value = router + self.mock_port_list.return_value = [self.ports.first()] self._mock_external_network_get(router) - if lookup_l3 and support_l3_agent: - agent = self.agents.list()[1] - api.neutron.list_l3_agent_hosting_router(IsA(http.HttpRequest), router.id)\ - .AndReturn([agent]) - self.mox.ReplayAll() res = self.client.get(reverse('horizon:%s' ':routers:detail' % self.DASHBOARD, args=[router.id])) return res - def _mock_external_network_list(self, alter_ids=False): - search_opts = {'router:external': True} + def _check_get_detail(self, router, extraroute=True): + self.mock_is_extension_supported.assert_any_call( + test.IsHttpRequest(), 'extraroute') + self.mock_is_extension_supported.assert_any_call( + test.IsHttpRequest(), 'router_availability_zone') + self.mock_router_get.assert_called_once_with( + test.IsHttpRequest(), router.id) + self.mock_port_list.assert_called_once_with(test.IsHttpRequest(), + device_id=router.id) + self._check_mock_external_network_get(router) + + def _mock_external_network_list(self, count=1, alter_ids=False): ext_nets = [n for n in self.networks.list() if n['router:external']] if alter_ids: for ext_net in ext_nets: ext_net.id += 'some extra garbage' - api.neutron.network_list( - IsA(http.HttpRequest), - **search_opts).AndReturn(ext_nets) + self.mock_network_list.side_effect = [ext_nets for i in range(count)] + + def _check_mock_external_network_list(self, count=1): + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_network_list, count, + mock.call(test.IsHttpRequest(), **{'router:external': True})) def _mock_external_network_get(self, router): - ext_net_id = router.external_gateway_info['network_id'] ext_net = self.networks.list()[2] - api.neutron.network_get(IsA(http.HttpRequest), ext_net_id, - expand_subnet=False).AndReturn(ext_net) + self.mock_network_get.return_value = ext_net - def _mock_network_list(self, tenant_id): - api.neutron.network_list( - IsA(http.HttpRequest), - shared=False, - tenant_id=tenant_id).AndReturn(self.networks.list()) - api.neutron.network_list( - IsA(http.HttpRequest), - shared=True).AndReturn([]) + def _check_mock_external_network_get(self, router): + ext_net_id = router.external_gateway_info['network_id'] + self.mock_network_get.assert_called_once_with( + test.IsHttpRequest(), ext_net_id, expand_subnet=False) -class RouterTests(RouterMixin, test.TestCase): - DASHBOARD = 'project' - INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD) - DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD +class RouterTestCase(object): - @test.create_stubs({api.neutron: ('router_list', 'network_list', + use_mox = False + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', 'is_extension_supported'), quotas: ('tenant_quota_usages',)}) def test_index(self): quota_data = self.neutron_quota_usages.first() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - quotas.tenant_quota_usages( - IsA(http.HttpRequest), targets=('router', )) \ - .MultipleTimes().AndReturn(quota_data) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_quota_usages.return_value = quota_data + self.mock_is_extension_supported.return_value = True self._mock_external_network_list() - self.mox.ReplayAll() res = self.client.get(self.INDEX_URL) @@ -115,23 +103,25 @@ class RouterTests(RouterMixin, test.TestCase): routers = res.context['table'].data self.assertItemsEqual(routers, self.routers.list()) - @test.create_stubs({api.neutron: ('router_list', 'network_list', + self.mock_router_list.assert_called_once_with( + test.IsHttpRequest(), tenant_id=self.tenant.id) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_quota_usages, 2, + mock.call(test.IsHttpRequest(), targets=('router',))) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self._check_mock_external_network_list() + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', 'is_extension_supported'), quotas: ('tenant_quota_usages',)}) def test_index_router_list_exception(self): quota_data = self.neutron_quota_usages.first() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).MultipleTimes().AndRaise( - self.exceptions.neutron) - quotas.tenant_quota_usages( - IsA(http.HttpRequest), targets=('router', )) \ - .MultipleTimes().AndReturn(quota_data) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) + self.mock_router_list.side_effect = self.exceptions.neutron + self.mock_tenant_quota_usages.return_value = quota_data + self.mock_is_extension_supported.return_value = True self._mock_external_network_list() - self.mox.ReplayAll() res = self.client.get(self.INDEX_URL) @@ -139,23 +129,26 @@ class RouterTests(RouterMixin, test.TestCase): self.assertEqual(len(res.context['table'].data), 0) self.assertMessageCount(res, error=1) - @test.create_stubs({api.neutron: ('router_list', 'network_list', + self.mock_router_list.assert_called_once_with( + test.IsHttpRequest(), tenant_id=self.tenant.id) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_quota_usages, 2, + mock.call(test.IsHttpRequest(), targets=('router',))) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self._check_mock_external_network_list() + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', 'is_extension_supported'), quotas: ('tenant_quota_usages',)}) def test_set_external_network_empty(self): router = self.routers.first() quota_data = self.neutron_quota_usages.first() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).MultipleTimes().AndReturn([router]) - quotas.tenant_quota_usages( - IsA(http.HttpRequest), targets=('router', )) \ - .MultipleTimes().AndReturn(quota_data) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) + self.mock_router_list.return_value = [router] + self.mock_tenant_quota_usages.return_value = quota_data + self.mock_is_extension_supported.return_value = True self._mock_external_network_list(alter_ids=True) - self.mox.ReplayAll() res = self.client.get(self.INDEX_URL) @@ -166,6 +159,19 @@ class RouterTests(RouterMixin, test.TestCase): self.assertTemplateUsed(res, INDEX_TEMPLATE) self.assertMessageCount(res, error=1) + self.mock_router_list.assert_called_once_with( + test.IsHttpRequest(), tenant_id=self.tenant.id) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_quota_usages, 2, + mock.call(test.IsHttpRequest(), targets=('router',))) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self._check_mock_external_network_list() + + @test.create_mocks({api.neutron: ('router_get', + 'port_list', + 'network_get', + 'is_extension_supported')}) def test_router_detail(self): router = self.routers.first() res = self._get_detail(router) @@ -174,48 +180,37 @@ class RouterTests(RouterMixin, test.TestCase): ports = res.context['interfaces_table'].data self.assertItemsEqual(ports, [self.ports.first()]) - @test.create_stubs({api.neutron: ('router_get',)}) + self._check_get_detail(router) + + @test.create_mocks({api.neutron: ('router_get',)}) def test_router_detail_exception(self): router = self.routers.first() - api.neutron.router_get(IsA(http.HttpRequest), router.id)\ - .AndRaise(self.exceptions.neutron) - self.mox.ReplayAll() + self.mock_router_get.side_effect = self.exceptions.neutron res = self.client.get(reverse('horizon:%s' ':routers:detail' % self.DASHBOARD, args=[router.id])) self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_list', 'network_list', - 'port_list', 'router_delete', + self.mock_router_get.assert_called_once_with(test.IsHttpRequest(), + router.id) + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', + 'port_list', + 'router_delete', 'is_extension_supported'), quotas: ('tenant_quota_usages',)}) def test_router_delete(self): router = self.routers.first() quota_data = self.neutron_quota_usages.first() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - quotas.tenant_quota_usages( - IsA(http.HttpRequest), targets=('router', )) \ - .MultipleTimes().AndReturn(quota_data) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .MultipleTimes().AndReturn(True) - self._mock_external_network_list() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - self._mock_external_network_list() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - self._mock_external_network_list() - api.neutron.port_list(IsA(http.HttpRequest), - device_id=router.id, device_owner=IgnoreArg())\ - .AndReturn([]) - api.neutron.router_delete(IsA(http.HttpRequest), router.id) - self.mox.ReplayAll() + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_quota_usages.return_value = quota_data + # router_availability_zone ext + self.mock_is_extension_supported.return_value = True + self._mock_external_network_list(count=3) + self.mock_port_list.return_value = [] + self.mock_router_delete.return_value = None res = self.client.get(self.INDEX_URL) @@ -226,8 +221,25 @@ class RouterTests(RouterMixin, test.TestCase): self.assertIn('Deleted Router: ' + router.name, res.content.decode('utf-8')) - @test.create_stubs({api.neutron: ('router_list', 'network_list', - 'port_list', 'router_remove_interface', + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_router_list, 3, + mock.call(test.IsHttpRequest(), tenant_id=self.tenant.id)) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_quota_usages, 4, + mock.call(test.IsHttpRequest(), targets=('router', ))) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_is_extension_supported, 3, + mock.call(test.IsHttpRequest(), 'router_availability_zone')) + self._check_mock_external_network_list(count=3) + self.mock_port_list.assert_called_once_with( + test.IsHttpRequest(), device_id=router.id, device_owner=mock.ANY) + self.mock_router_delete.assert_called_once_with( + test.IsHttpRequest(), router.id) + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', + 'port_list', + 'router_remove_interface', 'router_delete', 'is_extension_supported'), quotas: ('tenant_quota_usages',)}) @@ -235,32 +247,14 @@ class RouterTests(RouterMixin, test.TestCase): router = self.routers.first() ports = self.ports.list() quota_data = self.neutron_quota_usages.first() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - quotas.tenant_quota_usages( - IsA(http.HttpRequest), targets=('router', )) \ - .MultipleTimes().AndReturn(quota_data) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .MultipleTimes().AndReturn(True) - self._mock_external_network_list() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - self._mock_external_network_list() - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - self._mock_external_network_list() - api.neutron.port_list(IsA(http.HttpRequest), - device_id=router.id, device_owner=IgnoreArg())\ - .AndReturn(ports) - for port in ports: - api.neutron.router_remove_interface(IsA(http.HttpRequest), - router.id, port_id=port.id) - api.neutron.router_delete(IsA(http.HttpRequest), router.id) - self.mox.ReplayAll() + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_quota_usages.return_value = quota_data + # router_availability_zone ext + self.mock_is_extension_supported.return_value = True + self._mock_external_network_list(count=3) + self.mock_port_list.return_value = ports + self.mock_router_remove_interface.return_value = None + self.mock_router_delete.return_value = None res = self.client.get(self.INDEX_URL) @@ -271,39 +265,64 @@ class RouterTests(RouterMixin, test.TestCase): self.assertIn('Deleted Router: ' + router.name, res.content.decode('utf-8')) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_router_list, 3, + mock.call(test.IsHttpRequest(), tenant_id=self.tenant.id)) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_quota_usages, 4, + mock.call(test.IsHttpRequest(), targets=('router', ))) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_is_extension_supported, 3, + mock.call(test.IsHttpRequest(), 'router_availability_zone')) + self._check_mock_external_network_list(count=3) + self.mock_port_list.assert_called_once_with( + test.IsHttpRequest(), device_id=router.id, device_owner=mock.ANY) + self.assertEqual(len(ports), + self.mock_router_remove_interface.call_count) + self.mock_router_remove_interface.assert_has_calls( + [mock.call(test.IsHttpRequest(), router.id, port_id=port.id) + for port in ports] + ) + self.mock_router_delete.assert_called_once_with( + test.IsHttpRequest(), router.id) -class RouterActionTests(RouterMixin, test.TestCase): + +class RouterTests(RouterMixin, RouterTestCase, test.TestCase): DASHBOARD = 'project' INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD) DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD - @test.create_stubs({api.neutron: ('router_create', + +class RouterActionTests(test.TestCase): + DASHBOARD = 'project' + INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD) + DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD + + use_mox = False + + @test.create_mocks({api.neutron: ('router_create', 'get_feature_permission', 'network_list', 'is_extension_supported')}) def test_router_create_post(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "create_router_enable_snat")\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "create")\ - .AndReturn(False) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "l3-ha", "create")\ - .AndReturn(False) - api.neutron.network_list(IsA(http.HttpRequest))\ - .AndReturn(self.networks.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(False) - params = {'name': router.name, - 'admin_state_up': router.admin_state_up} - api.neutron.router_create(IsA(http.HttpRequest), **params)\ - .AndReturn(router) - self.mox.ReplayAll() + features = { + ('ext-gw-mode', 'create_router_enable_snat'): True, + ('dvr', 'create'): False, + ('l3-ha', 'create'): False, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission + self.mock_network_list.return_value = self.networks.list() + # router_availability_zone ext + self.mock_is_extension_supported.return_value = False + self.mock_router_create.return_value = router + form_data = {'name': router.name, 'admin_state_up': router.admin_state_up} url = reverse('horizon:%s:routers:create' % self.DASHBOARD) @@ -312,33 +331,45 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_create', + self.assertEqual(3, self.mock_get_feature_permission.call_count) + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), + 'ext-gw-mode', 'create_router_enable_snat'), + mock.call(test.IsHttpRequest(), 'dvr', 'create'), + mock.call(test.IsHttpRequest(), 'l3-ha', 'create'), + ]) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self.mock_router_create.assert_called_once_with( + test.IsHttpRequest(), + name=router.name, + admin_state_up=router.admin_state_up) + + @test.create_mocks({api.neutron: ('router_create', 'get_feature_permission', 'network_list', 'is_extension_supported')}) def test_router_create_post_mode_server_default(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "create_router_enable_snat")\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "create")\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "l3-ha", "create")\ - .AndReturn(True) - api.neutron.network_list(IsA(http.HttpRequest))\ - .AndReturn(self.networks.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(False) - params = {'name': router.name, - 'admin_state_up': router.admin_state_up} - api.neutron.router_create(IsA(http.HttpRequest), **params)\ - .AndReturn(router) - self.mox.ReplayAll() + features = { + ('ext-gw-mode', 'create_router_enable_snat'): True, + ('dvr', 'create'): True, + ('l3-ha', 'create'): True, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission + self.mock_network_list.return_value = self.networks.list() + # router_availability_zone ext + self.mock_is_extension_supported.return_value = False + self.mock_router_create.return_value = router + form_data = {'name': router.name, 'mode': 'server_default', 'ha': 'server_default', @@ -349,35 +380,45 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_create', + self.assertEqual(3, self.mock_get_feature_permission.call_count) + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), + 'ext-gw-mode', 'create_router_enable_snat'), + mock.call(test.IsHttpRequest(), 'dvr', 'create'), + mock.call(test.IsHttpRequest(), 'l3-ha', 'create'), + ]) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self.mock_router_create.assert_called_once_with( + test.IsHttpRequest(), + name=router.name, + admin_state_up=router.admin_state_up) + + @test.create_mocks({api.neutron: ('router_create', 'get_feature_permission', 'network_list', 'is_extension_supported')}) def test_dvr_ha_router_create_post(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "create_router_enable_snat")\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "create")\ - .MultipleTimes().AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "l3-ha", "create")\ - .MultipleTimes().AndReturn(True) - api.neutron.network_list(IsA(http.HttpRequest))\ - .AndReturn(self.networks.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(False) - param = {'name': router.name, - 'distributed': True, - 'ha': True, - 'admin_state_up': router.admin_state_up} - api.neutron.router_create(IsA(http.HttpRequest), **param)\ - .AndReturn(router) - self.mox.ReplayAll() + features = { + ('ext-gw-mode', 'create_router_enable_snat'): True, + ('dvr', 'create'): True, + ('l3-ha', 'create'): True, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission + self.mock_network_list.return_value = self.networks.list() + # router_availability_zone ext + self.mock_is_extension_supported.return_value = False + self.mock_router_create.return_value = router + form_data = {'name': router.name, 'mode': 'distributed', 'ha': 'enabled', @@ -388,37 +429,47 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_create', + self.assertEqual(3, self.mock_get_feature_permission.call_count) + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), + 'ext-gw-mode', 'create_router_enable_snat'), + mock.call(test.IsHttpRequest(), 'dvr', 'create'), + mock.call(test.IsHttpRequest(), 'l3-ha', 'create'), + ]) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self.mock_router_create.assert_called_once_with( + test.IsHttpRequest(), + name=router.name, distributed=True, ha=True, + admin_state_up=router.admin_state_up) + + @test.create_mocks({api.neutron: ('router_create', 'get_feature_permission', 'network_list', 'is_extension_supported', 'list_availability_zones')}) def test_az_router_create_post(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "create_router_enable_snat")\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "create")\ - .MultipleTimes().AndReturn(False) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "l3-ha", "create")\ - .AndReturn(False) - api.neutron.network_list(IsA(http.HttpRequest))\ - .AndReturn(self.networks.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) - api.neutron.list_availability_zones(IsA(http.HttpRequest), - "router", "available")\ - .AndReturn(self.neutron_availability_zones.list()) - param = {'name': router.name, - 'availability_zone_hints': ['nova'], - 'admin_state_up': router.admin_state_up} - api.neutron.router_create(IsA(http.HttpRequest), **param)\ - .AndReturn(router) - self.mox.ReplayAll() + + features = { + ('ext-gw-mode', 'create_router_enable_snat'): True, + ('dvr', 'create'): False, + ('l3-ha', 'create'): False, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission + self.mock_network_list.return_value = self.networks.list() + # router_availability_zone ext + self.mock_is_extension_supported.return_value = True + self.mock_list_availability_zones.return_value = \ + self.neutron_availability_zones.list() + self.mock_router_create.return_value = router form_data = {'name': router.name, 'mode': 'server_default', @@ -431,33 +482,40 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_create', + self.assertEqual(3, self.mock_get_feature_permission.call_count) + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), + 'ext-gw-mode', 'create_router_enable_snat'), + mock.call(test.IsHttpRequest(), 'dvr', 'create'), + mock.call(test.IsHttpRequest(), 'l3-ha', 'create'), + ]) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self.mock_list_availability_zones.assert_called_once_with( + test.IsHttpRequest(), 'router', 'available') + self.mock_router_create.assert_called_once_with( + test.IsHttpRequest(), + name=router.name, + availability_zone_hints=['nova'], + admin_state_up=router.admin_state_up) + + @test.create_mocks({api.neutron: ('router_create', 'get_feature_permission', 'network_list', 'is_extension_supported')}) def test_router_create_post_with_admin_state_up(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "create_router_enable_snat")\ - .AndReturn(False) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "create")\ - .MultipleTimes().AndReturn(False) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "l3-ha", "create")\ - .MultipleTimes().AndReturn(False) - api.neutron.network_list(IsA(http.HttpRequest))\ - .AndReturn(self.networks.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(False) - param = {'name': router.name, - 'admin_state_up': False} - api.neutron.router_create(IsA(http.HttpRequest), **param)\ - .AndReturn(router) + self.mock_get_feature_permission.side_effect = [ + False, # ext-gw-mode, create_router_enable_snat + False, # dvr, create + False, # l3-ha, create + ] + self.mock_network_list.return_value = self.networks.list() + self.mock_is_extension_supported.return_value = False + self.mock_router_create.return_value = router - self.mox.ReplayAll() form_data = {'name': router.name, 'admin_state_up': False} url = reverse('horizon:%s:routers:create' % self.DASHBOARD) @@ -466,33 +524,42 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_create', + self.assertEqual(3, self.mock_get_feature_permission.call_count) + self.mock_get_feature_permission.assert_has_calls( + [mock.call(test.IsHttpRequest(), + "ext-gw-mode", "create_router_enable_snat"), + mock.call(test.IsHttpRequest(), "dvr", "create"), + mock.call(test.IsHttpRequest(), "l3-ha", "create")]) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), "router_availability_zone") + self.mock_router_create.assert_called_once_with( + test.IsHttpRequest(), name=router.name, admin_state_up=False) + + @test.create_mocks({api.neutron: ('router_create', 'get_feature_permission', 'network_list', 'is_extension_supported')}) def test_router_create_post_exception_error_case_409(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "create_router_enable_snat")\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "create")\ - .MultipleTimes().AndReturn(False) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "l3-ha", "create")\ - .AndReturn(False) + + features = { + ('ext-gw-mode', 'create_router_enable_snat'): True, + ('dvr', 'create'): False, + ('l3-ha', 'create'): False, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission + self.mock_network_list.return_value = self.networks.list() + # router_availability_zone ext + self.mock_is_extension_supported.return_value = False self.exceptions.neutron.status_code = 409 - api.neutron.network_list(IsA(http.HttpRequest))\ - .MultipleTimes().AndReturn(self.networks.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(False) - params = {'name': router.name, - 'admin_state_up': router.admin_state_up} - api.neutron.router_create(IsA(http.HttpRequest), **params)\ - .AndRaise(self.exceptions.neutron) - self.mox.ReplayAll() + self.mock_router_create.side_effect = self.exceptions.neutron form_data = {'name': router.name, 'admin_state_up': router.admin_state_up} @@ -502,33 +569,45 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_create', + self.assertEqual(3, self.mock_get_feature_permission.call_count) + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), + 'ext-gw-mode', 'create_router_enable_snat'), + mock.call(test.IsHttpRequest(), 'dvr', 'create'), + mock.call(test.IsHttpRequest(), 'l3-ha', 'create'), + ]) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self.mock_router_create.assert_called_once_with( + test.IsHttpRequest(), + name=router.name, + admin_state_up=router.admin_state_up) + + @test.create_mocks({api.neutron: ('router_create', 'get_feature_permission', - 'is_extension_supported', - 'network_list')}) + 'network_list', + 'is_extension_supported')}) def test_router_create_post_exception_error_case_non_409(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "create_router_enable_snat")\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "create")\ - .MultipleTimes().AndReturn(False) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "l3-ha", "create")\ - .MultipleTimes().AndReturn(False) + + features = { + ('ext-gw-mode', 'create_router_enable_snat'): True, + ('dvr', 'create'): False, + ('l3-ha', 'create'): False, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission + self.mock_network_list.return_value = self.networks.list() + # router_availability_zone ext + self.mock_is_extension_supported.return_value = False self.exceptions.neutron.status_code = 999 - api.neutron.network_list(IsA(http.HttpRequest))\ - .MultipleTimes().AndReturn(self.networks.list()) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .MultipleTimes().AndReturn(False) - params = {'name': router.name, - 'admin_state_up': router.admin_state_up} - api.neutron.router_create(IsA(http.HttpRequest), **params)\ - .AndRaise(self.exceptions.neutron) - self.mox.ReplayAll() + self.mock_router_create.side_effect = self.exceptions.neutron form_data = {'name': router.name, 'admin_state_up': router.admin_state_up} @@ -538,28 +617,56 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_get', + self.assertEqual(3, self.mock_get_feature_permission.call_count) + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), + 'ext-gw-mode', 'create_router_enable_snat'), + mock.call(test.IsHttpRequest(), 'dvr', 'create'), + mock.call(test.IsHttpRequest(), 'l3-ha', 'create'), + ]) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self.mock_router_create.assert_called_once_with( + test.IsHttpRequest(), + name=router.name, + admin_state_up=router.admin_state_up) + + @test.create_mocks({api.neutron: ('router_get', 'get_feature_permission')}) def _test_router_update_get(self, dvr_enabled=False, - current_dvr=False, - ha_enabled=False): + current_dvr=False, ha_enabled=False): router = [r for r in self.routers.list() if r.distributed == current_dvr][0] - api.neutron.router_get(IsA(http.HttpRequest), router.id)\ - .AndReturn(router) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "update")\ - .AndReturn(dvr_enabled) - # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables - # PUT operation. It will be fixed in Kilo cycle. - # api.neutron.get_feature_permission(IsA(http.HttpRequest), - # "l3-ha", "update")\ - # .AndReturn(ha_enabled) - self.mox.ReplayAll() + self.mock_router_get.return_value = router + features = { + ('dvr', 'update'): dvr_enabled, + # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables + # PUT operation. It will be fixed in Kilo cycle. + # ('l3-ha', 'update'): ha_enabled, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission url = reverse('horizon:%s:routers:update' % self.DASHBOARD, args=[router.id]) - return self.client.get(url) + res = self.client.get(url) + + self.mock_router_get.assert_called_once_with( + test.IsHttpRequest(), router.id) + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), "dvr", "update"), + # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables + # PUT operation. It will be fixed in Kilo cycle. + # mock.call(test.IsHttpRequest(), "l3-ha", "update"), + ]) + + return res def test_router_update_get_dvr_disabled(self): res = self._test_router_update_get(dvr_enabled=False) @@ -595,26 +702,25 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertContains(res, pattern, html=True) self.assertNotContains(res, 'centralized') - @test.create_stubs({api.neutron: ('router_get', + @test.create_mocks({api.neutron: ('router_get', 'router_update', 'get_feature_permission')}) def test_router_update_post_dvr_ha_disabled(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "update")\ - .AndReturn(False) - # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables - # PUT operation. It will be fixed in Kilo cycle. - # api.neutron.get_feature_permission(IsA(http.HttpRequest), - # "l3-ha", "update")\ - # .AndReturn(False) - api.neutron.router_update(IsA(http.HttpRequest), router.id, - name=router.name, - admin_state_up=router.admin_state_up)\ - .AndReturn(router) - api.neutron.router_get(IsA(http.HttpRequest), router.id)\ - .AndReturn(router) - self.mox.ReplayAll() + features = { + ('dvr', 'update'): False, + # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables + # PUT operation. It will be fixed in Kilo cycle. + # ('l3-ha', 'update'): False, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission + self.mock_router_update.return_value = router + self.mock_router_get.return_value = router form_data = {'router_id': router.id, 'name': router.name, @@ -625,27 +731,37 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertRedirectsNoFollow(res, self.INDEX_URL) - @test.create_stubs({api.neutron: ('router_get', + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), "dvr", "update"), + # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables + # PUT operation. It will be fixed in Kilo cycle. + # mock.call(test.IsHttpRequest(), "l3-ha", "update"), + ]) + self.mock_router_update.assert_called_once_with( + test.IsHttpRequest(), router.id, + name=router.name, admin_state_up=router.admin_state_up) + self.mock_router_get.assert_called_once_with( + test.IsHttpRequest(), router.id) + + @test.create_mocks({api.neutron: ('router_get', 'router_update', 'get_feature_permission')}) def test_router_update_post_dvr_ha_enabled(self): router = self.routers.first() - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "dvr", "update")\ - .AndReturn(True) - # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables - # PUT operation. It will be fixed in Kilo cycle. - # api.neutron.get_feature_permission(IsA(http.HttpRequest), - # "l3-ha", "update")\ - # .AndReturn(True) - api.neutron.router_update(IsA(http.HttpRequest), router.id, - name=router.name, - admin_state_up=router.admin_state_up, - # ha=True, - distributed=True).AndReturn(router) - api.neutron.router_get(IsA(http.HttpRequest), router.id)\ - .AndReturn(router) - self.mox.ReplayAll() + features = { + ('dvr', 'update'): True, + # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables + # PUT operation. It will be fixed in Kilo cycle. + # ('l3-ha', 'update'): True, + } + + def fake_get_feature_permission(*args): + return features[(args[1], args[2])] + + self.mock_get_feature_permission.side_effect = \ + fake_get_feature_permission + self.mock_router_update.return_value = router + self.mock_router_get.return_value = router form_data = {'router_id': router.id, 'name': router.name, @@ -658,30 +774,48 @@ class RouterActionTests(RouterMixin, test.TestCase): self.assertRedirectsNoFollow(res, self.INDEX_URL) + self.mock_get_feature_permission.assert_has_calls([ + mock.call(test.IsHttpRequest(), "dvr", "update"), + # TODO(amotoki): Due to Neutron Bug 1378525, Neutron disables + # PUT operation. It will be fixed in Kilo cycle. + # mock.call(test.IsHttpRequest(), "l3-ha", "update"), + ]) + self.mock_router_update.assert_called_once_with( + test.IsHttpRequest(), router.id, + name=router.name, + admin_state_up=router.admin_state_up, + # ha=True, + distributed=True) + self.mock_router_get.assert_called_once_with( + test.IsHttpRequest(), router.id) + def _test_router_addinterface(self, raise_error=False): router = self.routers.first() subnet = self.subnets.first() port = self.ports.first() - add_interface = api.neutron.router_add_interface( - IsA(http.HttpRequest), router.id, subnet_id=subnet.id) if raise_error: - add_interface.AndRaise(self.exceptions.neutron) + self.mock_router_add_interface.side_effect = \ + self.exceptions.neutron else: - add_interface.AndReturn({'subnet_id': subnet.id, - 'port_id': port.id}) - api.neutron.port_get(IsA(http.HttpRequest), port.id)\ - .AndReturn(port) + self.mock_router_add_interface.return_value = { + 'subnet_id': subnet.id, + 'port_id': port.id + } + self.mock_port_get.return_value = port + self._check_router_addinterface(router, subnet) + self.mock_router_add_interface.assert_called_once_with( + test.IsHttpRequest(), router.id, subnet_id=subnet.id) + if not raise_error: + self.mock_port_get.assert_called_once_with( + test.IsHttpRequest(), port.id) + def _check_router_addinterface(self, router, subnet, ip_address=''): - # mock APIs used to show router detail - api.neutron.router_get(IsA(http.HttpRequest), router.id)\ - .AndReturn(router) - api.neutron.port_list(IsA(http.HttpRequest), device_id=router.id)\ - .AndReturn([]) - self._mock_network_list(router['tenant_id']) - self.mox.ReplayAll() + self.mock_router_get.return_value = router + self.mock_port_list.return_value = [] + self.mock_network_list.side_effect = [self.networks.list(), []] form_data = {'router_id': router.id, 'router_name': router.name, @@ -695,7 +829,20 @@ class RouterActionTests(RouterMixin, test.TestCase): detail_url = reverse(self.DETAIL_PATH, args=[router.id]) self.assertRedirectsNoFollow(res, detail_url) - @test.create_stubs({api.neutron: ('router_get', + self.mock_router_get.assert_called_once_with( + test.IsHttpRequest(), router.id) + self.mock_port_list.assert_called_once_with( + test.IsHttpRequest(), device_id=router.id) + self.assertEqual(2, self.mock_network_list.call_count) + self.mock_network_list.assert_has_calls([ + mock.call(test.IsHttpRequest(), + shared=False, + tenant_id=router['tenant_id']), + mock.call(test.IsHttpRequest(), + shared=True), + ]) + + @test.create_mocks({api.neutron: ('router_get', 'router_add_interface', 'port_get', 'network_list', @@ -703,7 +850,7 @@ class RouterActionTests(RouterMixin, test.TestCase): def test_router_addinterface(self): self._test_router_addinterface() - @test.create_stubs({api.neutron: ('router_get', + @test.create_mocks({api.neutron: ('router_get', 'router_add_interface', 'network_list', 'port_list')}) @@ -716,96 +863,126 @@ class RouterActionTests(RouterMixin, test.TestCase): subnet = self.subnets.first() port = self.ports.first() ip_addr = port['fixed_ips'][0]['ip_address'] - self._setup_mock_addinterface_ip_addr(router, subnet, port, - ip_addr, errors) - self._check_router_addinterface(router, subnet, ip_addr) + self._setup_mock_addinterface_ip_addr( + router, subnet, port, ip_addr, errors) + self._check_router_addinterface( + router, subnet, ip_addr) + self._check_mock_addinterface_ip_addr( + router, subnet, port, ip_addr, errors) - def _setup_mock_addinterface_ip_addr(self, router, subnet, port, - ip_addr, errors=None): + def _setup_mock_addinterface_ip_addr(self, router, subnet, port, ip_addr, + errors=None): errors = errors or [] - subnet_get = api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id) + + if 'subnet_get' in errors: + self.mock_subnet_get.side_effect = self.exceptions.neutron + return + + self.mock_subnet_get.return_value = subnet + + if 'port_create' in errors: + self.mock_port_create.side_effect = self.exceptions.neutron + return + + self.mock_port_create.return_value = port + + if 'add_interface' not in errors: + self.mock_router_add_interface.return_value = None + return + + self.mock_router_add_interface.side_effect = self.exceptions.neutron + + if 'port_delete' in errors: + self.mock_port_delete.side_effect = self.exceptions.neutron + else: + self.mock_port_delete.return_value = None + + def _check_mock_addinterface_ip_addr(self, router, subnet, port, ip_addr, + errors=None): + errors = errors or [] + + self.mock_subnet_get.assert_called_once_with( + test.IsHttpRequest(), subnet.id) if 'subnet_get' in errors: - subnet_get.AndRaise(self.exceptions.neutron) return - subnet_get.AndReturn(subnet) params = {'network_id': subnet.network_id, 'fixed_ips': [{'subnet_id': subnet.id, 'ip_address': ip_addr}]} - port_create = api.neutron.port_create(IsA(http.HttpRequest), **params) + self.mock_port_create.assert_called_once_with( + test.IsHttpRequest(), **params) if 'port_create' in errors: - port_create.AndRaise(self.exceptions.neutron) return - port_create.AndReturn(port) - add_inf = api.neutron.router_add_interface( - IsA(http.HttpRequest), router.id, port_id=port.id) + self.mock_router_add_interface.assert_called_once_with( + test.IsHttpRequest(), router.id, port_id=port.id) if 'add_interface' not in errors: return - add_inf.AndRaise(self.exceptions.neutron) - port_delete = api.neutron.port_delete(IsA(http.HttpRequest), port.id) - if 'port_delete' in errors: - port_delete.AndRaise(self.exceptions.neutron) + self.mock_port_delete.assert_called_once_with( + test.IsHttpRequest(), port.id) - @test.create_stubs({api.neutron: ('router_add_interface', 'subnet_get', + @test.create_mocks({api.neutron: ('router_add_interface', + 'subnet_get', 'port_create', - 'router_get', 'network_list', + 'router_get', + 'network_list', 'port_list')}) def test_router_addinterface_ip_addr(self): self._test_router_addinterface_ip_addr() - @test.create_stubs({api.neutron: ('subnet_get', 'router_get', - 'network_list', 'port_list')}) + @test.create_mocks({api.neutron: ('subnet_get', + 'router_get', + 'network_list', + 'port_list')}) def test_router_addinterface_ip_addr_exception_subnet_get(self): self._test_router_addinterface_ip_addr(errors=['subnet_get']) - @test.create_stubs({api.neutron: ('subnet_get', 'port_create', - 'router_get', 'network_list', + @test.create_mocks({api.neutron: ('subnet_get', + 'port_create', + 'router_get', + 'network_list', 'port_list')}) def test_router_addinterface_ip_addr_exception_port_create(self): self._test_router_addinterface_ip_addr(errors=['port_create']) - @test.create_stubs({api.neutron: ('router_add_interface', 'subnet_get', - 'port_create', 'port_delete', - 'router_get', 'network_list', + @test.create_mocks({api.neutron: ('router_add_interface', + 'subnet_get', + 'port_create', + 'port_delete', + 'router_get', + 'network_list', 'port_list')}) def test_router_addinterface_ip_addr_exception_add_interface(self): self._test_router_addinterface_ip_addr(errors=['add_interface']) - @test.create_stubs({api.neutron: ('router_add_interface', 'subnet_get', - 'port_create', 'port_delete', - 'router_get', 'network_list', + @test.create_mocks({api.neutron: ('router_add_interface', + 'subnet_get', + 'port_create', + 'port_delete', + 'router_get', + 'network_list', 'port_list')}) def test_router_addinterface_ip_addr_exception_port_delete(self): self._test_router_addinterface_ip_addr(errors=['add_interface', 'port_delete']) - @test.create_stubs({api.neutron: ('router_get', + @test.create_mocks({api.neutron: ('router_get', 'router_add_gateway', 'network_list', - 'is_extension_supported')}) + 'is_extension_supported', + 'get_feature_permission')}) def test_router_add_gateway(self): router = self.routers.first() network = self.networks.first() - api.neutron.router_add_gateway( - IsA(http.HttpRequest), - router.id, - network.id, - True).AndReturn(None) - api.neutron.router_get( - IsA(http.HttpRequest), router.id).AndReturn(router) - search_opts = {'router:external': True} - api.neutron.network_list( - IsA(http.HttpRequest), **search_opts).AndReturn([network]) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - 'ext-gw-mode')\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "update_router_enable_snat")\ - .AndReturn(True) - self.mox.ReplayAll() + + self.mock_router_add_gateway.return_value = None + self.mock_router_get.return_value = router + self.mock_network_list.return_value = [network] + # ext-gw-mode + self.mock_is_extension_supported.return_value = True + # ext-gw-mode and update_router_enable_snat + self.mock_get_feature_permission.return_value = True form_data = {'router_id': router.id, 'router_name': router.name, @@ -819,31 +996,33 @@ class RouterActionTests(RouterMixin, test.TestCase): detail_url = self.INDEX_URL self.assertRedirectsNoFollow(res, detail_url) - @test.create_stubs({api.neutron: ('router_get', + self.mock_router_add_gateway.assert_called_once_with( + test.IsHttpRequest(), router.id, network.id, True) + self.mock_router_get.assert_called_once_with( + test.IsHttpRequest(), router.id) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'ext-gw-mode') + self.mock_get_feature_permission.assert_called_once_with( + test.IsHttpRequest(), 'ext-gw-mode', 'update_router_enable_snat') + + @test.create_mocks({api.neutron: ('router_get', 'router_add_gateway', 'network_list', - 'is_extension_supported')}) + 'is_extension_supported', + 'get_feature_permission')}) def test_router_add_gateway_exception(self): router = self.routers.first() network = self.networks.first() - api.neutron.router_add_gateway( - IsA(http.HttpRequest), - router.id, - network.id, - True).AndRaise(self.exceptions.neutron) - api.neutron.router_get( - IsA(http.HttpRequest), router.id).AndReturn(router) - search_opts = {'router:external': True} - api.neutron.network_list( - IsA(http.HttpRequest), **search_opts).AndReturn([network]) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - 'ext-gw-mode')\ - .AndReturn(True) - api.neutron.get_feature_permission(IsA(http.HttpRequest), - "ext-gw-mode", - "update_router_enable_snat")\ - .AndReturn(True) - self.mox.ReplayAll() + + self.mock_router_add_gateway.side_effect = self.exceptions.neutron + self.mock_router_get.return_value = router + self.mock_network_list.return_value = [network] + # ext-gw-mode + self.mock_is_extension_supported.return_value = True + # ext-gw-mode and update_router_enable_snat + self.mock_get_feature_permission.return_value = True form_data = {'router_id': router.id, 'router_name': router.name, @@ -857,12 +1036,26 @@ class RouterActionTests(RouterMixin, test.TestCase): detail_url = self.INDEX_URL self.assertRedirectsNoFollow(res, detail_url) + self.mock_router_add_gateway.assert_called_once_with( + test.IsHttpRequest(), router.id, network.id, True) + self.mock_router_get.assert_called_once_with( + test.IsHttpRequest(), router.id) + self.mock_network_list.assert_called_once_with( + test.IsHttpRequest(), **{'router:external': True}) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'ext-gw-mode') + self.mock_get_feature_permission.assert_called_once_with( + test.IsHttpRequest(), 'ext-gw-mode', 'update_router_enable_snat') -class RouterRouteTests(RouterMixin, test.TestCase): - DASHBOARD = 'project' - INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD) - DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD +class RouterRouteTestCase(object): + + use_mox = False + + @test.create_mocks({api.neutron: ('router_get', + 'port_list', + 'network_get', + 'is_extension_supported')}) def test_extension_hides_without_routes(self): router = self.routers_with_routes.first() res = self._get_detail(router, extraroute=False) @@ -870,6 +1063,12 @@ class RouterRouteTests(RouterMixin, test.TestCase): self.assertTemplateUsed(res, 'horizon/common/_detail.html') self.assertNotIn('extra_routes_table', res.context) + self._check_get_detail(router, extraroute=False) + + @test.create_mocks({api.neutron: ('router_get', + 'port_list', + 'network_get', + 'is_extension_supported')}) def test_routerroute_detail(self): router = self.routers_with_routes.first() res = self._get_detail(router, extraroute=True) @@ -879,23 +1078,20 @@ class RouterRouteTests(RouterMixin, test.TestCase): routes_dict = [r._apidict for r in routes] self.assertItemsEqual(routes_dict, router['routes']) - @test.create_stubs({api.neutron: ('router_get', 'router_update')}) + self._check_get_detail(router, extraroute=True) + + @test.create_mocks({api.neutron: ('router_get', + 'router_update')}) def _test_router_addrouterroute(self, raise_error=False): pre_router = self.routers_with_routes.first() post_router = copy.deepcopy(pre_router) route = {'nexthop': '10.0.0.5', 'destination': '40.0.1.0/24'} post_router['routes'].insert(0, route) - api.neutron.router_get(IsA(http.HttpRequest), pre_router.id)\ - .MultipleTimes().AndReturn(pre_router) - params = {} - params['routes'] = post_router['routes'] - router_update = api.neutron.router_update(IsA(http.HttpRequest), - pre_router.id, **params) + self.mock_router_get.return_value = pre_router if raise_error: - router_update.AndRaise(self.exceptions.neutron) + self.mock_router_update.side_effect = self.exceptions.neutron else: - router_update.AndReturn({'router': post_router}) - self.mox.ReplayAll() + self.mock_router_update.return_value = {'router': post_router} form_data = copy.deepcopy(route) form_data['router_id'] = pre_router.id @@ -906,6 +1102,12 @@ class RouterRouteTests(RouterMixin, test.TestCase): detail_url = reverse(self.DETAIL_PATH, args=[pre_router.id]) self.assertRedirectsNoFollow(res, detail_url) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_router_get, 2, + mock.call(test.IsHttpRequest(), pre_router.id)) + self.mock_router_update.assert_called_once_with( + test.IsHttpRequest(), pre_router.id, routes=post_router['routes']) + def test_router_addrouterroute(self): if self.DASHBOARD == 'project': self._test_router_addrouterroute() @@ -916,8 +1118,10 @@ class RouterRouteTests(RouterMixin, test.TestCase): self._test_router_addrouterroute(raise_error=True) self.assertMessageCount(error=1) - @test.create_stubs({api.neutron: ('router_get', 'router_update', - 'network_get', 'port_list', + @test.create_mocks({api.neutron: ('router_get', + 'router_update', + 'network_get', + 'port_list', 'is_extension_supported')}) def test_router_removeroute(self): if self.DASHBOARD == 'admin': @@ -925,51 +1129,55 @@ class RouterRouteTests(RouterMixin, test.TestCase): pre_router = self.routers_with_routes.first() post_router = copy.deepcopy(pre_router) route = post_router['routes'].pop() - api.neutron.is_extension_supported(IsA(http.HttpRequest), 'extraroute')\ - .MultipleTimes().AndReturn(True) - api.neutron.router_get(IsA(http.HttpRequest), - pre_router.id).AndReturn(pre_router) - params = {} - params['routes'] = post_router['routes'] - api.neutron.router_get(IsA(http.HttpRequest), - pre_router.id).AndReturn(pre_router) - router_update = api.neutron.router_update(IsA(http.HttpRequest), - pre_router.id, **params) - router_update.AndReturn({'router': post_router}) - api.neutron.port_list(IsA(http.HttpRequest), - device_id=pre_router.id)\ - .AndReturn([self.ports.first()]) + self.mock_is_extension_supported.return_value = True + self.mock_router_get.return_value = pre_router + self.mock_router_update.return_value = {'router': post_router} + self.mock_port_list.return_value = [self.ports.first()] self._mock_external_network_get(pre_router) - self.mox.ReplayAll() + form_route_id = route['nexthop'] + ":" + route['destination'] form_data = {'action': 'extra_routes__delete__%s' % form_route_id} url = reverse(self.DETAIL_PATH, args=[pre_router.id]) res = self.client.post(url, form_data) self.assertNoFormErrors(res) + self._check_mock_external_network_get(pre_router) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_is_extension_supported, 2, + mock.call(test.IsHttpRequest(), 'extraroute')) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_router_get, 2, + mock.call(test.IsHttpRequest(), pre_router.id)) + self.mock_router_update.assert_called_once_with( + test.IsHttpRequest(), pre_router.id, + routes=post_router['routes']) + self.mock_port_list.assert_called_once_with( + test.IsHttpRequest(), device_id=pre_router.id) + + +class RouterRouteTests(RouterMixin, RouterRouteTestCase, test.TestCase): + DASHBOARD = 'project' + INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD) + DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD + class RouterViewTests(RouterMixin, test.TestCase): DASHBOARD = 'project' INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD) - @test.create_stubs({api.neutron: ('router_list', 'network_list', + use_mox = False + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', 'is_extension_supported'), quotas: ('tenant_quota_usages',)}) def test_create_button_disabled_when_quota_exceeded(self): quota_data = self.neutron_quota_usages.first() quota_data['router']['available'] = 0 - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - quotas.tenant_quota_usages( - IsA(http.HttpRequest), targets=('router', )) \ - .MultipleTimes().AndReturn(quota_data) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) - + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_quota_usages.return_value = quota_data + self.mock_is_extension_supported.return_value = True self._mock_external_network_list() - self.mox.ReplayAll() res = self.client.get(self.INDEX_URL) self.assertTemplateUsed(res, INDEX_TEMPLATE) @@ -983,24 +1191,26 @@ class RouterViewTests(RouterMixin, test.TestCase): self.assertEqual('Create Router (Quota exceeded)', create_action.verbose_name) - @test.create_stubs({api.neutron: ('router_list', 'network_list', + self.mock_router_list.assert_called_once_with( + test.IsHttpRequest(), tenant_id=self.tenant.id) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_quota_usages, 3, + mock.call(test.IsHttpRequest(), targets=('router', ))) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self._check_mock_external_network_list() + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', 'is_extension_supported'), quotas: ('tenant_quota_usages',)}) def test_create_button_shown_when_quota_disabled(self): quota_data = self.neutron_quota_usages.first() quota_data['router'].pop('available') - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - quotas.tenant_quota_usages( - IsA(http.HttpRequest), targets=('router', )) \ - .MultipleTimes().AndReturn(quota_data) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) - + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_quota_usages.return_value = quota_data + self.mock_is_extension_supported.return_value = True self._mock_external_network_list() - self.mox.ReplayAll() res = self.client.get(self.INDEX_URL) self.assertTemplateUsed(res, INDEX_TEMPLATE) @@ -1014,24 +1224,26 @@ class RouterViewTests(RouterMixin, test.TestCase): self.assertEqual('Create Router', create_action.verbose_name) - @test.create_stubs({api.neutron: ('router_list', 'network_list', + self.mock_router_list.assert_called_once_with( + test.IsHttpRequest(), tenant_id=self.tenant.id) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_quota_usages, 3, + mock.call(test.IsHttpRequest(), targets=('router', ))) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self._check_mock_external_network_list() + + @test.create_mocks({api.neutron: ('router_list', + 'network_list', 'is_extension_supported'), quotas: ('tenant_quota_usages',)}) def test_create_button_attributes(self): quota_data = self.neutron_quota_usages.first() quota_data['router']['available'] = 10 - api.neutron.router_list( - IsA(http.HttpRequest), - tenant_id=self.tenant.id).AndReturn(self.routers.list()) - quotas.tenant_quota_usages( - IsA(http.HttpRequest), targets=('router', )) \ - .MultipleTimes().AndReturn(quota_data) - api.neutron.is_extension_supported(IsA(http.HttpRequest), - "router_availability_zone")\ - .AndReturn(True) - + self.mock_router_list.return_value = self.routers.list() + self.mock_tenant_quota_usages.return_value = quota_data + self.mock_is_extension_supported.return_value = True self._mock_external_network_list() - self.mox.ReplayAll() res = self.client.get(self.INDEX_URL) self.assertTemplateUsed(res, INDEX_TEMPLATE) @@ -1046,3 +1258,12 @@ class RouterViewTests(RouterMixin, test.TestCase): self.assertEqual('horizon:project:routers:create', create_action.url) self.assertEqual((('network', 'create_router'),), create_action.policy_rules) + + self.mock_router_list.assert_called_once_with( + test.IsHttpRequest(), tenant_id=self.tenant.id) + self.assert_mock_multiple_calls_with_same_arguments( + self.mock_tenant_quota_usages, 3, + mock.call(test.IsHttpRequest(), targets=('router', ))) + self.mock_is_extension_supported.assert_called_once_with( + test.IsHttpRequest(), 'router_availability_zone') + self._check_mock_external_network_list()