From 69b73d89781cd6ba6a58a2b364fa7790cb9d9da3 Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Thu, 19 Jul 2018 20:40:11 +0100 Subject: [PATCH] [placement] ensure_rc_cache only at start of process Call ensure_rc_cache from deploy, so that we only try it once per process. A small number of unit tests needed an adjustment to either mock properly or call the ensure_rc_cache in advance of their work. Change-Id: I7499bba6ac6b463d8da46e10469121e62ee52ed1 --- nova/api/openstack/placement/deploy.py | 1 + .../placement/objects/resource_provider.py | 20 +------------------ .../objects/test_resource_provider.py | 6 ++++-- nova/tests/unit/cmd/test_status.py | 1 + 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/nova/api/openstack/placement/deploy.py b/nova/api/openstack/placement/deploy.py index 281a8d76d316..28dde5c164b6 100644 --- a/nova/api/openstack/placement/deploy.py +++ b/nova/api/openstack/placement/deploy.py @@ -90,6 +90,7 @@ def update_database(): """ ctx = db_api.DbContext() resource_provider.ensure_trait_sync(ctx) + resource_provider.ensure_rc_cache(ctx) # NOTE(cdent): Althought project_name is no longer used because of the diff --git a/nova/api/openstack/placement/objects/resource_provider.py b/nova/api/openstack/placement/objects/resource_provider.py index ceac35b6057f..a0d101bc7147 100644 --- a/nova/api/openstack/placement/objects/resource_provider.py +++ b/nova/api/openstack/placement/objects/resource_provider.py @@ -68,7 +68,7 @@ LOG = logging.getLogger(__name__) @db_api.placement_context_manager.reader -def _ensure_rc_cache(ctx): +def ensure_rc_cache(ctx): """Ensures that a singleton resource class cache has been created in the module's scope. @@ -289,7 +289,6 @@ def _add_inventory(context, rp, inventory): :raises `exception.ResourceClassNotFound` if inventory.resource_class cannot be found in either the standard classes or the DB. """ - _ensure_rc_cache(context) rc_id = _RC_CACHE.id_from_string(inventory.resource_class) inv_list = InventoryList(objects=[inventory]) _add_inventory_to_provider( @@ -304,7 +303,6 @@ def _update_inventory(context, rp, inventory): :raises `exception.ResourceClassNotFound` if inventory.resource_class cannot be found in either the standard classes or the DB. """ - _ensure_rc_cache(context) rc_id = _RC_CACHE.id_from_string(inventory.resource_class) inv_list = InventoryList(objects=[inventory]) exceeded = _update_inventory_for_provider( @@ -320,7 +318,6 @@ def _delete_inventory(context, rp, resource_class): :raises `exception.ResourceClassNotFound` if resource_class cannot be found in either the standard classes or the DB. """ - _ensure_rc_cache(context) rc_id = _RC_CACHE.id_from_string(resource_class) if not _delete_inventory_from_provider(context, rp, [rc_id]): raise exception.NotFound( @@ -350,8 +347,6 @@ def _set_inventory(context, rp, inv_list): :raises `exception.InventoryInUse` if we attempt to delete inventory from a provider that has allocations for that resource class. """ - _ensure_rc_cache(context) - existing_resources = _get_current_inventory_resources(context, rp) these_resources = set([_RC_CACHE.id_from_string(r.resource_class) for r in inv_list.objects]) @@ -1487,7 +1482,6 @@ class ResourceProviderList(base.ObjectListBase, base.VersionedObject): classes. :type filters: dict """ - _ensure_rc_cache(context) resource_providers = cls._get_all_by_filters_from_db(context, filters) return base.obj_make_list(context, cls(context), ResourceProvider, resource_providers) @@ -1559,7 +1553,6 @@ class InventoryList(base.ObjectListBase, base.VersionedObject): @classmethod def get_all_by_resource_provider(cls, context, rp): - _ensure_rc_cache(context) db_inv = _get_inventory_by_provider_id(context, rp.id) # Build up a list of Inventory objects, setting the Inventory object # fields to the same-named database record field we got from @@ -1955,8 +1948,6 @@ class AllocationList(base.ObjectListBase, base.VersionedObject): :raises `ConcurrentUpdateDetected` if a generation for a resource provider or consumer failed its increment check. """ - _ensure_rc_cache(context) - # First delete any existing allocations for any consumers. This # provides a clean slate for the consumers mentioned in the list of # allocations being manipulated. @@ -2028,7 +2019,6 @@ class AllocationList(base.ObjectListBase, base.VersionedObject): @classmethod def get_all_by_resource_provider(cls, context, rp): - _ensure_rc_cache(context) _create_incomplete_consumers_for_provider(context, rp.id) db_allocs = _get_allocations_by_provider_id(context, rp.id) # Build up a list of Allocation objects, setting the Allocation object @@ -2060,7 +2050,6 @@ class AllocationList(base.ObjectListBase, base.VersionedObject): @classmethod def get_all_by_consumer_id(cls, context, consumer_id): - _ensure_rc_cache(context) _create_incomplete_consumer(context, consumer_id) db_allocs = _get_allocations_by_consumer_uuid(context, consumer_id) @@ -2232,13 +2221,11 @@ class UsageList(base.ObjectListBase, base.VersionedObject): @classmethod def get_all_by_resource_provider_uuid(cls, context, rp_uuid): - _ensure_rc_cache(context) usage_list = cls._get_all_by_resource_provider_uuid(context, rp_uuid) return base.obj_make_list(context, cls(context), Usage, usage_list) @classmethod def get_all_by_project_user(cls, context, project_id, user_id=None): - _ensure_rc_cache(context) usage_list = cls._get_all_by_project_user(context, project_id, user_id=user_id) return base.obj_make_list(context, cls(context), Usage, usage_list) @@ -2284,7 +2271,6 @@ class ResourceClass(base.VersionedObject, base.TimestampedObject): :raises: ResourceClassNotFound if no such resource class was found """ - _ensure_rc_cache(context) rc = _RC_CACHE.all_from_string(name) obj = cls(context, id=rc['id'], name=rc['name'], updated_at=rc['updated_at'], created_at=rc['created_at']) @@ -2366,7 +2352,6 @@ class ResourceClass(base.VersionedObject, base.TimestampedObject): reason='ID attribute not found') # Never delete any standard resource class, since the standard resource # classes don't even exist in the database table anyway. - _ensure_rc_cache(self._context) if self.id in (rc['id'] for rc in _RC_CACHE.STANDARDS): raise exception.ResourceClassCannotDeleteStandard( resource_class=self.name) @@ -2396,7 +2381,6 @@ class ResourceClass(base.VersionedObject, base.TimestampedObject): updates = self.obj_get_changes() # Never update any standard resource class, since the standard resource # classes don't even exist in the database table anyway. - _ensure_rc_cache(self._context) if self.id in (rc['id'] for rc in _RC_CACHE.STANDARDS): raise exception.ResourceClassCannotUpdateStandard( resource_class=self.name) @@ -2425,7 +2409,6 @@ class ResourceClassList(base.ObjectListBase, base.VersionedObject): @staticmethod @db_api.placement_context_manager.reader def _get_all(context): - _ensure_rc_cache(context) customs = list(context.session.query(models.ResourceClass).all()) return _RC_CACHE.STANDARDS + customs @@ -3937,7 +3920,6 @@ class AllocationCandidates(base.VersionedObject): and provider_summaries satisfying `requests`, limited according to `limit`. """ - _ensure_rc_cache(context) alloc_reqs, provider_summaries = cls._get_by_requests( context, requests, limit=limit, group_policy=group_policy) return cls( diff --git a/nova/tests/unit/api/openstack/placement/objects/test_resource_provider.py b/nova/tests/unit/api/openstack/placement/objects/test_resource_provider.py index f16ac7c4651a..28fa449f4d92 100644 --- a/nova/tests/unit/api/openstack/placement/objects/test_resource_provider.py +++ b/nova/tests/unit/api/openstack/placement/objects/test_resource_provider.py @@ -161,10 +161,11 @@ class TestProviderSummaryNoDB(_TestCase): class TestInventoryNoDB(_TestCase): @mock.patch('nova.api.openstack.placement.objects.resource_provider.' - '_ensure_rc_cache', side_effect=_fake_ensure_cache) + 'ensure_rc_cache', side_effect=_fake_ensure_cache) @mock.patch('nova.api.openstack.placement.objects.resource_provider.' '_get_inventory_by_provider_id') def test_get_all_by_resource_provider(self, mock_get, mock_ensure_cache): + mock_ensure_cache(self.context) expected = [dict(_INVENTORY_DB, resource_provider_id=_RESOURCE_PROVIDER_ID), dict(_INVENTORY_DB, @@ -266,13 +267,14 @@ class TestAllocationListNoDB(_TestCase): @mock.patch('nova.api.openstack.placement.objects.resource_provider.' '_create_incomplete_consumers_for_provider') @mock.patch('nova.api.openstack.placement.objects.resource_provider.' - '_ensure_rc_cache', + 'ensure_rc_cache', side_effect=_fake_ensure_cache) @mock.patch('nova.api.openstack.placement.objects.resource_provider.' '_get_allocations_by_provider_id', return_value=[_ALLOCATION_DB]) def test_get_allocations(self, mock_get_allocations_from_db, mock_ensure_cache, mock_create_consumers): + mock_ensure_cache(self.context) rp = resource_provider.ResourceProvider(id=_RESOURCE_PROVIDER_ID, uuid=uuids.resource_provider) rp_alloc_list = resource_provider.AllocationList diff --git a/nova/tests/unit/cmd/test_status.py b/nova/tests/unit/cmd/test_status.py index 965a19bfc0e8..cfd04293872f 100644 --- a/nova/tests/unit/cmd/test_status.py +++ b/nova/tests/unit/cmd/test_status.py @@ -486,6 +486,7 @@ class TestUpgradeCheckResourceProviders(test.NoDBTestCase): self.useFixture(nova_fixtures.Database(database='api')) self.useFixture(nova_fixtures.Database(database='placement')) self.cmd = status.UpgradeCommands() + rp_obj.ensure_rc_cache(context.get_admin_context()) def test_check_resource_providers_fresh_install_no_mappings(self): """Tests the scenario where we don't have any cell mappings (no cells