Add test to create multiple volume from resource
This patch adds tests for creating multiple volumes from resources
like snapshot, source volume, backup etc.
It also moves creating multiple volumes from image test to the same
file as other resource tests.
Change-Id: Iddc4c40854a5a301ccfbdcf93e03886cc4ee9709
diff --git a/cinder_tempest_plugin/api/volume/base.py b/cinder_tempest_plugin/api/volume/base.py
index 40bfb33..f948a93 100644
--- a/cinder_tempest_plugin/api/volume/base.py
+++ b/cinder_tempest_plugin/api/volume/base.py
@@ -72,7 +72,7 @@
def create_volume(cls, wait_until='available', **kwargs):
"""Wrapper utility that returns a test volume.
- :param wait_until: wait till volume status.
+ :param wait_until: wait till volume status, None means no wait.
"""
if 'size' not in kwargs:
kwargs['size'] = CONF.volume.volume_size
@@ -93,8 +93,9 @@
cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
cls.volumes_client.delete_volume,
volume['id'])
- waiters.wait_for_volume_resource_status(cls.volumes_client,
- volume['id'], wait_until)
+ if wait_until:
+ waiters.wait_for_volume_resource_status(cls.volumes_client,
+ volume['id'], wait_until)
return volume
@classmethod
@@ -199,3 +200,19 @@
cls.admin_volume_types_client.delete_volume_type, type_id)
test_utils.call_and_ignore_notfound_exc(
cls.admin_volume_types_client.wait_for_resource_deletion, type_id)
+
+
+class CreateMultipleResourceTest(BaseVolumeTest):
+
+ def _create_multiple_resource(self, callback, repeat_count=5,
+ **kwargs):
+
+ res = []
+ for _ in range(repeat_count):
+ res.append(callback(**kwargs)['id'])
+ return res
+
+ def _wait_for_multiple_resources(self, callback, wait_list, **kwargs):
+
+ for r in wait_list:
+ callback(resource_id=r, **kwargs)
diff --git a/cinder_tempest_plugin/api/volume/test_create_from_image.py b/cinder_tempest_plugin/api/volume/test_create_from_image.py
index dc296c0..acb1943 100644
--- a/cinder_tempest_plugin/api/volume/test_create_from_image.py
+++ b/cinder_tempest_plugin/api/volume/test_create_from_image.py
@@ -23,64 +23,6 @@
CONF = config.CONF
-class VolumeFromImageTest(base.BaseVolumeTest):
-
- @classmethod
- def skip_checks(cls):
- super(VolumeFromImageTest, cls).skip_checks()
- if not CONF.service_available.glance:
- raise cls.skipException("Glance service is disabled")
-
- @classmethod
- def create_volume_no_wait(cls, **kwargs):
- """Returns a test volume.
-
- This does not wait for volume creation to finish,
- so that multiple operations can happen on the
- Cinder server in parallel.
- """
- if 'size' not in kwargs:
- kwargs['size'] = CONF.volume.volume_size
-
- if 'imageRef' in kwargs:
- image = cls.os_primary.image_client_v2.show_image(
- kwargs['imageRef'])
- min_disk = image['min_disk']
- kwargs['size'] = max(kwargs['size'], min_disk)
-
- if 'name' not in kwargs:
- name = data_utils.rand_name(cls.__name__ + '-Volume')
- kwargs['name'] = name
-
- volume = cls.volumes_client.create_volume(**kwargs)['volume']
- cls.addClassResourceCleanup(
- cls.volumes_client.wait_for_resource_deletion, volume['id'])
- cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
- cls.volumes_client.delete_volume,
- volume['id'])
-
- return volume
-
- @decorators.idempotent_id('8976a11b-1ddc-49b6-b66f-8c26adf3fa9e')
- def test_create_from_image_multiple(self):
- """Create a handful of volumes from the same image at once.
-
- The purpose of this test is to stress volume drivers,
- image download, the image cache, etc., within Cinder.
- """
-
- img_uuid = CONF.compute.image_ref
-
- vols = []
- for v in range(0, 5):
- vols.append(self.create_volume_no_wait(imageRef=img_uuid))
-
- for v in vols:
- waiters.wait_for_volume_resource_status(self.volumes_client,
- v['id'],
- 'available')
-
-
class VolumeAndVolumeTypeFromImageTest(base.BaseVolumeAdminTest):
# needs AdminTest as superclass to manipulate volume_types
diff --git a/cinder_tempest_plugin/api/volume/test_multiple_volume_from_resource.py b/cinder_tempest_plugin/api/volume/test_multiple_volume_from_resource.py
new file mode 100644
index 0000000..10a79f0
--- /dev/null
+++ b/cinder_tempest_plugin/api/volume/test_multiple_volume_from_resource.py
@@ -0,0 +1,105 @@
+# Copyright 2022 Red Hat, Inc.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.common import waiters
+from tempest import config
+from tempest.lib import decorators
+
+from cinder_tempest_plugin.api.volume import base
+
+CONF = config.CONF
+
+
+class CreateVolumesFromSnapshotTest(base.CreateMultipleResourceTest):
+
+ @decorators.idempotent_id('3b879ad1-d861-4ad3-b2c8-c89162e867c3')
+ def test_create_multiple_volume_from_snapshot(self):
+ """Create multiple volumes from a snapshot."""
+
+ volume = self.create_volume()
+ snapshot = self.create_snapshot(volume_id=volume['id'])
+ kwargs_create = {"'snapshot_id": snapshot['id'], "wait_until": None}
+ res = self._create_multiple_resource(self.create_volume,
+ **kwargs_create)
+ kwargs_wait = {"client": self.volumes_client, "status": "available"}
+ self._wait_for_multiple_resources(
+ waiters.wait_for_volume_resource_status, res, **kwargs_wait)
+
+
+class CreateVolumesFromSourceVolumeTest(base.CreateMultipleResourceTest):
+
+ @decorators.idempotent_id('b4a250d1-3ffd-4727-a2f5-9d858b298558')
+ def test_create_multiple_volume_from_source_volume(self):
+ """Create multiple volumes from a source volume.
+
+ The purpose of this test is to check the synchronization
+ of driver clone method with simultaneous requests.
+ """
+
+ volume = self.create_volume()
+ kwargs_create = {"'source_volid": volume['id'], "wait_until": None}
+ res = self._create_multiple_resource(self.create_volume,
+ **kwargs_create)
+ kwargs_wait = {"client": self.volumes_client, "status": "available"}
+ self._wait_for_multiple_resources(
+ waiters.wait_for_volume_resource_status, res, **kwargs_wait)
+
+
+class CreateVolumesFromBackupTest(base.CreateMultipleResourceTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(CreateVolumesFromBackupTest, cls).skip_checks()
+ if not CONF.volume_feature_enabled.backup:
+ raise cls.skipException("Cinder backup feature disabled")
+
+ @decorators.idempotent_id('9db67083-bf1a-486c-8f77-3778467f39a1')
+ def test_create_multiple_volume_from_backup(self):
+ """Create multiple volumes from a backup."""
+
+ volume = self.create_volume()
+ backup = self.create_backup(volume_id=volume['id'])
+ kwargs_create = {"'backup_id": backup['id'], "wait_until": None}
+ res = self._create_multiple_resource(self.create_volume,
+ **kwargs_create)
+ kwargs_wait = {"client": self.volumes_client, "status": "available"}
+ self._wait_for_multiple_resources(
+ waiters.wait_for_volume_resource_status, res, **kwargs_wait)
+
+
+class CreateVolumesFromImageTest(base.CreateMultipleResourceTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(CreateVolumesFromImageTest, cls).skip_checks()
+ if not CONF.service_available.glance:
+ raise cls.skipException("Glance service is disabled")
+
+ @decorators.idempotent_id('8976a11b-1ddc-49b6-b66f-8c26adf3fa9e')
+ def test_create_from_image_multiple(self):
+ """Create a handful of volumes from the same image at once.
+
+ The purpose of this test is to stress volume drivers,
+ image download, the image cache, etc., within Cinder.
+ """
+
+ img_uuid = CONF.compute.image_ref
+
+ kwargs_create = {"'imageRef": img_uuid, "wait_until": None}
+ res = self._create_multiple_resource(self.create_volume,
+ **kwargs_create)
+ kwargs_wait = {"client": self.volumes_client, "status": "available"}
+ self._wait_for_multiple_resources(
+ waiters.wait_for_volume_resource_status, res, **kwargs_wait)