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
This commit is contained in:
ghanshyam
2018-01-12 07:49:15 +00:00
parent 7557925ad8
commit dae4b6df5f
5 changed files with 199 additions and 21 deletions

View File

@@ -0,0 +1,170 @@
# Copyright 2017 NEC Corporation.
# 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 api_microversion_fixture
from tempest.common import compute
from tempest.common import waiters
from tempest import config
from tempest.lib.common import api_version_utils
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions
from tempest import test
CONF = config.CONF
class BaseVolumeTest(api_version_utils.BaseMicroversionTest,
test.BaseTestCase):
"""Base test case class for all Cinder API tests."""
_api_version = 2
credentials = ['primary']
@classmethod
def skip_checks(cls):
super(BaseVolumeTest, cls).skip_checks()
if not CONF.service_available.cinder:
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
raise cls.skipException(skip_msg)
if cls._api_version == 2:
if not CONF.volume_feature_enabled.api_v2:
msg = "Volume API v2 is disabled"
raise cls.skipException(msg)
elif cls._api_version == 3:
if not CONF.volume_feature_enabled.api_v3:
msg = "Volume API v3 is disabled"
raise cls.skipException(msg)
else:
msg = ("Invalid Cinder API version (%s)" % cls._api_version)
raise exceptions.InvalidConfiguration(msg)
api_version_utils.check_skip_with_microversion(
cls.min_microversion, cls.max_microversion,
CONF.volume.min_microversion, CONF.volume.max_microversion)
@classmethod
def setup_clients(cls):
super(BaseVolumeTest, cls).setup_clients()
if cls._api_version == 3:
cls.backups_client = cls.os_primary.backups_v3_client
cls.volumes_client = cls.os_primary.volumes_v3_client
else:
cls.backups_client = cls.os_primary.backups_v2_client
cls.volumes_client = cls.os_primary.volumes_v2_client
cls.snapshots_client = cls.os_primary.snapshots_v2_client
@classmethod
def setup_credentials(cls):
cls.set_network_resources()
super(BaseVolumeTest, cls).setup_credentials()
def setUp(self):
super(BaseVolumeTest, self).setUp()
self.useFixture(api_microversion_fixture.APIMicroversionFixture(
self.request_microversion))
@classmethod
def resource_setup(cls):
super(BaseVolumeTest, cls).resource_setup()
cls.request_microversion = (
api_version_utils.select_request_microversion(
cls.min_microversion,
CONF.volume.min_microversion))
@classmethod
def create_volume(cls, wait_until='available', **kwargs):
"""Wrapper utility that returns a test volume.
:param wait_until: wait till volume status.
"""
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'])
waiters.wait_for_volume_resource_status(cls.volumes_client,
volume['id'], wait_until)
return volume
@classmethod
def create_snapshot(cls, volume_id=1, **kwargs):
"""Wrapper utility that returns a test snapshot."""
if 'name' not in kwargs:
name = data_utils.rand_name(cls.__name__ + '-Snapshot')
kwargs['name'] = name
snapshot = cls.snapshots_client.create_snapshot(
volume_id=volume_id, **kwargs)['snapshot']
cls.addClassResourceCleanup(
cls.snapshots_client.wait_for_resource_deletion, snapshot['id'])
cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
cls.snapshots_client.delete_snapshot,
snapshot['id'])
waiters.wait_for_volume_resource_status(cls.snapshots_client,
snapshot['id'], 'available')
return snapshot
def create_backup(self, volume_id, backup_client=None, **kwargs):
"""Wrapper utility that returns a test backup."""
if backup_client is None:
backup_client = self.backups_client
if 'name' not in kwargs:
name = data_utils.rand_name(self.__class__.__name__ + '-Backup')
kwargs['name'] = name
backup = backup_client.create_backup(
volume_id=volume_id, **kwargs)['backup']
self.addCleanup(backup_client.delete_backup, backup['id'])
waiters.wait_for_volume_resource_status(backup_client, backup['id'],
'available')
return backup
def create_server(self, wait_until='ACTIVE', **kwargs):
name = kwargs.pop(
'name',
data_utils.rand_name(self.__class__.__name__ + '-instance'))
tenant_network = self.get_tenant_network()
body, _ = compute.create_test_server(
self.os_primary,
tenant_network=tenant_network,
name=name,
wait_until=wait_until,
**kwargs)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
waiters.wait_for_server_termination,
self.os_primary.servers_client, body['id'])
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.os_primary.servers_client.delete_server,
body['id'])
return body

View File

