From ea914a22e2cc447d5916e187f4aba110237dcd60 Mon Sep 17 00:00:00 2001 From: Rajat Dhasmana Date: Thu, 27 Jun 2024 00:51:29 +0530 Subject: [PATCH] Test image <-> volume <-> server dependency This patch adds a test where we test the following workflow: 1. Create image 2. Create a bootable volume from Image 3. Launch an instance from the bootable volume 4. Take snapshot of the instance -- which creates the volume snapshot 5. Delete the image In the above workflow, steps 2 and 3 are performed together as we create the instance as volume backed providing the image ID to instance create call. Change-Id: Ie9c27e7e7305147b7081c5f1dcc8f1631081fda5 --- .../api/image/v2/test_images_dependency.py | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/tempest/api/image/v2/test_images_dependency.py b/tempest/api/image/v2/test_images_dependency.py index 326045bdda..41611bb255 100644 --- a/tempest/api/image/v2/test_images_dependency.py +++ b/tempest/api/image/v2/test_images_dependency.py @@ -56,9 +56,10 @@ class ImageDependencyTests(image_base.BaseV2ImageTest, "not enabled" % (cls.__name__)) raise cls.skipException(skip_msg) - def _create_instance_snapshot(self): + def _create_instance_snapshot(self, bfv=False): """Create instance from image and then snapshot the instance.""" # Create image and store data to image + source = 'volume' if bfv else 'image' image_name = data_utils.rand_name( prefix=CONF.resource_name_prefix, name='image-dependency-test') @@ -71,12 +72,20 @@ class ImageDependencyTests(image_base.BaseV2ImageTest, self.client.store_image_file(image['id'], image_file) waiters.wait_for_image_status( self.client, image['id'], 'active') - # Create instance - instance = self.create_test_server( - name='instance-depend-image', - image_id=image['id'], - wait_until='ACTIVE') - LOG.info("Instance from image is created %s", instance) + if bfv: + # Create instance + instance = self.create_test_server( + name='instance-depend-image', + image_id=image['id'], + volume_backed=True, + wait_until='ACTIVE') + else: + # Create instance + instance = self.create_test_server( + name='instance-depend-image', + image_id=image['id'], + wait_until='ACTIVE') + LOG.info("Instance from %s is created %s", source, instance) instance_observed = \ self.servers_client.show_server(instance['id'])['server'] # Create instance snapshot @@ -101,3 +110,26 @@ class ImageDependencyTests(image_base.BaseV2ImageTest, fetched_images_id = [img['id'] for img in images_list] self.assertNotIn(base_image_id, fetched_images_id) self.assertIn(snapshot_image_id, fetched_images_id) + + @utils.services('compute', 'volume') + @decorators.idempotent_id('f0c8a35d-8f8f-443c-8bcb-85a9c0f87d19') + def test_image_volume_server_snapshot_dependency(self): + """Test with image > volume > instance > snapshot dependency. + + We are going to perform the following steps in the test: + * Create image + * Create a bootable volume from Image + * Launch an instance from the bootable volume + * Take snapshot of the instance -- which creates the volume snapshot + * Delete the image. + + This will test the dependency chain of image -> volume -> snapshot. + """ + base_image_id, snapshot_image_id = self._create_instance_snapshot( + bfv=True) + self.client.delete_image(base_image_id) + self.client.wait_for_resource_deletion(base_image_id) + images_list = self.client.list_images()['images'] + fetched_images_id = [img['id'] for img in images_list] + self.assertNotIn(base_image_id, fetched_images_id) + self.assertIn(snapshot_image_id, fetched_images_id)