Remove In-repo cinder tempest plugin

As part of Queens Goal "Split Tempest Plugins into Separate
Repos/Projects",the cinder tempest plugin needs to be split
into a separate project.
https://governance.openstack.org/tc/goals/queens/split-tempest-plugins.html

This patch removes the in-tree tempest plugin as well as the
setuptools entry point.

Change-Id: I5ff95ca13f02ed6e0afb35f0d6bb5c36d4111f5a
Depends-On: Ib309cb1f87211e82eae0d27fa2464ec13a9deca6
Implements: blueprint goal-split-tempest-plugin
This commit is contained in:
Nishant Kumar 2017-07-25 13:11:41 -04:00 committed by Sean McGinnis
parent 019d9c75f7
commit bcec744c45
16 changed files with 0 additions and 960 deletions

View File

@ -1,61 +0,0 @@
===============================================
Tempest Integration for Cinder
===============================================
This directory contains additional Cinder tempest tests.
See the tempest plugin docs for information on using it:
https://docs.openstack.org/tempest/latest/plugin.html#using-plugins
To run all tests from this plugin, install cinder into your environment. Then
from the tempest directory run::
$ tox -e all-plugin -- volume
It is expected that Cinder third party CI's use the all-plugin tox environment
above for all test runs. Developers can also use this locally to perform more
extensive testing.
Any typical devstack instance should be able to run all Cinder plugin tests.
For completeness, here is an example of a devstack local.conf that should
work. Update backend information to fit your environment.
::
[[local|localrc]]
VIRT_DRIVER=libvirt
ADMIN_PASSWORD=secret
SERVICE_TOKEN=$ADMIN_PASSWORD
MYSQL_PASSWORD=$ADMIN_PASSWORD
RABBIT_PASSWORD=$ADMIN_PASSWORD
SERVICE_PASSWORD=$ADMIN_PASSWORD
LOGFILE=$DEST/logs/stack.sh.log
LOGDAYS=2
SYSLOG=False
LOG_COLOR=False
RECLONE=yes
ENABLED_SERVICES=c-api,c-sch,c-vol,cinder,dstat,g-api,g-reg,key,mysql,
n-api,n-cond,n-cpu,n-crt,n-net,n-sch,rabbit,tempest
CINDER_ENABLED_BACKENDS=lvmdriver-1
CINDER_DEFAULT_VOLUME_TYPE=lvmdriver-1
CINDER_VOLUME_CLEAR=none
TEMPEST_ENABLED_BACKENDS=lvmdriver-1
TEMPEST_VOLUME_DRIVER=lvmdriver-1
TEMPEST_VOLUME_VENDOR="Open Source"
TEMPEST_STORAGE_PROTOCOL=iSCSI
LIBVIRT_FIREWALL_DRIVER=nova.virt.firewall.NoopFirewallDriver
VIRT_DRIVER=libvirt
ACTIVE_TIMEOUT=120
BOOT_TIMEOUT=120
ASSOCIATE_TIMEOUT=120
TERMINATE_TIMEOUT=120
[[post-config|$CINDER_CONF]]
[DEFAULT]
[lvmdriver-1]
volume_driver=cinder.volume.drivers.lvm.LVMISCSIDriver
volume_group=stack-volumes-1
volume_backend_name=lvmdriver-1``

View File

