Refactor volume groups and group snapshots tests
According to api microversion history of Cinder[1], min microversion for
volume groups (create/delete/update/list/show) is 3.13, min microversion
for group snapshots(create/delete/list/show) and create group from group
or group snapshot is 3.14.
While in GroupsTest in Tempest, the min microversion for volume groups is
set to 3.14. This patch aims to refactor the original GroupsTest to correct
the min microversion for volume groups, and also spilt it into two parts,
one for groups tests and the other for group snapshot tests, which will make
the code more clear and readable.
[1] https://docs.openstack.org/cinder/latest/contributor/api_microversion_history.html
Change-Id: Ic98e8892c4a44850d7a7afac9be1aa59ab38bb8c
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index 7189312..aca1845 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -352,6 +352,10 @@
.. _3.12: https://docs.openstack.org/cinder/latest/contributor/api_microversion_history.html#id12
+ * `3.13`_
+
+ .. _3.13: https://docs.openstack.org/cinder/latest/contributor/api_microversion_history.html#id13
+
* `3.14`_
.. _3.14: https://docs.openstack.org/cinder/latest/contributor/api_microversion_history.html#id14
diff --git a/tempest/api/volume/admin/test_group_snapshots.py b/tempest/api/volume/admin/test_group_snapshots.py
new file mode 100644
index 0000000..36e0035
--- /dev/null
+++ b/tempest/api/volume/admin/test_group_snapshots.py
@@ -0,0 +1,193 @@
+# Copyright 2017 FiberHome Telecommunication Technologies CO.,LTD
+# Copyright (C) 2017 Dell Inc. or its subsidiaries.
+# 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.api.volume import base
+from tempest.common import waiters
+from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
+
+
+class BaseGroupSnapshotsTest(base.BaseVolumeAdminTest):
+
+ def _create_group_snapshot(self, **kwargs):
+ if 'name' not in kwargs:
+ kwargs['name'] = data_utils.rand_name(
+ self.__class__.__name__ + '-Group_Snapshot')
+
+ group_snapshot = self.group_snapshots_client.create_group_snapshot(
+ **kwargs)['group_snapshot']
+ group_snapshot['group_id'] = kwargs['group_id']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self._delete_group_snapshot, group_snapshot)
+ waiters.wait_for_volume_resource_status(
+ self.group_snapshots_client, group_snapshot['id'], 'available')
+ return group_snapshot
+
+ def _delete_group_snapshot(self, group_snapshot):
+ self.group_snapshots_client.delete_group_snapshot(group_snapshot['id'])
+ vols = self.volumes_client.list_volumes(detail=True)['volumes']
+ snapshots = self.snapshots_client.list_snapshots(
+ detail=True)['snapshots']
+ for vol in vols:
+ for snap in snapshots:
+ if (vol['group_id'] == group_snapshot['group_id'] and
+ vol['id'] == snap['volume_id']):
+ self.snapshots_client.wait_for_resource_deletion(
+ snap['id'])
+ self.group_snapshots_client.wait_for_resource_deletion(
+ group_snapshot['id'])
+
+
+class GroupSnapshotsTest(BaseGroupSnapshotsTest):
+ _api_version = 3
+ min_microversion = '3.14'
+ max_microversion = 'latest'
+
+ @decorators.idempotent_id('1298e537-f1f0-47a3-a1dd-8adec8168897')
+ def test_group_snapshot_create_show_list_delete(self):
+ # Create volume type
+ volume_type = self.create_volume_type()
+
+ # Create group type
+ group_type = self.create_group_type()
+
+ # Create group
+ grp = self.create_group(group_type=group_type['id'],
+ volume_types=[volume_type['id']])
+
+ # Create volume
+ vol = self.create_volume(volume_type=volume_type['id'],
+ group_id=grp['id'])
+
+ # Create group snapshot
+ group_snapshot_name = data_utils.rand_name('group_snapshot')
+ group_snapshot = self._create_group_snapshot(
+ group_id=grp['id'], name=group_snapshot_name)
+ snapshots = self.snapshots_client.list_snapshots(
+ detail=True)['snapshots']
+ for snap in snapshots:
+ if vol['id'] == snap['volume_id']:
+ waiters.wait_for_volume_resource_status(
+ self.snapshots_client, snap['id'], 'available')
+ self.assertEqual(group_snapshot_name, group_snapshot['name'])
+
+ # Get a given group snapshot
+ group_snapshot = self.group_snapshots_client.show_group_snapshot(
+ group_snapshot['id'])['group_snapshot']
+ self.assertEqual(group_snapshot_name, group_snapshot['name'])
+
+ # Get all group snapshots with details, check some detail-specific
+ # elements, and look for the created group snapshot
+ group_snapshots = self.group_snapshots_client.list_group_snapshots(
+ detail=True)['group_snapshots']
+ for grp_snapshot in group_snapshots:
+ self.assertIn('created_at', grp_snapshot)
+ self.assertIn('group_id', grp_snapshot)
+ self.assertIn((group_snapshot['name'], group_snapshot['id']),
+ [(m['name'], m['id']) for m in group_snapshots])
+
+ # Delete group snapshot
+ self._delete_group_snapshot(group_snapshot)
+ group_snapshots = self.group_snapshots_client.list_group_snapshots()[
+ 'group_snapshots']
+ self.assertEmpty(group_snapshots)
+
+ @decorators.idempotent_id('eff52c70-efc7-45ed-b47a-4ad675d09b81')
+ def test_create_group_from_group_snapshot(self):
+ # Create volume type
+ volume_type = self.create_volume_type()
+
+ # Create group type
+ group_type = self.create_group_type()
+
+ # Create Group
+ grp = self.create_group(group_type=group_type['id'],
+ volume_types=[volume_type['id']])
+
+ # Create volume
+ vol = self.create_volume(volume_type=volume_type['id'],
+ group_id=grp['id'])
+
+ # Create group_snapshot
+ group_snapshot_name = data_utils.rand_name('group_snapshot')
+ group_snapshot = self._create_group_snapshot(
+ group_id=grp['id'], name=group_snapshot_name)
+ self.assertEqual(group_snapshot_name, group_snapshot['name'])
+ snapshots = self.snapshots_client.list_snapshots(
+ detail=True)['snapshots']
+ for snap in snapshots:
+ if vol['id'] == snap['volume_id']:
+ waiters.wait_for_volume_resource_status(
+ self.snapshots_client, snap['id'], 'available')
+
+ # Create Group from Group snapshot
+ grp_name2 = data_utils.rand_name('Group_from_snap')
+ grp2 = self.groups_client.create_group_from_source(
+ group_snapshot_id=group_snapshot['id'], name=grp_name2)['group']
+ self.addCleanup(self.delete_group, grp2['id'])
+ self.assertEqual(grp_name2, grp2['name'])
+ vols = self.volumes_client.list_volumes(detail=True)['volumes']
+ for vol in vols:
+ if vol['group_id'] == grp2['id']:
+ waiters.wait_for_volume_resource_status(
+ self.volumes_client, vol['id'], 'available')
+ waiters.wait_for_volume_resource_status(
+ self.groups_client, grp2['id'], 'available')
+
+
+class GroupSnapshotsV319Test(BaseGroupSnapshotsTest):
+ _api_version = 3
+ min_microversion = '3.19'
+ max_microversion = 'latest'
+
+ @decorators.idempotent_id('3b42c9b9-c984-4444-816e-ca2e1ed30b40')
+ def test_reset_group_snapshot_status(self):
+ # Create volume type
+ volume_type = self.create_volume_type()
+
+ # Create group type
+ group_type = self.create_group_type()
+
+ # Create group
+ group = self.create_group(group_type=group_type['id'],
+ volume_types=[volume_type['id']])
+
+ # Create volume
+ volume = self.create_volume(volume_type=volume_type['id'],
+ group_id=group['id'])
+
+ # Create group snapshot
+ group_snapshot = self._create_group_snapshot(group_id=group['id'])
+ snapshots = self.snapshots_client.list_snapshots(
+ detail=True)['snapshots']
+ for snap in snapshots:
+ if volume['id'] == snap['volume_id']:
+ waiters.wait_for_volume_resource_status(
+ self.snapshots_client, snap['id'], 'available')
+
+ # Reset group snapshot status
+ self.addCleanup(waiters.wait_for_volume_resource_status,
+ self.group_snapshots_client,
+ group_snapshot['id'], 'available')
+ self.addCleanup(
+ self.admin_group_snapshots_client.reset_group_snapshot_status,
+ group_snapshot['id'], 'available')
+ for status in ['creating', 'available', 'error']:
+ self.admin_group_snapshots_client.reset_group_snapshot_status(
+ group_snapshot['id'], status)
+ waiters.wait_for_volume_resource_status(
+ self.group_snapshots_client, group_snapshot['id'], status)
diff --git a/tempest/api/volume/admin/test_groups.py b/tempest/api/volume/admin/test_groups.py
index 6b53d85..2f6eb6b 100644
--- a/tempest/api/volume/admin/test_groups.py
+++ b/tempest/api/volume/admin/test_groups.py
@@ -17,54 +17,14 @@
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
-from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
CONF = config.CONF
-class BaseGroupsTest(base.BaseVolumeAdminTest):
-
- def _delete_group(self, grp_id, delete_volumes=True):
- self.groups_client.delete_group(grp_id, delete_volumes)
- vols = self.volumes_client.list_volumes(detail=True)['volumes']
- for vol in vols:
- if vol['group_id'] == grp_id:
- self.volumes_client.wait_for_resource_deletion(vol['id'])
- self.groups_client.wait_for_resource_deletion(grp_id)
-
- def _delete_group_snapshot(self, group_snapshot_id, grp_id):
- self.group_snapshots_client.delete_group_snapshot(group_snapshot_id)
- vols = self.volumes_client.list_volumes(detail=True)['volumes']
- snapshots = self.snapshots_client.list_snapshots(
- detail=True)['snapshots']
- for vol in vols:
- for snap in snapshots:
- if (vol['group_id'] == grp_id and
- vol['id'] == snap['volume_id']):
- self.snapshots_client.wait_for_resource_deletion(
- snap['id'])
- self.group_snapshots_client.wait_for_resource_deletion(
- group_snapshot_id)
-
- def _create_group(self, group_type, volume_type, grp_name=None):
- if not grp_name:
- grp_name = data_utils.rand_name('Group')
- grp = self.groups_client.create_group(
- group_type=group_type['id'],
- volume_types=[volume_type['id']],
- name=grp_name)['group']
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self._delete_group, grp['id'])
- waiters.wait_for_volume_resource_status(
- self.groups_client, grp['id'], 'available')
- self.assertEqual(grp_name, grp['name'])
- return grp
-
-
-class GroupsTest(BaseGroupsTest):
+class GroupsTest(base.BaseVolumeAdminTest):
_api_version = 3
- min_microversion = '3.14'
+ min_microversion = '3.13'
max_microversion = 'latest'
@decorators.idempotent_id('4b111d28-b73d-4908-9bd2-03dc2992e4d4')
@@ -77,13 +37,15 @@
# Create group
grp1_name = data_utils.rand_name('Group1')
- grp1 = self._create_group(group_type, volume_type,
- grp_name=grp1_name)
+ grp1 = self.create_group(group_type=group_type['id'],
+ volume_types=[volume_type['id']],
+ name=grp1_name)
grp1_id = grp1['id']
grp2_name = data_utils.rand_name('Group2')
- grp2 = self._create_group(group_type, volume_type,
- grp_name=grp2_name)
+ grp2 = self.create_group(group_type=group_type['id'],
+ volume_types=[volume_type['id']],
+ name=grp2_name)
grp2_id = grp2['id']
# Create volume
@@ -125,143 +87,12 @@
# Delete group
# grp1 has a volume so delete_volumes flag is set to True by default
- self._delete_group(grp1_id)
+ self.delete_group(grp1_id)
# grp2 is empty so delete_volumes flag can be set to False
- self._delete_group(grp2_id, delete_volumes=False)
+ self.delete_group(grp2_id, delete_volumes=False)
grps = self.groups_client.list_groups(detail=True)['groups']
self.assertEmpty(grps)
- @decorators.idempotent_id('1298e537-f1f0-47a3-a1dd-8adec8168897')
- def test_group_snapshot_create_show_list_delete(self):
- # Create volume type
- volume_type = self.create_volume_type()
-
- # Create group type
- group_type = self.create_group_type()
-
- # Create group
- grp = self._create_group(group_type, volume_type)
-
- # Create volume
- vol = self.create_volume(volume_type=volume_type['id'],
- group_id=grp['id'])
-
- # Create group snapshot
- group_snapshot_name = data_utils.rand_name('group_snapshot')
- group_snapshot = (
- self.group_snapshots_client.create_group_snapshot(
- group_id=grp['id'],
- name=group_snapshot_name)['group_snapshot'])
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self._delete_group_snapshot,
- group_snapshot['id'], grp['id'])
- snapshots = self.snapshots_client.list_snapshots(
- detail=True)['snapshots']
- for snap in snapshots:
- if vol['id'] == snap['volume_id']:
- waiters.wait_for_volume_resource_status(
- self.snapshots_client, snap['id'], 'available')
- waiters.wait_for_volume_resource_status(
- self.group_snapshots_client,
- group_snapshot['id'], 'available')
- self.assertEqual(group_snapshot_name, group_snapshot['name'])
-
- # Get a given group snapshot
- group_snapshot = self.group_snapshots_client.show_group_snapshot(
- group_snapshot['id'])['group_snapshot']
- self.assertEqual(group_snapshot_name, group_snapshot['name'])
-
- # Get all group snapshots with details, check some detail-specific
- # elements, and look for the created group snapshot
- group_snapshots = (self.group_snapshots_client.list_group_snapshots(
- detail=True)['group_snapshots'])
- for grp_snapshot in group_snapshots:
- self.assertIn('created_at', grp_snapshot)
- self.assertIn('group_id', grp_snapshot)
- self.assertIn((group_snapshot['name'], group_snapshot['id']),
- [(m['name'], m['id']) for m in group_snapshots])
-
- # Delete group snapshot
- self._delete_group_snapshot(group_snapshot['id'], grp['id'])
- group_snapshots = (self.group_snapshots_client.list_group_snapshots()
- ['group_snapshots'])
- self.assertEmpty(group_snapshots)
-
- @decorators.idempotent_id('eff52c70-efc7-45ed-b47a-4ad675d09b81')
- def test_create_group_from_group_snapshot(self):
- # Create volume type
- volume_type = self.create_volume_type()
-
- # Create group type
- group_type = self.create_group_type()
-
- # Create Group
- grp = self._create_group(group_type, volume_type)
-
- # Create volume
- vol = self.create_volume(volume_type=volume_type['id'],
- group_id=grp['id'])
-
- # Create group_snapshot
- group_snapshot_name = data_utils.rand_name('group_snapshot')
- group_snapshot = (
- self.group_snapshots_client.create_group_snapshot(
- group_id=grp['id'],
- name=group_snapshot_name)['group_snapshot'])
- self.addCleanup(self._delete_group_snapshot,
- group_snapshot['id'], grp['id'])
- self.assertEqual(group_snapshot_name, group_snapshot['name'])
- snapshots = self.snapshots_client.list_snapshots(
- detail=True)['snapshots']
- for snap in snapshots:
- if vol['id'] == snap['volume_id']:
- waiters.wait_for_volume_resource_status(
- self.snapshots_client, snap['id'], 'available')
- waiters.wait_for_volume_resource_status(
- self.group_snapshots_client, group_snapshot['id'], 'available')
-
- # Create Group from Group snapshot
- grp_name2 = data_utils.rand_name('Group_from_snap')
- grp2 = self.groups_client.create_group_from_source(
- group_snapshot_id=group_snapshot['id'], name=grp_name2)['group']
- self.addCleanup(self._delete_group, grp2['id'])
- self.assertEqual(grp_name2, grp2['name'])
- vols = self.volumes_client.list_volumes(detail=True)['volumes']
- for vol in vols:
- if vol['group_id'] == grp2['id']:
- waiters.wait_for_volume_resource_status(
- self.volumes_client, vol['id'], 'available')
- waiters.wait_for_volume_resource_status(
- self.groups_client, grp2['id'], 'available')
-
- @decorators.idempotent_id('2424af8c-7851-4888-986a-794b10c3210e')
- def test_create_group_from_group(self):
- # Create volume type
- volume_type = self.create_volume_type()
-
- # Create group type
- group_type = self.create_group_type()
-
- # Create Group
- grp = self._create_group(group_type, volume_type)
-
- # Create volume
- self.create_volume(volume_type=volume_type['id'], group_id=grp['id'])
-
- # Create Group from Group
- grp_name2 = data_utils.rand_name('Group_from_grp')
- grp2 = self.groups_client.create_group_from_source(
- source_group_id=grp['id'], name=grp_name2)['group']
- self.addCleanup(self._delete_group, grp2['id'])
- self.assertEqual(grp_name2, grp2['name'])
- vols = self.volumes_client.list_volumes(detail=True)['volumes']
- for vol in vols:
- if vol['group_id'] == grp2['id']:
- waiters.wait_for_volume_resource_status(
- self.volumes_client, vol['id'], 'available')
- waiters.wait_for_volume_resource_status(
- self.groups_client, grp2['id'], 'available')
-
@decorators.idempotent_id('4a8a6fd2-8b3b-4641-8f54-6a6f99320006')
def test_group_update(self):
# Create volume type
@@ -271,7 +102,8 @@
group_type = self.create_group_type()
# Create Group
- grp = self._create_group(group_type, volume_type)
+ grp = self.create_group(group_type=group_type['id'],
+ volume_types=[volume_type['id']])
# Create volumes
grp_vols = []
@@ -317,56 +149,42 @@
self.assertEqual(2, len(grp_vols))
-class GroupsV319Test(BaseGroupsTest):
+class GroupsV314Test(base.BaseVolumeAdminTest):
_api_version = 3
- min_microversion = '3.19'
+ min_microversion = '3.14'
max_microversion = 'latest'
- @decorators.idempotent_id('3b42c9b9-c984-4444-816e-ca2e1ed30b40')
- def test_reset_group_snapshot_status(self):
+ @decorators.idempotent_id('2424af8c-7851-4888-986a-794b10c3210e')
+ def test_create_group_from_group(self):
# Create volume type
volume_type = self.create_volume_type()
# Create group type
group_type = self.create_group_type()
- # Create group
- group = self._create_group(group_type, volume_type)
+ # Create Group
+ grp = self.create_group(group_type=group_type['id'],
+ volume_types=[volume_type['id']])
# Create volume
- volume = self.create_volume(volume_type=volume_type['id'],
- group_id=group['id'])
+ self.create_volume(volume_type=volume_type['id'], group_id=grp['id'])
- # Create group snapshot
- group_snapshot_name = data_utils.rand_name('group_snapshot')
- group_snapshot = (self.group_snapshots_client.create_group_snapshot(
- group_id=group['id'], name=group_snapshot_name)['group_snapshot'])
- self.addCleanup(self._delete_group_snapshot,
- group_snapshot['id'], group['id'])
- snapshots = self.snapshots_client.list_snapshots(
- detail=True)['snapshots']
- for snap in snapshots:
- if volume['id'] == snap['volume_id']:
+ # Create Group from Group
+ grp_name2 = data_utils.rand_name('Group_from_grp')
+ grp2 = self.groups_client.create_group_from_source(
+ source_group_id=grp['id'], name=grp_name2)['group']
+ self.addCleanup(self.delete_group, grp2['id'])
+ self.assertEqual(grp_name2, grp2['name'])
+ vols = self.volumes_client.list_volumes(detail=True)['volumes']
+ for vol in vols:
+ if vol['group_id'] == grp2['id']:
waiters.wait_for_volume_resource_status(
- self.snapshots_client, snap['id'], 'available')
+ self.volumes_client, vol['id'], 'available')
waiters.wait_for_volume_resource_status(
- self.group_snapshots_client, group_snapshot['id'], 'available')
-
- # Reset group snapshot status
- self.addCleanup(waiters.wait_for_volume_resource_status,
- self.group_snapshots_client,
- group_snapshot['id'], 'available')
- self.addCleanup(
- self.admin_group_snapshots_client.reset_group_snapshot_status,
- group_snapshot['id'], 'available')
- for status in ['creating', 'available', 'error']:
- self.admin_group_snapshots_client.reset_group_snapshot_status(
- group_snapshot['id'], status)
- waiters.wait_for_volume_resource_status(
- self.group_snapshots_client, group_snapshot['id'], status)
+ self.groups_client, grp2['id'], 'available')
-class GroupsV320Test(BaseGroupsTest):
+class GroupsV320Test(base.BaseVolumeAdminTest):
_api_version = 3
min_microversion = '3.20'
max_microversion = 'latest'
@@ -380,7 +198,8 @@
group_type = self.create_group_type()
# Create group
- group = self._create_group(group_type, volume_type)
+ group = self.create_group(group_type=group_type['id'],
+ volume_types=[volume_type['id']])
# Reset group status
self.addCleanup(waiters.wait_for_volume_resource_status,
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 63ef85b..ea3bb5a 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -242,6 +242,27 @@
self.servers_client.delete_server, body['id'])
return body
+ def create_group(self, **kwargs):
+ if 'name' not in kwargs:
+ kwargs['name'] = data_utils.rand_name(
+ self.__class__.__name__ + '-Group')
+
+ group = self.groups_client.create_group(**kwargs)['group']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.delete_group, group['id'])
+ waiters.wait_for_volume_resource_status(
+ self.groups_client, group['id'], 'available')
+ return group
+
+ def delete_group(self, group_id, delete_volumes=True):
+ self.groups_client.delete_group(group_id, delete_volumes)
+ if delete_volumes:
+ vols = self.volumes_client.list_volumes(detail=True)['volumes']
+ for vol in vols:
+ if vol['group_id'] == group_id:
+ self.volumes_client.wait_for_resource_deletion(vol['id'])
+ self.groups_client.wait_for_resource_deletion(group_id)
+
class BaseVolumeAdminTest(BaseVolumeTest):
"""Base test case class for all Volume Admin API tests."""