From f1addff61ba10cac7e2b5b0fc12da8568099864d Mon Sep 17 00:00:00 2001 From: Jason Paroly Date: Wed, 18 Feb 2026 10:03:07 -0500 Subject: [PATCH] Use project_reader in compute volumes tests Add reader client setup for volumes_extensions_client and snapshots_extensions_client to BaseV2ComputeTest.setup_clients() in tempest/api/compute/base.py. Update test files to use reader clients for read operations. Change-Id: I24feaaced466e7539895b45ff35ebc10229acc73 Signed-off-by: Jason Paroly Co-Authored-By: Claude Sonnet 4.5 --- tempest/api/compute/base.py | 10 +++++++++ .../api/compute/volumes/test_attach_volume.py | 13 ++++++++++-- .../compute/volumes/test_volume_snapshots.py | 5 +++-- .../api/compute/volumes/test_volumes_get.py | 3 ++- .../api/compute/volumes/test_volumes_list.py | 21 ++++++++++--------- .../compute/volumes/test_volumes_negative.py | 5 +++-- 6 files changed, 40 insertions(+), 17 deletions(-) diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py index 3b44ded1b2..635685fc48 100644 --- a/tempest/api/compute/base.py +++ b/tempest/api/compute/base.py @@ -99,6 +99,16 @@ class BaseV2ComputeTest(api_version_utils.BaseMicroversionTest, cls.os_primary.volumes_extensions_client cls.snapshots_extensions_client =\ cls.os_primary.snapshots_extensions_client + if CONF.enforce_scope.nova and hasattr(cls, 'os_project_reader'): + cls.reader_volumes_extensions_client = ( + cls.os_project_reader.volumes_extensions_client) + cls.reader_snapshots_extensions_client = ( + cls.os_project_reader.snapshots_extensions_client) + else: + cls.reader_volumes_extensions_client = ( + cls.volumes_extensions_client) + cls.reader_snapshots_extensions_client = ( + cls.snapshots_extensions_client) cls.interfaces_client = cls.os_primary.interfaces_client cls.availability_zone_client = cls.os_primary.availability_zone_client cls.agents_client = cls.os_primary.agents_client diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py index e267b0f166..72df5e34e3 100644 --- a/tempest/api/compute/volumes/test_attach_volume.py +++ b/tempest/api/compute/volumes/test_attach_volume.py @@ -42,6 +42,15 @@ class BaseAttachVolumeTest(base.BaseV2ComputeTest): cls.prepare_instance_network() super(BaseAttachVolumeTest, cls).setup_credentials() + @classmethod + def setup_clients(cls): + super(BaseAttachVolumeTest, cls).setup_clients() + if CONF.enforce_scope.nova and hasattr(cls, 'os_project_reader'): + cls.reader_volumes_client = ( + cls.os_project_reader.volumes_client_latest) + else: + cls.reader_volumes_client = cls.volumes_client + def _create_server(self): # Start a server and wait for it to become ready validation_resources = self.get_test_validation_resources( @@ -356,7 +365,7 @@ class AttachVolumeMultiAttachTest(BaseAttachVolumeTest): more attachments or 'available' state if there are no more attachments. """ # Count the number of attachments before starting the detach. - volume = self.volumes_client.show_volume(volume_id)['volume'] + volume = self.reader_volumes_client.show_volume(volume_id)['volume'] attachments = volume['attachments'] wait_status = 'in-use' if len(attachments) > 1 else 'available' # Now detach the volume from the given server. @@ -418,7 +427,7 @@ class AttachVolumeMultiAttachTest(BaseAttachVolumeTest): # List attachments from the volume and make sure the server uuids # are in that list. - vol_attachments = self.volumes_client.show_volume( + vol_attachments = self.reader_volumes_client.show_volume( volume['id'])['volume']['attachments'] attached_server_ids = [attachment['server_id'] for attachment in vol_attachments] diff --git a/tempest/api/compute/volumes/test_volume_snapshots.py b/tempest/api/compute/volumes/test_volume_snapshots.py index 5b06a865ed..698504ba72 100644 --- a/tempest/api/compute/volumes/test_volume_snapshots.py +++ b/tempest/api/compute/volumes/test_volume_snapshots.py @@ -46,6 +46,7 @@ class VolumesSnapshotsTestJSON(base.BaseV2ComputeTest): super(VolumesSnapshotsTestJSON, cls).setup_clients() cls.volumes_client = cls.volumes_extensions_client cls.snapshots_client = cls.snapshots_extensions_client + cls.reader_snapshots_client = cls.reader_snapshots_extensions_client @decorators.idempotent_id('cd4ec87d-7825-450d-8040-6e2068f2da8f') def test_volume_snapshot_create_get_list_delete(self): @@ -72,10 +73,10 @@ class VolumesSnapshotsTestJSON(base.BaseV2ComputeTest): self.addCleanup(delete_snapshot, snapshot['id']) self.assertEqual(volume['id'], snapshot['volumeId']) # Get snapshot - fetched_snapshot = self.snapshots_client.show_snapshot( + fetched_snapshot = self.reader_snapshots_client.show_snapshot( snapshot['id'])['snapshot'] self.assertEqual(s_name, fetched_snapshot['displayName']) self.assertEqual(volume['id'], fetched_snapshot['volumeId']) # Fetch all snapshots - snapshots = self.snapshots_client.list_snapshots()['snapshots'] + snapshots = self.reader_snapshots_client.list_snapshots()['snapshots'] self.assertIn(snapshot['id'], map(lambda x: x['id'], snapshots)) diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py index 2a4189e75f..8e5838b218 100644 --- a/tempest/api/compute/volumes/test_volumes_get.py +++ b/tempest/api/compute/volumes/test_volumes_get.py @@ -43,6 +43,7 @@ class VolumesGetTestJSON(base.BaseV2ComputeTest): def setup_clients(cls): super(VolumesGetTestJSON, cls).setup_clients() cls.volumes_client = cls.volumes_extensions_client + cls.reader_volumes_client = cls.reader_volumes_extensions_client @decorators.idempotent_id('f10f25eb-9775-4d9d-9cbe-1cf54dae9d5f') def test_volume_create_get_delete(self): @@ -59,7 +60,7 @@ class VolumesGetTestJSON(base.BaseV2ComputeTest): "The created volume name is not equal " "to the requested name") # GET Volume - fetched_volume = self.volumes_client.show_volume( + fetched_volume = self.reader_volumes_client.show_volume( volume['id'])['volume'] # Verification of details of fetched Volume self.assertEqual(v_name, diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py index 0b372645d7..142555a66d 100644 --- a/tempest/api/compute/volumes/test_volumes_list.py +++ b/tempest/api/compute/volumes/test_volumes_list.py @@ -45,6 +45,7 @@ class VolumesTestJSON(base.BaseV2ComputeTest): def setup_clients(cls): super(VolumesTestJSON, cls).setup_clients() cls.client = cls.volumes_extensions_client + cls.reader_client = cls.reader_volumes_extensions_client @classmethod def resource_setup(cls): @@ -61,7 +62,7 @@ class VolumesTestJSON(base.BaseV2ComputeTest): def test_volume_list(self): """Test listing volumes should return all volumes""" # Fetch all Volumes - fetched_list = self.client.list_volumes()['volumes'] + fetched_list = self.reader_client.list_volumes()['volumes'] # Now check if all the Volumes created in setup are in fetched list missing_volumes = [ v for v in self.volume_list if v not in fetched_list @@ -76,7 +77,7 @@ class VolumesTestJSON(base.BaseV2ComputeTest): def test_volume_list_with_details(self): """Test listing volumes with detail should return all volumes""" # Fetch all Volumes - fetched_list = self.client.list_volumes(detail=True)['volumes'] + fetched_list = self.reader_client.list_volumes(detail=True)['volumes'] # Now check if all the Volumes created in setup are in fetched list missing_volumes = [ v for v in self.volume_list if v not in fetched_list @@ -95,7 +96,7 @@ class VolumesTestJSON(base.BaseV2ComputeTest): returned. """ params = {'limit': 2} - fetched_vol_list = self.client.list_volumes(**params)['volumes'] + fetched_vol_list = self.reader_client.list_volumes(**params)['volumes'] self.assertEqual(len(fetched_vol_list), params['limit'], "Failed to list volumes by limit set") @@ -108,8 +109,8 @@ class VolumesTestJSON(base.BaseV2ComputeTest): detail should be returned. """ params = {'limit': 2} - fetched_vol_list = self.client.list_volumes(detail=True, - **params)['volumes'] + fetched_vol_list = self.reader_client.list_volumes(detail=True, + **params)['volumes'] self.assertEqual(len(fetched_vol_list), params['limit'], "Failed to list volume details by limit set") @@ -123,9 +124,9 @@ class VolumesTestJSON(base.BaseV2ComputeTest): (The items in the all volumes list start from position 0.) """ # get all volumes list - all_vol_list = self.client.list_volumes()['volumes'] + all_vol_list = self.reader_client.list_volumes()['volumes'] params = {'offset': 1, 'limit': 1} - fetched_vol_list = self.client.list_volumes(**params)['volumes'] + fetched_vol_list = self.reader_client.list_volumes(**params)['volumes'] # Validating length of the fetched volumes self.assertEqual(len(fetched_vol_list), params['limit'], @@ -146,10 +147,10 @@ class VolumesTestJSON(base.BaseV2ComputeTest): (The items in the all volumes list start from position 0.) """ # get all volumes list - all_vol_list = self.client.list_volumes(detail=True)['volumes'] + all_vol_list = self.reader_client.list_volumes(detail=True)['volumes'] params = {'offset': 1, 'limit': 1} - fetched_vol_list = self.client.list_volumes(detail=True, - **params)['volumes'] + fetched_vol_list = self.reader_client.list_volumes(detail=True, + **params)['volumes'] # Validating length of the fetched volumes self.assertEqual(len(fetched_vol_list), params['limit'], diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py index c38649791c..bfd29ab413 100644 --- a/tempest/api/compute/volumes/test_volumes_negative.py +++ b/tempest/api/compute/volumes/test_volumes_negative.py @@ -41,6 +41,7 @@ class VolumesNegativeTest(base.BaseV2ComputeTest): def setup_clients(cls): super(VolumesNegativeTest, cls).setup_clients() cls.client = cls.volumes_extensions_client + cls.reader_client = cls.reader_volumes_extensions_client @decorators.attr(type=['negative']) @decorators.idempotent_id('c03ea686-905b-41a2-8748-9635154b7c57') @@ -48,7 +49,7 @@ class VolumesNegativeTest(base.BaseV2ComputeTest): """Test getting details of a non existent volume should fail""" # Creating a nonexistent volume id # Trying to GET a non existent volume - self.assertRaises(lib_exc.NotFound, self.client.show_volume, + self.assertRaises(lib_exc.NotFound, self.reader_client.show_volume, data_utils.rand_uuid()) @decorators.attr(type=['negative']) @@ -97,7 +98,7 @@ class VolumesNegativeTest(base.BaseV2ComputeTest): @decorators.idempotent_id('62bab09a-4c03-4617-8cca-8572bc94af9b') def test_get_volume_without_passing_volume_id(self): """Test getting volume details without volume id should fail""" - self.assertRaises(lib_exc.NotFound, self.client.show_volume, '') + self.assertRaises(lib_exc.NotFound, self.reader_client.show_volume, '') @decorators.attr(type=['negative']) @decorators.idempotent_id('62972737-124b-4513-b6cf-2f019f178494')