@ -1,281 +0,0 @@
# Copyright (C) 2015 EMC Corporation.
# Copyright (C) 2016 Pure Storage, 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.api.volume import base
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from cinder.tests.tempest import cinder_clients
CONF = config.CONF
class ConsistencyGroupsV2Test(base.BaseVolumeAdminTest):
@classmethod
def setup_clients(cls):
cls._api_version = 2
super(ConsistencyGroupsV2Test, cls).setup_clients()
manager = cinder_clients.Manager(cls.os_admin)
cls.consistencygroups_adm_client = manager.consistencygroups_adm_client
@classmethod
def skip_checks(cls):
super(ConsistencyGroupsV2Test, cls).skip_checks()
if not CONF.volume_feature_enabled.consistency_group:
raise cls.skipException("Cinder consistency group "
"feature disabled")
def _delete_consistencygroup(self, cg_id):
self.consistencygroups_adm_client.delete_consistencygroup(cg_id)
vols = self.admin_volume_client.list_volumes(detail=True)['volumes']
for vol in vols:
if vol['consistencygroup_id'] == cg_id:
self.admin_volume_client.wait_for_resource_deletion(vol['id'])
self.consistencygroups_adm_client.wait_for_consistencygroup_deletion(
cg_id)
def _delete_cgsnapshot(self, cgsnapshot_id, cg_id):
self.consistencygroups_adm_client.delete_cgsnapshot(cgsnapshot_id)
vols = self.admin_volume_client.list_volumes(detail=True)['volumes']
snapshots = self.admin_snapshots_client.list_snapshots(
detail=True)['snapshots']
for vol in vols:
for snap in snapshots:
if (vol['consistencygroup_id'] == cg_id and
vol['id'] == snap['volume_id']):
self.snapshots_client.wait_for_resource_deletion(
snap['id'])
self.consistencygroups_adm_client.wait_for_cgsnapshot_deletion(
cgsnapshot_id)
@decorators.idempotent_id('3fe776ba-ec1f-4e6c-8d78-4b14c3a7fc44')
def test_consistencygroup_create_delete(self):
# Create volume type
name = data_utils.rand_name("volume-type")
volume_type = self.admin_volume_types_client.create_volume_type(
name=name)['volume_type']
# Create CG
cg_name = data_utils.rand_name('CG')
create_consistencygroup = (
self.consistencygroups_adm_client.create_consistencygroup)
cg = create_consistencygroup(volume_type['id'],
name=cg_name)['consistencygroup']
vol_name = data_utils.rand_name("volume")
params = {'name': vol_name,
'volume_type': volume_type['id'],
'consistencygroup_id': cg['id'],
'size': CONF.volume.volume_size}
# Create volume
volume = self.admin_volume_client.create_volume(**params)['volume']
waiters.wait_for_volume_resource_status(self.admin_volume_client,
volume['id'], 'available')
self.consistencygroups_adm_client.wait_for_consistencygroup_status(
cg['id'], 'available')
self.assertEqual(cg_name, cg['name'])
# Get a given CG
cg = self.consistencygroups_adm_client.show_consistencygroup(
cg['id'])['consistencygroup']
self.assertEqual(cg_name, cg['name'])
# Get all CGs with detail
cgs = self.consistencygroups_adm_client.list_consistencygroups(
detail=True)['consistencygroups']
self.assertIn((cg['name'], cg['id']),
[(m['name'], m['id']) for m in cgs])
# Clean up
self._delete_consistencygroup(cg['id'])
self.admin_volume_types_client.delete_volume_type(volume_type['id'])
@decorators.idempotent_id('2134dd52-f333-4456-bb05-6cb0f009a44f')
def test_consistencygroup_cgsnapshot_create_delete(self):
# Create volume type
name = data_utils.rand_name("volume-type")
volume_type = self.admin_volume_types_client.create_volume_type(
name=name)['volume_type']
# Create CG
cg_name = data_utils.rand_name('CG')
create_consistencygroup = (
self.consistencygroups_adm_client.create_consistencygroup)
cg = create_consistencygroup(volume_type['id'],
name=cg_name)['consistencygroup']
vol_name = data_utils.rand_name("volume")
params = {'name': vol_name,
'volume_type': volume_type['id'],
'consistencygroup_id': cg['id'],
'size': CONF.volume.volume_size}
# Create volume
volume = self.admin_volume_client.create_volume(**params)['volume']
waiters.wait_for_volume_resource_status(self.admin_volume_client,
volume['id'], 'available')
self.consistencygroups_adm_client.wait_for_consistencygroup_status(
cg['id'], 'available')
self.assertEqual(cg_name, cg['name'])
# Create cgsnapshot
cgsnapshot_name = data_utils.rand_name('cgsnapshot')
create_cgsnapshot = (
self.consistencygroups_adm_client.create_cgsnapshot)
cgsnapshot = create_cgsnapshot(cg['id'],
name=cgsnapshot_name)['cgsnapshot']
snapshots = self.admin_snapshots_client.list_snapshots(
detail=True)['snapshots']
for snap in snapshots:
if volume['id'] == snap['volume_id']:
waiters.wait_for_volume_resource_status(
self.admin_snapshots_client, snap['id'], 'available')
self.consistencygroups_adm_client.wait_for_cgsnapshot_status(
cgsnapshot['id'], 'available')
self.assertEqual(cgsnapshot_name, cgsnapshot['name'])
# Get a given CG snapshot
cgsnapshot = self.consistencygroups_adm_client.show_cgsnapshot(
cgsnapshot['id'])['cgsnapshot']
self.assertEqual(cgsnapshot_name, cgsnapshot['name'])
# Get all CG snapshots with detail
cgsnapshots = self.consistencygroups_adm_client.list_cgsnapshots(
detail=True)['cgsnapshots']
self.assertIn((cgsnapshot['name'], cgsnapshot['id']),
[(m['name'], m['id']) for m in cgsnapshots])
# Clean up
self._delete_cgsnapshot(cgsnapshot['id'], cg['id'])
self._delete_consistencygroup(cg['id'])
self.admin_volume_types_client.delete_volume_type(volume_type['id'])
@decorators.idempotent_id('3a6a5525-25ca-4a6c-aac4-cac6fa8f5b43')
def test_create_consistencygroup_from_cgsnapshot(self):
# Create volume type
name = data_utils.rand_name("volume-type")
volume_type = self.admin_volume_types_client.create_volume_type(
name=name)['volume_type']
# Create CG
cg_name = data_utils.rand_name('CG')
create_consistencygroup = (
self.consistencygroups_adm_client.create_consistencygroup)
cg = create_consistencygroup(volume_type['id'],
name=cg_name)['consistencygroup']
vol_name = data_utils.rand_name("volume")
params = {'name': vol_name,
'volume_type': volume_type['id'],
'consistencygroup_id': cg['id'],
'size': CONF.volume.volume_size}
# Create volume
volume = self.admin_volume_client.create_volume(**params)['volume']
waiters.wait_for_volume_resource_status(self.admin_volume_client,
volume['id'], 'available')
self.consistencygroups_adm_client.wait_for_consistencygroup_status(
cg['id'], 'available')
self.assertEqual(cg_name, cg['name'])
# Create cgsnapshot
cgsnapshot_name = data_utils.rand_name('cgsnapshot')
create_cgsnapshot = (
self.consistencygroups_adm_client.create_cgsnapshot)
cgsnapshot = create_cgsnapshot(cg['id'],
name=cgsnapshot_name)['cgsnapshot']
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.admin_snapshots_client, snap['id'], 'available')
self.consistencygroups_adm_client.wait_for_cgsnapshot_status(
cgsnapshot['id'], 'available')
self.assertEqual(cgsnapshot_name, cgsnapshot['name'])
# Create CG from CG snapshot
cg_name2 = data_utils.rand_name('CG_from_snap')
create_consistencygroup2 = (
self.consistencygroups_adm_client.create_consistencygroup_from_src)
cg2 = create_consistencygroup2(cgsnapshot_id=cgsnapshot['id'],
name=cg_name2)['consistencygroup']
vols = self.admin_volume_client.list_volumes(
detail=True)['volumes']
for vol in vols:
if vol['consistencygroup_id'] == cg2['id']:
waiters.wait_for_volume_resource_status(
self.admin_volume_client, vol['id'], 'available')
self.consistencygroups_adm_client.wait_for_consistencygroup_status(
cg2['id'], 'available')
self.assertEqual(cg_name2, cg2['name'])
# Clean up
self._delete_consistencygroup(cg2['id'])
self._delete_cgsnapshot(cgsnapshot['id'], cg['id'])
self._delete_consistencygroup(cg['id'])
self.admin_volume_types_client.delete_volume_type(volume_type['id'])
@decorators.idempotent_id('556121ae-de9c-4342-9897-e54260447a19')
def test_create_consistencygroup_from_consistencygroup(self):
# Create volume type
name = data_utils.rand_name("volume-type")
volume_type = self.admin_volume_types_client.create_volume_type(
name=name)['volume_type']
# Create CG
cg_name = data_utils.rand_name('CG')
create_consistencygroup = (
self.consistencygroups_adm_client.create_consistencygroup)
cg = create_consistencygroup(volume_type['id'],
name=cg_name)['consistencygroup']
vol_name = data_utils.rand_name("volume")
params = {'name': vol_name,
'volume_type': volume_type['id'],
'consistencygroup_id': cg['id'],
'size': CONF.volume.volume_size}
# Create volume
volume = self.admin_volume_client.create_volume(**params)['volume']
waiters.wait_for_volume_resource_status(self.admin_volume_client,
volume['id'], 'available')
self.consistencygroups_adm_client.wait_for_consistencygroup_status(
cg['id'], 'available')
self.assertEqual(cg_name, cg['name'])
# Create CG from CG
cg_name2 = data_utils.rand_name('CG_from_cg')
create_consistencygroup2 = (
self.consistencygroups_adm_client.create_consistencygroup_from_src)
cg2 = create_consistencygroup2(source_cgid=cg['id'],
name=cg_name2)['consistencygroup']
vols = self.admin_volume_client.list_volumes(
detail=True)['volumes']
for vol in vols:
if vol['consistencygroup_id'] == cg2['id']:
waiters.wait_for_volume_resource_status(
self.admin_volume_client, vol['id'], 'available')
self.consistencygroups_adm_client.wait_for_consistencygroup_status(
cg2['id'], 'available')
self.assertEqual(cg_name2, cg2['name'])
# Clean up
self._delete_consistencygroup(cg2['id'])
self._delete_consistencygroup(cg['id'])
self.admin_volume_types_client.delete_volume_type(volume_type['id'])