@@ -14,23 +14,23 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from tempest.api.volume import base
from tempest.common import waiters from tempest.common import waiters
from tempest import config from tempest import config
from tempest.lib.common.utils import data_utils from tempest.lib.common.utils import data_utils
from tempest.lib import decorators from tempest.lib import decorators
from cinder.tests.tempest.api.volume import base
from cinder.tests.tempest import cinder_clients from cinder.tests.tempest import cinder_clients
CONF = config.CONF CONF = config.CONF
class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest): class ConsistencyGroupsV2Test(base.BaseVolumeTest):
@classmethod @classmethod
def setup_clients(cls): def setup_clients(cls):
cls._api_version = 2 cls._api_version = 2
super(ConsistencyGroupsV2Test, cls).setup_clients() super(ConsistencyGroupsV2Test, cls).setup_clients()
cls.admin_volume_client = cls.os_admin.volumes_v2_client
manager = cinder_clients.Manager(cls.os_admin) manager = cinder_clients.Manager(cls.os_admin)
cls.consistencygroups_adm_client = manager.consistencygroups_adm_client cls.consistencygroups_adm_client = manager.consistencygroups_adm_client
@@ -54,14 +54,14 @@ class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest):
def _delete_cgsnapshot(self, cgsnapshot_id, cg_id): def _delete_cgsnapshot(self, cgsnapshot_id, cg_id):
self.consistencygroups_adm_client.delete_cgsnapshot(cgsnapshot_id) self.consistencygroups_adm_client.delete_cgsnapshot(cgsnapshot_id)
vols = self.admin_volume_client.list_volumes(detail=True)['volumes'] vols = self.admin_volume_client.list_volumes(detail=True)['volumes']
snapshots = self.admin_snapshots_client.list_snapshots( snapshots = self.os_admin.snapshots_v2_client.list_snapshots(
detail=True)['snapshots'] detail=True)['snapshots']
for vol in vols: for vol in vols:
for snap in snapshots: for snap in snapshots:
if (vol['consistencygroup_id'] == cg_id and if (vol['consistencygroup_id'] == cg_id and
vol['id'] == snap['volume_id']): vol['id'] == snap['volume_id']):
self.snapshots_client.wait_for_resource_deletion( (self.snapshots_client.
snap['id']) wait_for_resource_deletion(snap['id']))
self.consistencygroups_adm_client.wait_for_cgsnapshot_deletion( self.consistencygroups_adm_client.wait_for_cgsnapshot_deletion(
cgsnapshot_id) cgsnapshot_id)
@@ -69,7 +69,7 @@ class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest):
def test_consistencygroup_create_delete(self): def test_consistencygroup_create_delete(self):
# Create volume type # Create volume type
name = data_utils.rand_name("volume-type") name = data_utils.rand_name("volume-type")
volume_type = self.admin_volume_types_client.create_volume_type( volume_type = self.os_admin.volume_types_v2_client.create_volume_type(
name=name)['volume_type'] name=name)['volume_type']
# Create CG # Create CG
@@ -106,7 +106,8 @@ class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest):
# Clean up # Clean up
self._delete_consistencygroup(cg['id']) self._delete_consistencygroup(cg['id'])
self.admin_volume_types_client.delete_volume_type(volume_type['id']) self.os_admin.volume_types_v2_client.delete_volume_type(
volume_type['id'])
@decorators.idempotent_id('2134dd52-f333-4456-bb05-6cb0f009a44f') @decorators.idempotent_id('2134dd52-f333-4456-bb05-6cb0f009a44f')
def test_consistencygroup_cgsnapshot_create_delete(self): def test_consistencygroup_cgsnapshot_create_delete(self):
@@ -141,12 +142,13 @@ class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest):
self.consistencygroups_adm_client.create_cgsnapshot) self.consistencygroups_adm_client.create_cgsnapshot)
cgsnapshot = create_cgsnapshot(cg['id'], cgsnapshot = create_cgsnapshot(cg['id'],
name=cgsnapshot_name)['cgsnapshot'] name=cgsnapshot_name)['cgsnapshot']
snapshots = self.admin_snapshots_client.list_snapshots( snapshots = self.os_admin.snapshots_v2_client.list_snapshots(
detail=True)['snapshots'] detail=True)['snapshots']
for snap in snapshots: for snap in snapshots:
if volume['id'] == snap['volume_id']: if volume['id'] == snap['volume_id']:
waiters.wait_for_volume_resource_status( waiters.wait_for_volume_resource_status(
self.admin_snapshots_client, snap['id'], 'available') self.os_admin.snapshots_v2_client,
snap['id'], 'available')
self.consistencygroups_adm_client.wait_for_cgsnapshot_status( self.consistencygroups_adm_client.wait_for_cgsnapshot_status(
cgsnapshot['id'], 'available') cgsnapshot['id'], 'available')
self.assertEqual(cgsnapshot_name, cgsnapshot['name']) self.assertEqual(cgsnapshot_name, cgsnapshot['name'])
@@ -205,7 +207,7 @@ class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest):
for snap in snapshots: for snap in snapshots:
if volume['id'] == snap['volume_id']: if volume['id'] == snap['volume_id']:
waiters.wait_for_volume_resource_status( waiters.wait_for_volume_resource_status(
self.admin_snapshots_client, snap['id'], 'available') self.os_admin.snapshots_v2_client, snap['id'], 'available')
self.consistencygroups_adm_client.wait_for_cgsnapshot_status( self.consistencygroups_adm_client.wait_for_cgsnapshot_status(
cgsnapshot['id'], 'available') cgsnapshot['id'], 'available')
self.assertEqual(cgsnapshot_name, cgsnapshot['name']) self.assertEqual(cgsnapshot_name, cgsnapshot['name'])

