From 3b82dceaa80ede1e5d03f0f44e71b3f09a9d9047 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Braun Date: Tue, 25 Aug 2015 10:29:45 +0200 Subject: [PATCH] Fix lbaas resources cleanup Even if the extension is not available rally tries to list lbaas resources to delete them. This results in a 404 exception. This commit introduces NeutronLbaasV1Mixin that checks first if the extension is available. If it's not it returns an empty list of resources to delete. All lbaas resources (only pools currently) must inherit from this mixin. Change-Id: I94a8457c3026c1859413c867369cae49889f29e1 Closes-Bug: #1470330 --- .../openstack/context/cleanup/resources.py | 16 ++++++- .../context/cleanup/test_resources.py | 47 ++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/rally/plugins/openstack/context/cleanup/resources.py b/rally/plugins/openstack/context/cleanup/resources.py index 83fe458d88..718a2209d8 100644 --- a/rally/plugins/openstack/context/cleanup/resources.py +++ b/rally/plugins/openstack/context/cleanup/resources.py @@ -154,6 +154,12 @@ _neutron_order = get_order(300) class NeutronMixin(SynchronizedDeletion, base.ResourceManager): # Neutron has the best client ever, so we need to override everything + def supports_extension(self, extension): + exts = self._manager().list_extensions().get("extensions", []) + if any(ext.get("alias") == extension for ext in exts): + return True + return False + def _manager(self): client = self._admin_required and self.admin or self.user return getattr(client, self._service)() @@ -173,6 +179,14 @@ class NeutronMixin(SynchronizedDeletion, base.ResourceManager): list_method({"tenant_id": self.tenant_uuid})[resources]) +class NeutronLbaasV1Mixin(NeutronMixin): + + def list(self): + if self.supports_extension("lbaas"): + return super(NeutronLbaasV1Mixin, self).list() + return [] + + @base.resource("neutron", "port", order=next(_neutron_order), tenant_resource=True) class NeutronPort(NeutronMixin): @@ -202,7 +216,7 @@ class NeutronRouter(NeutronMixin): @base.resource("neutron", "pool", order=next(_neutron_order), tenant_resource=True) -class NeutronV1Pool(NeutronMixin): +class NeutronV1Pool(NeutronLbaasV1Mixin): pass diff --git a/tests/unit/plugins/openstack/context/cleanup/test_resources.py b/tests/unit/plugins/openstack/context/cleanup/test_resources.py index 45515fc3be..5abc0f349a 100644 --- a/tests/unit/plugins/openstack/context/cleanup/test_resources.py +++ b/tests/unit/plugins/openstack/context/cleanup/test_resources.py @@ -39,7 +39,8 @@ class AllResourceManagerTestCase(test.TestCase): "_admin_required", "_perform_for_admin_only", "_tenant_resource", "_service", "_resource", "_order", "_max_attempts", "_timeout", "_interval", "_threads", - "_manager", "id", "is_deleted", "delete", "list" + "_manager", "id", "is_deleted", "delete", "list", + "supports_extension" ]) extra_opts = set(fields) - available_opts @@ -229,6 +230,16 @@ class NeutronMixinTestCase(test.TestCase): neut.user = mock.MagicMock() self.assertEqual(neut.user.neutron.return_value, neut._manager()) + @mock.patch("%s.NeutronMixin._manager" % BASE) + def test_supports_extension(self, mock__manager): + mock__manager().list_extensions.return_value = { + "extensions": [{"alias": "foo"}, {"alias": "bar"}] + } + neut = self.get_neutron_mixin() + self.assertTrue(neut.supports_extension("foo")) + self.assertTrue(neut.supports_extension("bar")) + self.assertFalse(neut.supports_extension("foobar")) + def test_id(self): neut = self.get_neutron_mixin() neut.raw_resource = {"id": "test"} @@ -260,6 +271,40 @@ class NeutronMixinTestCase(test.TestCase): {"tenant_id": neut.tenant_uuid}) +class NeutronLbaasV1MixinTestCase(test.TestCase): + + def get_neutron_lbaasv1_mixin(self, extensions=None): + if extensions is None: + extensions = [] + neut = resources.NeutronLbaasV1Mixin() + neut._service = "neutron" + neut._resource = "some_resource" + neut._manager = mock.Mock() + neut._manager().list_extensions.return_value = { + "extensions": [{"alias": ext} for ext in extensions] + } + return neut + + def test_list_lbaas_available(self): + neut = self.get_neutron_lbaasv1_mixin(extensions=["lbaas"]) + neut.tenant_uuid = "user_tenant" + + some_resources = [{"tenant_id": neut.tenant_uuid}, {"tenant_id": "a"}] + neut._manager().list_some_resources.return_value = { + "some_resources": some_resources + } + + self.assertEqual([some_resources[0]], list(neut.list())) + neut._manager().list_some_resources.assert_called_once_with( + {"tenant_id": neut.tenant_uuid}) + + def test_list_lbaas_unavailable(self): + neut = self.get_neutron_lbaasv1_mixin() + + self.assertEqual([], list(neut.list())) + self.assertFalse(neut._manager().list_some_resources.called) + + class NeutronPortTestCase(test.TestCase): def test_delete(self):