View File

@ -1,129 +0,0 @@
# Copyright (c) 2016 Mirantis 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.api.volume import base as volume_base
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
CONF = config.CONF
class VolumesBackupsTest(volume_base.BaseVolumeTest):
@classmethod
def skip_checks(cls):
super(VolumesBackupsTest, cls).skip_checks()
if not CONF.volume_feature_enabled.backup:
raise cls.skipException("Cinder backup feature disabled")
@decorators.idempotent_id('885410c6-cd1d-452c-a409-7c32b7e0be15')
def test_volume_snapshot_backup(self):
"""Create backup from snapshot."""
volume = self.create_volume()
# Create snapshot
snapshot = self.create_snapshot(volume['id'])
# Create backup
backup = self.create_backup(
volume_id=volume['id'],
snapshot_id=snapshot['id'])
# Get a given backup
backup = self.backups_client.show_backup(
backup['id'])['backup']
waiters.wait_for_volume_resource_status(
self.backups_client,
backup['id'], 'available')
self.assertEqual(volume['id'], backup['volume_id'])
self.assertEqual(snapshot['id'], backup['snapshot_id'])
self.snapshots_client.delete_snapshot(snapshot['id'])
self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
self.volumes_client.delete_volume(volume['id'])
self.volumes_client.wait_for_resource_deletion(volume['id'])
@decorators.idempotent_id('b5d837b0-7066-455d-88fc-4a721a899306')
def test_backup_create_and_restore_to_an_existing_volume(self):
"""Test backup create and restore to an existing volume."""
# Create volume
src_vol = self.create_volume()
self.addCleanup(self.volumes_client.delete_volume,
src_vol['id'])
# Create backup
backup = self.backups_client.create_backup(
volume_id=src_vol['id'])['backup']
self.addCleanup(self.backups_client.delete_backup, backup['id'])
waiters.wait_for_volume_resource_status(
self.backups_client,
backup['id'], 'available')
# Restore to existing volume
restore = self.backups_client.restore_backup(
backup_id=backup['id'],
volume_id=src_vol['id'])['restore']
waiters.wait_for_volume_resource_status(
self.backups_client,
backup['id'], 'available')
waiters.wait_for_volume_resource_status(
self.volumes_client,
src_vol['id'], 'available')
self.assertEqual(src_vol['id'], restore['volume_id'])
self.assertEqual(backup['id'], restore['backup_id'])
@decorators.idempotent_id('c810fe2c-cb40-43ab-96aa-471b74516a98')
def test_incremental_backup(self):
"""Test create incremental backup."""
# Create volume from image
volume = self.create_volume(size=CONF.volume.volume_size,
imageRef=CONF.compute.image_ref)
self.addCleanup(self.volumes_client.delete_volume,
volume['id'])
# Create backup
backup = self.backups_client.create_backup(
volume_id=volume['id'])['backup']
waiters.wait_for_volume_resource_status(self.backups_client,
backup['id'], 'available')
# Create a server
bd_map = [{'volume_id': volume['id'],
'delete_on_termination': '0'}]
server_name = data_utils.rand_name('instance')
server = self.create_server(
name=server_name,
block_device_mapping=bd_map,
wait_until='ACTIVE')
# Delete VM
self.servers_client.delete_server(server['id'])
# Create incremental backup
waiters.wait_for_volume_resource_status(self.volumes_client,
volume['id'], 'available')
backup_incr = self.backups_client.create_backup(
volume_id=volume['id'],
incremental=True)['backup']
waiters.wait_for_volume_resource_status(self.backups_client,
backup_incr['id'],
'available')
is_incremental = self.backups_client.show_backup(
backup_incr['id'])['backup']['is_incremental']
self.assertTrue(is_incremental)
self.backups_client.delete_backup(backup_incr['id'])
self.backups_client.wait_for_resource_deletion(backup_incr['id'])
self.backups_client.delete_backup(backup['id'])
self.backups_client.wait_for_resource_deletion(backup['id'])