View File

@@ -13,16 +13,17 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from tempest.api.volume import base as volume_base
from tempest.common import waiters from tempest.common import waiters
from tempest import config from tempest import config
from tempest.lib.common.utils import data_utils from tempest.lib.common.utils import data_utils
from tempest.lib import decorators from tempest.lib import decorators
from cinder.tests.tempest.api.volume import base
CONF = config.CONF CONF = config.CONF
class VolumesBackupsTest(volume_base.BaseVolumeTest): class VolumesBackupsTest(base.BaseVolumeTest):
@classmethod @classmethod
def skip_checks(cls): def skip_checks(cls):
@@ -107,7 +108,7 @@ class VolumesBackupsTest(volume_base.BaseVolumeTest):
wait_until='ACTIVE') wait_until='ACTIVE')
# Delete VM # Delete VM
self.servers_client.delete_server(server['id']) self.os_primary.servers_client.delete_server(server['id'])
# Create incremental backup # Create incremental backup
waiters.wait_for_volume_resource_status(self.volumes_client, waiters.wait_for_volume_resource_status(self.volumes_client,
volume['id'], 'available') volume['id'], 'available')

View File

@@ -13,17 +13,17 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from tempest.api.volume import base as volume_base
from tempest.common import waiters from tempest.common import waiters
from tempest import config from tempest import config
from tempest.lib import decorators from tempest.lib import decorators
from cinder.tests.tempest.api.volume import base
from cinder.tests.tempest import cinder_clients from cinder.tests.tempest import cinder_clients
CONF = config.CONF CONF = config.CONF
class VolumeRevertTests(volume_base.BaseVolumeTest): class VolumeRevertTests(base.BaseVolumeTest):
min_microversion = '3.40' min_microversion = '3.40'
@classmethod @classmethod

View File

@@ -14,15 +14,17 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from tempest.api.volume import base as volume_base
from tempest.common import waiters from tempest.common import waiters
from tempest import config from tempest import config
from tempest.lib.common.utils import data_utils from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from cinder.tests.tempest.api.volume import base
CONF = config.CONF CONF = config.CONF
class CinderUnicodeTest(volume_base.BaseVolumeTest): class CinderUnicodeTest(base.BaseVolumeTest):
@classmethod @classmethod
def resource_setup(cls): def resource_setup(cls):
@@ -42,8 +44,11 @@ class CinderUnicodeTest(volume_base.BaseVolumeTest):
kwargs['size'] = CONF.volume.volume_size kwargs['size'] = CONF.volume.volume_size
volume = cls.volumes_client.create_volume(**kwargs)['volume'] volume = cls.volumes_client.create_volume(**kwargs)['volume']
cls.volumes.append(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'])
waiters.wait_for_volume_resource_status(cls.volumes_client, waiters.wait_for_volume_resource_status(cls.volumes_client,
volume['id'], volume['id'],
'available') 'available')
@@ -53,7 +58,7 @@ class CinderUnicodeTest(volume_base.BaseVolumeTest):
def test_create_delete_unicode_volume_name(self): def test_create_delete_unicode_volume_name(self):
"""Create a volume with a unicode name and view it.""" """Create a volume with a unicode name and view it."""
result = self.volumes_client.show_volume(self.volumes[0]['id']) result = self.volumes_client.show_volume(self.volume['id'])
fetched_volume = result['volume'] fetched_volume = result['volume']
self.assertEqual(fetched_volume['name'], self.assertEqual(fetched_volume['name'],
self.volume_name) self.volume_name)