From 370bea472b5324a3ce827bb514bca20e239e2f00 Mon Sep 17 00:00:00 2001 From: melanie witt Date: Tue, 22 Aug 2023 01:43:31 +0000 Subject: [PATCH] Make scenario snapshot tests work with ephemeral|swap Currently, the create_server_snapshot and test_image_defined_boot_from_volume methods assume that the server being snapshotted will have only one block device mapping. However, if the server has an ephemeral disk and/or a swap disk, it will have multiple block device mappings. This can cause erroneous scenario test failures if the first block device mapping in the image service response is not the root disk. This adjusts create_server_snapshot and test_image_defined_boot_from_volume to check for a non-null snapshot_id before using it. Change-Id: I2417d5a91ae5fbb2101b64a07b6b8c74199e8fb5 --- tempest/scenario/manager.py | 40 +++++++++++++------- tempest/scenario/test_volume_boot_pattern.py | 4 +- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py index 7c986cc7e4..a809342331 100644 --- a/tempest/scenario/manager.py +++ b/tempest/scenario/manager.py @@ -898,6 +898,19 @@ class ScenarioTest(tempest.test.BaseTestCase): if not isinstance(exc, lib_exc.SSHTimeout): LOG.debug('Network information on a devstack host') + def get_snapshot_id(self, bdms): + if isinstance(bdms, str): + bdms = json.loads(bdms) + snapshot_id = None + for bdm in bdms: + # Look for the block device mapping that actually has a + # snapshot. If the server has ephemeral or swap disk, their + # block device mappings will be present with snapshot_id = None + if 'snapshot_id' in bdm and bdm['snapshot_id'] is not None: + snapshot_id = bdm['snapshot_id'] + break + return snapshot_id + def create_server_snapshot(self, server, name=None, **kwargs): """Creates server snapshot""" # Glance client @@ -924,20 +937,19 @@ class ScenarioTest(tempest.test.BaseTestCase): snapshot_image = _image_client.show_image(image_id) image_props = snapshot_image - bdm = image_props.get('block_device_mapping') - if bdm: - bdm = json.loads(bdm) - if bdm and 'snapshot_id' in bdm[0]: - snapshot_id = bdm[0]['snapshot_id'] - self.addCleanup( - self.snapshots_client.wait_for_resource_deletion, - snapshot_id) - self.addCleanup(test_utils.call_and_ignore_notfound_exc, - self.snapshots_client.delete_snapshot, - snapshot_id) - waiters.wait_for_volume_resource_status(self.snapshots_client, - snapshot_id, - 'available') + bdms = image_props.get('block_device_mapping') + if bdms: + snapshot_id = self.get_snapshot_id(bdms) + self.assertIsNotNone(snapshot_id) + self.addCleanup( + self.snapshots_client.wait_for_resource_deletion, + snapshot_id) + self.addCleanup(test_utils.call_and_ignore_notfound_exc, + self.snapshots_client.delete_snapshot, + snapshot_id) + waiters.wait_for_volume_resource_status( + self.snapshots_client, snapshot_id, 'available') + image_name = snapshot_image['name'] self.assertEqual(name, image_name) LOG.debug("Created snapshot image %s for server %s", diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py index 5e28ecd319..febc2f63e6 100644 --- a/tempest/scenario/test_volume_boot_pattern.py +++ b/tempest/scenario/test_volume_boot_pattern.py @@ -11,7 +11,6 @@ # under the License. from oslo_log import log as logging -from oslo_serialization import jsonutils as json import testtools from tempest.common import utils @@ -245,8 +244,7 @@ class TestVolumeBootPattern(manager.EncryptionScenarioTest): bdms = image.get('block_device_mapping') if not bdms: bdms = image['properties']['block_device_mapping'] - bdms = json.loads(bdms) - snapshot_id = bdms[0]['snapshot_id'] + snapshot_id = self.get_snapshot_id(bdms) self._delete_snapshot(snapshot_id) # Now, delete the first server which will also delete the first