View File

@ -1,78 +0,0 @@
# Copyright (c) 2017 Huawei.
# 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 as volume_base
from tempest.common import waiters
from tempest import config
from tempest.lib import decorators
from cinder.api import microversions
from cinder.tests.tempest import cinder_clients
CONF = config.CONF
class VolumeRevertTests(volume_base.BaseVolumeTest):
min_microversion = microversions.VOLUME_REVERT
@classmethod
def setup_clients(cls):
cls._api_version = 3
super(VolumeRevertTests, cls).setup_clients()
manager = cinder_clients.Manager(cls.os_primary)
cls.volume_revert_client = manager.volume_revert_client
def setUp(self):
super(VolumeRevertTests, self).setUp()
# Create volume
self.volume = self.create_volume(size=1)
# Create snapshot
self.snapshot = self.create_snapshot(self.volume['id'])
@decorators.idempotent_id('87b7dcb7-4950-4a3a-802c-ece55491846d')
def test_volume_revert_to_snapshot(self):
"""Test revert to snapshot"""
# Revert to snapshot
self.volume_revert_client.revert_to_snapshot(self.volume,
self.snapshot['id'])
waiters.wait_for_volume_resource_status(
self.volumes_client,
self.volume['id'], 'available')
waiters.wait_for_volume_resource_status(
self.snapshots_client,
self.snapshot['id'], 'available')
volume = self.volumes_client.show_volume(self.volume['id'])['volume']
self.assertEqual(1, volume['size'])
@decorators.idempotent_id('4e8b0788-87fe-430d-be7a-444d7f8e0347')
def test_volume_revert_to_snapshot_after_extended(self):
"""Test revert to snapshot after extended"""
# Extend the volume
self.volumes_client.extend_volume(self.volume['id'], new_size=2)
waiters.wait_for_volume_resource_status(self.volumes_client,
self.volume['id'], 'available')
# Revert to snapshot
self.volume_revert_client.revert_to_snapshot(self.volume,
self.snapshot['id'])
waiters.wait_for_volume_resource_status(
self.volumes_client,
self.volume['id'], 'available')
waiters.wait_for_volume_resource_status(
self.snapshots_client,
self.snapshot['id'], 'available')
volume = self.volumes_client.show_volume(self.volume['id'])['volume']
self.assertEqual(2, volume['size'])

