Cinder Tempest plugin tests: Switch to stable interface
All the cinder tempest plugin tests are inherited from tempest/api/volume/base.py
which is not stable class and can be changed anytime by tempest.
One recent case where some changes in base class on tempest side could
have break the cinder tests-
http://logs.openstack.org/07/522707/3/check/legacy-tempest-dsvm-full-devstack-plugin-ceph/a92cd60/logs/testr_results.html.gz
This commit switch cinder tests to use test.py which is stable interface
for plugin and create a base class with commonly used function & variable.
Change-Id: I0edda1fa23aed0b3d25691d5f4440a7234decc9a
Closes-Bug: #1734821
ghanshyam
8 years ago
| 0 | # Copyright 2017 NEC Corporation. | |
| 1 | # All Rights Reserved. | |
| 2 | # | |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
| 4 | # not use this file except in compliance with the License. You may obtain | |
| 5 | # a copy of the License at | |
| 6 | # | |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 | # | |
| 9 | # Unless required by applicable law or agreed to in writing, software | |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
| 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
| 12 | # License for the specific language governing permissions and limitations | |
| 13 | # under the License. | |
| 14 | ||
| 15 | from tempest.api.volume import api_microversion_fixture | |
| 16 | from tempest.common import compute | |
| 17 | from tempest.common import waiters | |
| 18 | from tempest import config | |
| 19 | from tempest.lib.common import api_version_utils | |
| 20 | from tempest.lib.common.utils import data_utils | |
| 21 | from tempest.lib.common.utils import test_utils | |
| 22 | from tempest.lib import exceptions | |
| 23 | from tempest import test | |
| 24 | ||
| 25 | CONF = config.CONF | |
| 26 | ||
| 27 | ||
| 28 | class BaseVolumeTest(api_version_utils.BaseMicroversionTest, | |
| 29 | test.BaseTestCase): | |
| 30 | """Base test case class for all Cinder API tests.""" | |
| 31 | ||
| 32 | _api_version = 2 | |
| 33 | credentials = ['primary'] | |
| 34 | ||
| 35 | @classmethod | |
| 36 | def skip_checks(cls): | |
| 37 | super(BaseVolumeTest, cls).skip_checks() | |
| 38 | ||
| 39 | if not CONF.service_available.cinder: | |
| 40 | skip_msg = ("%s skipped as Cinder is not available" % cls.__name__) | |
| 41 | raise cls.skipException(skip_msg) | |
| 42 | if cls._api_version == 2: | |
| 43 | if not CONF.volume_feature_enabled.api_v2: | |
| 44 | msg = "Volume API v2 is disabled" | |
| 45 | raise cls.skipException(msg) | |
| 46 | elif cls._api_version == 3: | |
| 47 | if not CONF.volume_feature_enabled.api_v3: | |
| 48 | msg = "Volume API v3 is disabled" | |
| 49 | raise cls.skipException(msg) | |
| 50 | else: | |
| 51 | msg = ("Invalid Cinder API version (%s)" % cls._api_version) | |
| 52 | raise exceptions.InvalidConfiguration(msg) | |
| 53 | ||
| 54 | api_version_utils.check_skip_with_microversion( | |
| 55 | cls.min_microversion, cls.max_microversion, | |
| 56 | CONF.volume.min_microversion, CONF.volume.max_microversion) | |
| 57 | ||
| 58 | @classmethod | |
| 59 | def setup_clients(cls): | |
| 60 | super(BaseVolumeTest, cls).setup_clients() | |
| 61 | if cls._api_version == 3: | |
| 62 | cls.backups_client = cls.os_primary.backups_v3_client | |
| 63 | cls.volumes_client = cls.os_primary.volumes_v3_client | |
| 64 | else: | |
| 65 | cls.backups_client = cls.os_primary.backups_v2_client | |
| 66 | cls.volumes_client = cls.os_primary.volumes_v2_client | |
| 67 | ||
| 68 | cls.snapshots_client = cls.os_primary.snapshots_v2_client | |
| 69 | ||
| 70 | @classmethod | |
| 71 | def setup_credentials(cls): | |
| 72 | cls.set_network_resources() | |
| 73 | super(BaseVolumeTest, cls).setup_credentials() | |
| 74 | ||
| 75 | def setUp(self): | |
| 76 | super(BaseVolumeTest, self).setUp() | |
| 77 | self.useFixture(api_microversion_fixture.APIMicroversionFixture( | |
| 78 | self.request_microversion)) | |
| 79 | ||
| 80 | @classmethod | |
| 81 | def resource_setup(cls): | |
| 82 | super(BaseVolumeTest, cls).resource_setup() | |
| 83 | cls.request_microversion = ( | |
| 84 | api_version_utils.select_request_microversion( | |
| 85 | cls.min_microversion, | |
| 86 | CONF.volume.min_microversion)) | |
| 87 | ||
| 88 | @classmethod | |
| 89 | def create_volume(cls, wait_until='available', **kwargs): | |
| 90 | """Wrapper utility that returns a test volume. | |
| 91 | ||
| 92 | :param wait_until: wait till volume status. | |
| 93 | """ | |
| 94 | if 'size' not in kwargs: | |
| 95 | kwargs['size'] = CONF.volume.volume_size | |
| 96 | ||
| 97 | if 'imageRef' in kwargs: | |
| 98 | image = cls.os_primary.image_client_v2.show_image( | |
| 99 | kwargs['imageRef']) | |
| 100 | min_disk = image['min_disk'] | |
| 101 | kwargs['size'] = max(kwargs['size'], min_disk) | |
| 102 | ||
| 103 | if 'name' not in kwargs: | |
| 104 | name = data_utils.rand_name(cls.__name__ + '-Volume') | |
| 105 | kwargs['name'] = name | |
| 106 | ||
| 107 | volume = cls.volumes_client.create_volume(**kwargs)['volume'] | |
| 108 | cls.addClassResourceCleanup( | |
| 109 | cls.volumes_client.wait_for_resource_deletion, volume['id']) | |
| 110 | cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc, | |
| 111 | cls.volumes_client.delete_volume, | |
| 112 | volume['id']) | |
| 113 | waiters.wait_for_volume_resource_status(cls.volumes_client, | |
| 114 | volume['id'], wait_until) | |
| 115 | return volume | |
| 116 | ||
| 117 | @classmethod | |
| 118 | def create_snapshot(cls, volume_id=1, **kwargs): | |
| 119 | """Wrapper utility that returns a test snapshot.""" | |
| 120 | if 'name' not in kwargs: | |
| 121 | name = data_utils.rand_name(cls.__name__ + '-Snapshot') | |
| 122 | kwargs['name'] = name | |
| 123 | ||
| 124 | snapshot = cls.snapshots_client.create_snapshot( | |
| 125 | volume_id=volume_id, **kwargs)['snapshot'] | |
| 126 | cls.addClassResourceCleanup( | |
| 127 | cls.snapshots_client.wait_for_resource_deletion, snapshot['id']) | |
| 128 | cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc, | |
| 129 | cls.snapshots_client.delete_snapshot, | |
| 130 | snapshot['id']) | |
| 131 | waiters.wait_for_volume_resource_status(cls.snapshots_client, | |
| 132 | snapshot['id'], 'available') | |
| 133 | return snapshot | |
| 134 | ||
| 135 | def create_backup(self, volume_id, backup_client=None, **kwargs): | |
| 136 | """Wrapper utility that returns a test backup.""" | |
| 137 | if backup_client is None: | |
| 138 | backup_client = self.backups_client | |
| 139 | if 'name' not in kwargs: | |
| 140 | name = data_utils.rand_name(self.__class__.__name__ + '-Backup') | |
| 141 | kwargs['name'] = name | |
| 142 | ||
| 143 | backup = backup_client.create_backup( | |
| 144 | volume_id=volume_id, **kwargs)['backup'] | |
| 145 | self.addCleanup(backup_client.delete_backup, backup['id']) | |
| 146 | waiters.wait_for_volume_resource_status(backup_client, backup['id'], | |
| 147 | 'available') | |
| 148 | return backup | |
| 149 | ||
| 150 | def create_server(self, wait_until='ACTIVE', **kwargs): | |
| 151 | name = kwargs.pop( | |
| 152 | 'name', | |
| 153 | data_utils.rand_name(self.__class__.__name__ + '-instance')) | |
| 154 | ||
| 155 | tenant_network = self.get_tenant_network() | |
| 156 | body, _ = compute.create_test_server( | |
| 157 | self.os_primary, | |
| 158 | tenant_network=tenant_network, | |
| 159 | name=name, | |
| 160 | wait_until=wait_until, | |
| 161 | **kwargs) | |
| 162 | ||
| 163 | self.addCleanup(test_utils.call_and_ignore_notfound_exc, | |
| 164 | waiters.wait_for_server_termination, | |
| 165 | self.os_primary.servers_client, body['id']) | |
| 166 | self.addCleanup(test_utils.call_and_ignore_notfound_exc, | |
| 167 | self.os_primary.servers_client.delete_server, | |
| 168 | body['id']) | |
| 169 | return body |
| 13 | 13 | # License for the specific language governing permissions and limitations |
| 14 | 14 | # under the License. |
| 15 | 15 | |
| 16 | from tempest.api.volume import base | |
| 17 | 16 | from tempest.common import waiters |
| 18 | 17 | from tempest import config |
| 19 | 18 | from tempest.lib.common.utils import data_utils |
| 20 | 19 | from tempest.lib import decorators |
| 21 | 20 | |
| 21 | from cinder.tests.tempest.api.volume import base | |
| 22 | 22 | from cinder.tests.tempest import cinder_clients |
| 23 | 23 | |
| 24 | 24 | CONF = config.CONF |
| 25 | 25 | |
| 26 | 26 | |
| 27 | class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest): | |
| 28 | ||
| 27 | class ConsistencyGroupsV2Test(base.BaseVolumeTest): | |
| 29 | 28 | @classmethod |
| 30 | 29 | def setup_clients(cls): |
| 31 | 30 | cls._api_version = 2 |
| 32 | 31 | super(ConsistencyGroupsV2Test, cls).setup_clients() |
| 32 | cls.admin_volume_client = cls.os_admin.volumes_v2_client | |
| 33 | 33 | |
| 34 | 34 | manager = cinder_clients.Manager(cls.os_admin) |
| 35 | 35 | cls.consistencygroups_adm_client = manager.consistencygroups_adm_client |
| 53 | 53 | def _delete_cgsnapshot(self, cgsnapshot_id, cg_id): |
| 54 | 54 | self.consistencygroups_adm_client.delete_cgsnapshot(cgsnapshot_id) |
| 55 | 55 | vols = self.admin_volume_client.list_volumes(detail=True)['volumes'] |
| 56 | snapshots = self.admin_snapshots_client.list_snapshots( | |
| 56 | snapshots = self.os_admin.snapshots_v2_client.list_snapshots( | |
| 57 | 57 | detail=True)['snapshots'] |
| 58 | 58 | for vol in vols: |
| 59 | 59 | for snap in snapshots: |
| 60 | 60 | if (vol['consistencygroup_id'] == cg_id and |
| 61 | 61 | vol['id'] == snap['volume_id']): |
| 62 | self.snapshots_client.wait_for_resource_deletion( | |
| 63 | snap['id']) | |
| 62 | (self.snapshots_client. | |
| 63 | wait_for_resource_deletion(snap['id'])) | |
| 64 | 64 | self.consistencygroups_adm_client.wait_for_cgsnapshot_deletion( |
| 65 | 65 | cgsnapshot_id) |
| 66 | 66 | |
| 68 | 68 | def test_consistencygroup_create_delete(self): |
| 69 | 69 | # Create volume type |
| 70 | 70 | name = data_utils.rand_name("volume-type") |
| 71 | volume_type = self.admin_volume_types_client.create_volume_type( | |
| 71 | volume_type = self.os_admin.volume_types_v2_client.create_volume_type( | |
| 72 | 72 | name=name)['volume_type'] |
| 73 | 73 | |
| 74 | 74 | # Create CG |
| 105 | 105 | |
| 106 | 106 | # Clean up |
| 107 | 107 | self._delete_consistencygroup(cg['id']) |
| 108 | self.admin_volume_types_client.delete_volume_type(volume_type['id']) | |
| 108 | self.os_admin.volume_types_v2_client.delete_volume_type( | |
| 109 | volume_type['id']) | |
| 109 | 110 | |
| 110 | 111 | @decorators.idempotent_id('2134dd52-f333-4456-bb05-6cb0f009a44f') |
| 111 | 112 | def test_consistencygroup_cgsnapshot_create_delete(self): |
| 140 | 141 | self.consistencygroups_adm_client.create_cgsnapshot) |
| 141 | 142 | cgsnapshot = create_cgsnapshot(cg['id'], |
| 142 | 143 | name=cgsnapshot_name)['cgsnapshot'] |
| 143 | snapshots = self.admin_snapshots_client.list_snapshots( | |
| 144 | snapshots = self.os_admin.snapshots_v2_client.list_snapshots( | |
| 144 | 145 | detail=True)['snapshots'] |
| 145 | 146 | for snap in snapshots: |
| 146 | 147 | if volume['id'] == snap['volume_id']: |
| 147 | 148 | waiters.wait_for_volume_resource_status( |
| 148 | self.admin_snapshots_client, snap['id'], 'available') | |
| 149 | self.os_admin.snapshots_v2_client, | |
| 150 | snap['id'], 'available') | |
| 149 | 151 | self.consistencygroups_adm_client.wait_for_cgsnapshot_status( |
| 150 | 152 | cgsnapshot['id'], 'available') |
| 151 | 153 | self.assertEqual(cgsnapshot_name, cgsnapshot['name']) |
| 204 | 206 | for snap in snapshots: |
| 205 | 207 | if volume['id'] == snap['volume_id']: |
| 206 | 208 | waiters.wait_for_volume_resource_status( |
| 207 | self.admin_snapshots_client, snap['id'], 'available') | |
| 209 | self.os_admin.snapshots_v2_client, snap['id'], 'available') | |
| 208 | 210 | self.consistencygroups_adm_client.wait_for_cgsnapshot_status( |
| 209 | 211 | cgsnapshot['id'], 'available') |
| 210 | 212 | self.assertEqual(cgsnapshot_name, cgsnapshot['name']) |
| 12 | 12 | # License for the specific language governing permissions and limitations |
| 13 | 13 | # under the License. |
| 14 | 14 | |
| 15 | from tempest.api.volume import base as volume_base | |
| 16 | 15 | from tempest.common import waiters |
| 17 | 16 | from tempest import config |
| 18 | 17 | from tempest.lib.common.utils import data_utils |
| 19 | 18 | from tempest.lib import decorators |
| 20 | 19 | |
| 20 | from cinder.tests.tempest.api.volume import base | |
| 21 | ||
| 21 | 22 | CONF = config.CONF |
| 22 | 23 | |
| 23 | 24 | |
| 24 | class VolumesBackupsTest(volume_base.BaseVolumeTest): | |
| 25 | class VolumesBackupsTest(base.BaseVolumeTest): | |
| 25 | 26 | |
| 26 | 27 | @classmethod |
| 27 | 28 | def skip_checks(cls): |
| 106 | 107 | wait_until='ACTIVE') |
| 107 | 108 | |
| 108 | 109 | # Delete VM |
| 109 | self.servers_client.delete_server(server['id']) | |
| 110 | self.os_primary.servers_client.delete_server(server['id']) | |
| 110 | 111 | # Create incremental backup |
| 111 | 112 | waiters.wait_for_volume_resource_status(self.volumes_client, |
| 112 | 113 | volume['id'], 'available') |
| 12 | 12 | # License for the specific language governing permissions and limitations |
| 13 | 13 | # under the License. |
| 14 | 14 | |
| 15 | from tempest.api.volume import base as volume_base | |
| 16 | 15 | from tempest.common import waiters |
| 17 | 16 | from tempest import config |
| 18 | 17 | from tempest.lib import decorators |
| 19 | 18 | |
| 19 | from cinder.tests.tempest.api.volume import base | |
| 20 | 20 | from cinder.tests.tempest import cinder_clients |
| 21 | 21 | |
| 22 | 22 | CONF = config.CONF |
| 23 | 23 | |
| 24 | 24 | |
| 25 | class VolumeRevertTests(volume_base.BaseVolumeTest): | |
| 25 | class VolumeRevertTests(base.BaseVolumeTest): | |
| 26 | 26 | min_microversion = '3.40' |
| 27 | 27 | |
| 28 | 28 | @classmethod |
| 13 | 13 | # License for the specific language governing permissions and limitations |
| 14 | 14 | # under the License. |
| 15 | 15 | |
| 16 | from tempest.api.volume import base as volume_base | |
| 17 | 16 | from tempest.common import waiters |
| 18 | 17 | from tempest import config |
| 19 | 18 | from tempest.lib.common.utils import data_utils |
| 19 | from tempest.lib.common.utils import test_utils | |
| 20 | ||
| 21 | from cinder.tests.tempest.api.volume import base | |
| 20 | 22 | |
| 21 | 23 | CONF = config.CONF |
| 22 | 24 | |
| 23 | 25 | |
| 24 | class CinderUnicodeTest(volume_base.BaseVolumeTest): | |
| 26 | class CinderUnicodeTest(base.BaseVolumeTest): | |
| 25 | 27 | |
| 26 | 28 | @classmethod |
| 27 | 29 | def resource_setup(cls): |
| 41 | 43 | kwargs['size'] = CONF.volume.volume_size |
| 42 | 44 | |
| 43 | 45 | volume = cls.volumes_client.create_volume(**kwargs)['volume'] |
| 44 | cls.volumes.append(volume) | |
| 45 | ||
| 46 | cls.addClassResourceCleanup( | |
| 47 | cls.volumes_client.wait_for_resource_deletion, volume['id']) | |
| 48 | cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc, | |
| 49 | cls.volumes_client.delete_volume, | |
| 50 | volume['id']) | |
| 46 | 51 | waiters.wait_for_volume_resource_status(cls.volumes_client, |
| 47 | 52 | volume['id'], |
| 48 | 53 | 'available') |
| 52 | 57 | def test_create_delete_unicode_volume_name(self): |
| 53 | 58 | """Create a volume with a unicode name and view it.""" |
| 54 | 59 | |
| 55 | result = self.volumes_client.show_volume(self.volumes[0]['id']) | |
| 60 | result = self.volumes_client.show_volume(self.volume['id']) | |
| 56 | 61 | fetched_volume = result['volume'] |
| 57 | 62 | self.assertEqual(fetched_volume['name'], |
| 58 | 63 | self.volume_name) |