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):