View File

@ -1,76 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2016 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.api.volume import base as volume_base
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
import testtools
CONF = config.CONF
class CinderUnicodeTest(volume_base.BaseVolumeTest):
@classmethod
def resource_setup(cls):
super(CinderUnicodeTest, cls).resource_setup()
# Stick to three-byte unicode here, since four+ byte
# chars require utf8mb4 database support which may not
# be configured.
cls.volume_name = u"CinderUnicodeTest塵㼗‽"
cls.volume = cls.create_volume_with_args(name=cls.volume_name)
@classmethod
def create_volume_with_args(cls, **kwargs):
if 'name' not in kwargs:
kwargs['name'] = data_utils.rand_name('Volume')
kwargs['size'] = CONF.volume.volume_size
volume = cls.volumes_client.create_volume(**kwargs)['volume']
cls.volumes.append(volume)
waiters.wait_for_volume_resource_status(cls.volumes_client,
volume['id'],
'available')
return volume
def test_create_delete_unicode_volume_name(self):
"""Create a volume with a unicode name and view it."""
result = self.volumes_client.show_volume(self.volumes[0]['id'])
fetched_volume = result['volume']
self.assertEqual(fetched_volume['name'],
self.volume_name)
@testtools.skipUnless(CONF.volume_feature_enabled.snapshot,
"Cinder volume snapshots are disabled")
def test_snapshot_create_volume_description_non_ascii_code(self):
# Create a volume with non-ascii description
description = u'\u05e7\u05d9\u05d9\u05e4\u05e9'
volume = self.create_volume(description=description)
vol_info = self.volumes_client.show_volume(volume['id'])['volume']
self.assertEqual(description, vol_info['description'])
# Create a snapshot with different non-ascii description
description = u'\u4e2d\u56fd\u793e\u533a'
snapshot = self.create_snapshot(volume['id'], description=description)
snapshot_info = self.snapshots_client.show_snapshot(
snapshot['id'])['snapshot']
self.assertEqual(description, snapshot_info['description'])

