diff --git a/.zuul.yaml b/.zuul.yaml index a5d34c5..2b6b59c 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -25,9 +25,9 @@ # branches. That is what we need to do for all tempest plugins. Only jobs # for the current releasable ("Maintained") stable branches should be listed # here. + - cinder-tempest-plugin-basic-2023-2 - cinder-tempest-plugin-basic-2023-1 - cinder-tempest-plugin-basic-zed - - cinder-tempest-plugin-basic-yoga - cinder-tempest-plugin-protection-functional gate: jobs: @@ -38,9 +38,9 @@ - cinder-tempest-plugin-cbak-ceph experimental: jobs: + - cinder-tempest-plugin-cbak-ceph-2023-2 - cinder-tempest-plugin-cbak-ceph-2023-1 - cinder-tempest-plugin-cbak-ceph-zed - - cinder-tempest-plugin-cbak-ceph-yoga - job: name: cinder-tempest-plugin-protection-functional @@ -269,6 +269,12 @@ timeout: 10800 - job: + name: cinder-tempest-plugin-cbak-ceph-2023-2 + parent: cinder-tempest-plugin-cbak-ceph + nodeset: openstack-single-node-jammy + override-checkout: stable/2023.2 + +- job: name: cinder-tempest-plugin-cbak-ceph-2023-1 parent: cinder-tempest-plugin-cbak-ceph nodeset: openstack-single-node-jammy @@ -279,12 +285,6 @@ parent: cinder-tempest-plugin-cbak-ceph nodeset: openstack-single-node-focal override-checkout: stable/zed - -- job: - name: cinder-tempest-plugin-cbak-ceph-yoga - parent: cinder-tempest-plugin-cbak-ceph - nodeset: openstack-single-node-focal - override-checkout: stable/yoga # variant for pre-Ussuri branches (no volume revert for Ceph), # should this job be used on those branches @@ -416,6 +416,12 @@ - ^releasenotes/.*$ - job: + name: cinder-tempest-plugin-basic-2023-2 + parent: cinder-tempest-plugin-basic + nodeset: openstack-single-node-jammy + override-checkout: stable/2023.2 + +- job: name: cinder-tempest-plugin-basic-2023-1 parent: cinder-tempest-plugin-basic nodeset: openstack-single-node-jammy @@ -426,9 +432,3 @@ parent: cinder-tempest-plugin-basic nodeset: openstack-single-node-focal override-checkout: stable/zed - -- job: - name: cinder-tempest-plugin-basic-yoga - parent: cinder-tempest-plugin-basic - nodeset: openstack-single-node-focal - override-checkout: stable/yoga diff --git a/cinder_tempest_plugin/api/volume/admin/test_consistencygroups.py b/cinder_tempest_plugin/api/volume/admin/test_consistencygroups.py index 7dff494..42c78f1 100644 --- a/cinder_tempest_plugin/api/volume/admin/test_consistencygroups.py +++ b/cinder_tempest_plugin/api/volume/admin/test_consistencygroups.py @@ -28,9 +28,7 @@ class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest): @classmethod def setup_clients(cls): - cls._api_version = 2 super(ConsistencyGroupsV2Test, cls).setup_clients() - cls.admin_volume_client = cls.os_admin.volumes_v2_client manager = cinder_clients.Manager(cls.os_admin) cls.consistencygroups_adm_client = manager.consistencygroups_adm_client diff --git a/cinder_tempest_plugin/api/volume/admin/test_volume_backup.py b/cinder_tempest_plugin/api/volume/admin/test_volume_backup.py index e5ded52..41cfc91 100644 --- a/cinder_tempest_plugin/api/volume/admin/test_volume_backup.py +++ b/cinder_tempest_plugin/api/volume/admin/test_volume_backup.py @@ -23,13 +23,6 @@ class VolumesBackupsTest(base.BaseVolumeAdminTest): - @classmethod - def setup_clients(cls): - super(VolumesBackupsTest, cls).setup_clients() - cls.admin_volume_client = cls.os_admin.volumes_client_latest - cls.backups_client = cls.os_primary.backups_client_latest - cls.volumes_client = cls.os_primary.volumes_client_latest - @classmethod def skip_checks(cls): super(VolumesBackupsTest, cls).skip_checks() diff --git a/cinder_tempest_plugin/api/volume/base.py b/cinder_tempest_plugin/api/volume/base.py index ea6bd2e..1fd82bf 100644 --- a/cinder_tempest_plugin/api/volume/base.py +++ b/cinder_tempest_plugin/api/volume/base.py @@ -16,7 +16,6 @@ from tempest.common import compute from tempest.common import waiters from tempest import config -from tempest.lib.common import api_microversion_fixture from tempest.lib.common import api_version_utils from tempest.lib.common.utils import data_utils from tempest.lib.common.utils import test_utils @@ -57,8 +56,6 @@ def setUp(self): super(BaseVolumeTest, self).setUp() - self.useFixture(api_microversion_fixture.APIMicroversionFixture( - volume_microversion=self.request_microversion)) @classmethod def resource_setup(cls): @@ -67,6 +64,8 @@ api_version_utils.select_request_microversion( cls.min_microversion, CONF.volume.min_microversion)) + cls.setup_api_microversion_fixture( + volume_microversion=cls.request_microversion) @classmethod def create_volume(cls, wait_until='available', **kwargs): @@ -171,7 +170,7 @@ cls.admin_volume_types_client = cls.os_admin.volume_types_client_latest cls.admin_backups_client = cls.os_admin.backups_client_latest - cls.admin_volumes_client = cls.os_admin.volumes_client_latest + cls.admin_volume_client = cls.os_admin.volumes_client_latest @classmethod def create_volume_type(cls, name=None, **kwargs): @@ -194,12 +193,12 @@ type_id = volume_type['id'] type_name = volume_type['name'] - volumes = cls.admin_volumes_client.list_volumes( + volumes = cls.admin_volume_client.list_volumes( detail=True, params={'all_tenants': 1})['volumes'] for volume in [v for v in volumes if v['volume_type'] == type_name]: test_utils.call_and_ignore_notfound_exc( - cls.admin_volumes_client.delete_volume, volume['id']) - cls.admin_volumes_client.wait_for_resource_deletion(volume['id']) + cls.admin_volume_client.delete_volume, volume['id']) + cls.admin_volume_client.wait_for_resource_deletion(volume['id']) test_utils.call_and_ignore_notfound_exc( cls.admin_volume_types_client.delete_volume_type, type_id) diff --git a/cinder_tempest_plugin/api/volume/test_volume_dependency.py b/cinder_tempest_plugin/api/volume/test_volume_dependency.py new file mode 100644 index 0000000..b204e84 --- /dev/null +++ b/cinder_tempest_plugin/api/volume/test_volume_dependency.py @@ -0,0 +1,121 @@ +# 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 import config +from tempest.lib import decorators + +from cinder_tempest_plugin.api.volume import base + +CONF = config.CONF + + +class VolumeDependencyTests(base.BaseVolumeTest): + min_microversion = '3.40' + + @classmethod + def setup_clients(cls): + super(VolumeDependencyTests, cls).setup_clients() + + @decorators.idempotent_id('42e9df95-854b-4840-9d55-ae62f65e9b8e') + def test_delete_source_volume(self): + """Test basic dependency deletion + + * Create a volume with source_volid + * Delete the source volume + """ + source_volume = self.create_volume() + kwargs = {'source_volid': source_volume['id']} + cloned_volume = self.create_volume(**kwargs) + self.assertEqual(source_volume['id'], cloned_volume['source_volid']) + self.volumes_client.delete_volume(source_volume['id']) + self.volumes_client.wait_for_resource_deletion(source_volume['id']) + + @decorators.idempotent_id('900d8ea5-2afd-4fe5-a0c3-fab4744f0d40') + def test_delete_source_snapshot(self): + """Test basic dependency deletion with snapshot + + * Create a snapshot from source volume + * Create a volume from that snapshot + * Delete the source snapshot + * Delete the source volume + """ + source_volume = self.create_volume() + snapshot_source_volume = self.create_snapshot(source_volume['id']) + kwargs = {'snapshot_id': snapshot_source_volume['id']} + volume_from_snapshot = self.create_volume(**kwargs) + self.assertEqual(volume_from_snapshot['snapshot_id'], + snapshot_source_volume['id']) + + self.snapshots_client.delete_snapshot(snapshot_source_volume['id']) + self.snapshots_client.wait_for_resource_deletion( + snapshot_source_volume['id']) + self.volumes_client.delete_volume(source_volume['id']) + self.volumes_client.wait_for_resource_deletion(source_volume['id']) + + def _delete_vol_and_wait(self, vol_id): + self.volumes_client.delete_volume(vol_id) + + self.volumes_client.wait_for_resource_deletion(vol_id) + + def _delete_snap_and_wait(self, snap_id): + self.snapshots_client.delete_snapshot(snap_id) + + self.snapshots_client.wait_for_resource_deletion(snap_id) + + @decorators.idempotent_id('f8278e5c-50ff-4a1d-8670-3ca0866d411a') + def test_delete_dep_chain(self): + """Test a complex chain of volume and snapshot dependency deletion.""" + volume_1 = self.create_volume()['id'] + snapshot_of_vol_1 = self.create_snapshot(volume_1)['id'] + + volume_2_args = {'snapshot_id': snapshot_of_vol_1} + volume_2 = self.create_volume(**volume_2_args)['id'] + + snapshot_of_vol_2 = self.create_snapshot(volume_2)['id'] + + volume_3_args = {'snapshot_id': snapshot_of_vol_2} + volume_3 = self.create_volume(**volume_3_args)['id'] + + volume_4_args = {'source_volid': volume_3} + volume_4 = self.create_volume(**volume_4_args)['id'] + + self._delete_snap_and_wait(snapshot_of_vol_1) + self._delete_snap_and_wait(snapshot_of_vol_2) + + self._delete_vol_and_wait(volume_3) + self._delete_vol_and_wait(volume_1) + self._delete_vol_and_wait(volume_2) + self._delete_vol_and_wait(volume_4) + + @decorators.idempotent_id('63447ef8-e667-4796-ba66-1b9b883af1f1') + def test_delete_dep_chain_2(self): + """Test a different chain of volume/snapshot dependency deletion.""" + volume_1 = self.create_volume()['id'] + snapshot_of_vol_1 = self.create_snapshot(volume_1)['id'] + + volume_2_args = {'snapshot_id': snapshot_of_vol_1} + volume_2 = self.create_volume(**volume_2_args)['id'] + + snapshot_of_vol_2 = self.create_snapshot(volume_2)['id'] + + volume_3_args = {'snapshot_id': snapshot_of_vol_2} + volume_3 = self.create_volume(**volume_3_args)['id'] + + self._delete_snap_and_wait(snapshot_of_vol_1) + self._delete_snap_and_wait(snapshot_of_vol_2) + + self._delete_vol_and_wait(volume_1) + self._delete_vol_and_wait(volume_2) + self._delete_vol_and_wait(volume_3) diff --git a/cinder_tempest_plugin/api/volume/test_volume_revert.py b/cinder_tempest_plugin/api/volume/test_volume_revert.py index bf3d806..2c4d6bd 100644 --- a/cinder_tempest_plugin/api/volume/test_volume_revert.py +++ b/cinder_tempest_plugin/api/volume/test_volume_revert.py @@ -35,7 +35,6 @@ @classmethod def setup_clients(cls): - cls._api_version = 3 super(VolumeRevertTests, cls).setup_clients() manager = cinder_clients.Manager(cls.os_primary) diff --git a/cinder_tempest_plugin/rbac/v3/base.py b/cinder_tempest_plugin/rbac/v3/base.py index af724a3..6fc6be5 100644 --- a/cinder_tempest_plugin/rbac/v3/base.py +++ b/cinder_tempest_plugin/rbac/v3/base.py @@ -13,7 +13,6 @@ from tempest.common import waiters from tempest import config -from tempest.lib.common import api_microversion_fixture from tempest.lib.common import api_version_utils from tempest.lib.common.utils import data_utils from tempest.lib.common.utils import test_utils @@ -51,8 +50,6 @@ def setUp(self): super(VolumeV3RbacBaseTests, self).setUp() - self.useFixture(api_microversion_fixture.APIMicroversionFixture( - volume_microversion=self.request_microversion)) @classmethod def resource_setup(cls): @@ -61,6 +58,8 @@ api_version_utils.select_request_microversion( cls.min_microversion, CONF.volume.min_microversion)) + cls.setup_api_microversion_fixture( + volume_microversion=cls.request_microversion) def do_request(self, method, expected_status=200, client=None, **payload): """Perform API call