View File

@ -1,40 +0,0 @@
# Copyright (c) 2016 Pure Storage, 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 cinder.tests.tempest.services import consistencygroups_client
from cinder.tests.tempest.services import volume_revert_client
CONF = config.CONF
class Manager(object):
def __init__(self, base_manager):
params = {
'service': CONF.volume.catalog_type,
'region': CONF.volume.region or CONF.identity.region,
'endpoint_type': CONF.volume.endpoint_type,
'build_interval': CONF.volume.build_interval,
'build_timeout': CONF.volume.build_timeout
}
params.update(base_manager.default_params)
auth_provider = base_manager.auth_provider
self.consistencygroups_adm_client = (
consistencygroups_client.ConsistencyGroupsClient(auth_provider,
**params))
self.volume_revert_client = (
volume_revert_client.VolumeRevertClient(auth_provider, **params))

View File

@ -1,22 +0,0 @@
# Copyright 2016
# 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 oslo_config import cfg
cinder_option = [
cfg.BoolOpt('consistency_group',
default=False,
help='Enable to run Cinder volume consistency group tests'),
]

View File

@ -1,43 +0,0 @@
# Copyright 2015
# 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.
import cinder
import os
from cinder.tests.tempest import opts as project_opts
from tempest import config
from tempest.test_discover import plugins
class CinderTempestPlugin(plugins.TempestPlugin):
def load_tests(self):
base_path = os.path.split(os.path.dirname(
os.path.abspath(cinder.__file__)))[0]
test_dir = "cinder/tests/tempest"
full_test_dir = os.path.join(base_path, test_dir)
return full_test_dir, base_path
def register_opts(self, conf):
config.register_opt_group(
conf, config.volume_feature_group,
project_opts.cinder_option
)
def get_opt_lists(self):
return [
(config.volume_feature_group.name,
project_opts.cinder_option),
]

View File

@ -1,193 +0,0 @@
# Copyright (C) 2015 EMC Corporation.
# Copyright (C) 2016 Pure Storage, 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.
import time
from oslo_serialization import jsonutils as json
from six.moves import http_client
from tempest import exceptions
from tempest.lib.common import rest_client
from tempest.lib import exceptions as lib_exc
class ConsistencyGroupsClient(rest_client.RestClient):
"""Client class to send CRUD Volume ConsistencyGroup API requests"""
def __init__(self, auth_provider, service, region, **kwargs):
super(ConsistencyGroupsClient, self).__init__(
auth_provider, service, region, **kwargs)
def create_consistencygroup(self, volume_types, **kwargs):
"""Creates a consistency group."""
post_body = {'volume_types': volume_types}
if kwargs.get('availability_zone'):
post_body['availability_zone'] = kwargs.get('availability_zone')
if kwargs.get('name'):
post_body['name'] = kwargs.get('name')
if kwargs.get('description'):
post_body['description'] = kwargs.get('description')
post_body = json.dumps({'consistencygroup': post_body})
resp, body = self.post('consistencygroups', post_body)
body = json.loads(body)
self.expected_success(http_client.ACCEPTED, resp.status)
return rest_client.ResponseBody(resp, body)
def create_consistencygroup_from_src(self, **kwargs):
"""Creates a consistency group from source."""
post_body = {}
if kwargs.get('cgsnapshot_id'):
post_body['cgsnapshot_id'] = kwargs.get('cgsnapshot_id')
if kwargs.get('source_cgid'):
post_body['source_cgid'] = kwargs.get('source_cgid')
if kwargs.get('name'):
post_body['name'] = kwargs.get('name')
if kwargs.get('description'):
post_body['description'] = kwargs.get('description')
post_body = json.dumps({'consistencygroup-from-src': post_body})
resp, body = self.post('consistencygroups/create_from_src', post_body)
body = json.loads(body)
self.expected_success(http_client.ACCEPTED, resp.status)
return rest_client.ResponseBody(resp, body)
def delete_consistencygroup(self, cg_id):
"""Delete a consistency group."""
post_body = {'force': True}
post_body = json.dumps({'consistencygroup': post_body})
resp, body = self.post('consistencygroups/%s/delete' % cg_id,
post_body)
self.expected_success(http_client.ACCEPTED, resp.status)
return rest_client.ResponseBody(resp, body)
def show_consistencygroup(self, cg_id):
"""Returns the details of a single consistency group."""
url = "consistencygroups/%s" % str(cg_id)
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(http_client.OK, resp.status)
return rest_client.ResponseBody(resp, body)
def list_consistencygroups(self, detail=False):
"""Information for all the tenant's consistency groups."""
url = "consistencygroups"
if detail:
url += "/detail"
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(http_client.OK, resp.status)
return rest_client.ResponseBody(resp, body)
def create_cgsnapshot(self, consistencygroup_id, **kwargs):
"""Creates a consistency group snapshot."""
post_body = {'consistencygroup_id': consistencygroup_id}
if kwargs.get('name'):
post_body['name'] = kwargs.get('name')
if kwargs.get('description'):
post_body['description'] = kwargs.get('description')
post_body = json.dumps({'cgsnapshot': post_body})
resp, body = self.post('cgsnapshots', post_body)
body = json.loads(body)
self.expected_success(http_client.ACCEPTED, resp.status)
return rest_client.ResponseBody(resp, body)
def delete_cgsnapshot(self, cgsnapshot_id):
"""Delete a consistency group snapshot."""
resp, body = self.delete('cgsnapshots/%s' % (str(cgsnapshot_id)))
self.expected_success(http_client.ACCEPTED, resp.status)
return rest_client.ResponseBody(resp, body)
def show_cgsnapshot(self, cgsnapshot_id):
"""Returns the details of a single consistency group snapshot."""
url = "cgsnapshots/%s" % str(cgsnapshot_id)
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(http_client.OK, resp.status)
return rest_client.ResponseBody(resp, body)
def list_cgsnapshots(self, detail=False):
"""Information for all the tenant's consistency group snapshotss."""
url = "cgsnapshots"
if detail:
url += "/detail"
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(http_client.OK, resp.status)
return rest_client.ResponseBody(resp, body)
def wait_for_consistencygroup_status(self, cg_id, status):
"""Waits for a consistency group to reach a given status."""
body = self.show_consistencygroup(cg_id)['consistencygroup']
cg_status = body['status']
start = int(time.time())
while cg_status != status:
time.sleep(self.build_interval)
body = self.show_consistencygroup(cg_id)['consistencygroup']
cg_status = body['status']
if cg_status == 'error':
raise exceptions.ConsistencyGroupException(cg_id=cg_id)
if int(time.time()) - start >= self.build_timeout:
message = ('Consistency group %s failed to reach %s status '
'(current %s) within the required time (%s s).' %
(cg_id, status, cg_status,
self.build_timeout))
raise exceptions.TimeoutException(message)
def wait_for_consistencygroup_deletion(self, cg_id):
"""Waits for consistency group deletion"""
start_time = int(time.time())
while True:
try:
self.show_consistencygroup(cg_id)
except lib_exc.NotFound:
return
if int(time.time()) - start_time >= self.build_timeout:
raise exceptions.TimeoutException
time.sleep(self.build_interval)
def wait_for_cgsnapshot_status(self, cgsnapshot_id, status):
"""Waits for a consistency group snapshot to reach a given status."""
body = self.show_cgsnapshot(cgsnapshot_id)['cgsnapshot']
cgsnapshot_status = body['status']
start = int(time.time())
while cgsnapshot_status != status:
time.sleep(self.build_interval)
body = self.show_cgsnapshot(cgsnapshot_id)['cgsnapshot']
cgsnapshot_status = body['status']
if cgsnapshot_status == 'error':
raise exceptions.ConsistencyGroupSnapshotException(
cgsnapshot_id=cgsnapshot_id)
if int(time.time()) - start >= self.build_timeout:
message = ('Consistency group snapshot %s failed to reach '
'%s status (current %s) within the required time '
'(%s s).' %
(cgsnapshot_id, status, cgsnapshot_status,
self.build_timeout))
raise exceptions.TimeoutException(message)
def wait_for_cgsnapshot_deletion(self, cgsnapshot_id):
"""Waits for consistency group snapshot deletion"""
start_time = int(time.time())
while True:
try:
self.show_cgsnapshot(cgsnapshot_id)
except lib_exc.NotFound:
return
if int(time.time()) - start_time >= self.build_timeout:
raise exceptions.TimeoutException
time.sleep(self.build_interval)

View File

@ -1,34 +0,0 @@
# Copyright (C) 2017 Huawei.
# 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 oslo_serialization import jsonutils as json
from tempest.lib.common import rest_client
from tempest.lib.services.volume.v3 import base_client
class VolumeRevertClient(base_client.BaseClient):
"""Client class to send revert to snapshot action API request"""
def __init__(self, auth_provider, service, region, **kwargs):
super(VolumeRevertClient, self).__init__(
auth_provider, service, region, **kwargs)
def revert_to_snapshot(self, volume, snapshot_id):
"""Revert a volume to snapshot."""
post_body = {'snapshot_id': snapshot_id}
post_body = json.dumps({'revert': post_body})
resp, body = self.post('volumes/%s/action' % volume['id'],
post_body)
return rest_client.ResponseBody(resp, body)

View File

@ -82,9 +82,6 @@ oslo_middleware =
cinder.database.migration_backend =
sqlalchemy = oslo_db.sqlalchemy.migration
# In-tree Tempest test entry point
tempest.test_plugins =
cinder_tests = cinder.tests.tempest.plugin:CinderTempestPlugin
[build_sphinx]
all_files = 1