From f4fbf30742673c1dc5b9ee3346bfe5f574c0633c Mon Sep 17 00:00:00 2001 From: "jeremy.zhang" Date: Wed, 22 Mar 2017 11:25:53 +0800 Subject: [PATCH] Add test case for volume unmanage and manage Lots of Cinder backend drivers have support unmanage and manage features. It's necessary to add test case for these feature apis. Including: [1] Add volume manage client as library [2] Add unmanage volume api to v2 volumes client [3] Add release note [4] Add test case: test_volume_unmanage_manage Depends-On: I055aa66738deb5ae2fb925429cec565e3901340c Change-Id: I4294de92a801db2697ba870ff1b5fdbe4b2f5a4b --- ...ge-client-as-library-78ab198a1dc1bd41.yaml | 9 +++ .../api/volume/admin/v2/test_volume_manage.py | 81 +++++++++++++++++++ tempest/api/volume/base.py | 1 + tempest/clients.py | 1 + tempest/config.py | 9 +++ tempest/lib/services/volume/v2/__init__.py | 4 +- .../volume/v2/volume_manage_client.py | 37 +++++++++ .../lib/services/volume/v2/volumes_client.py | 12 +++ 8 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml create mode 100644 tempest/api/volume/admin/v2/test_volume_manage.py create mode 100644 tempest/lib/services/volume/v2/volume_manage_client.py diff --git a/releasenotes/notes/add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml b/releasenotes/notes/add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml new file mode 100644 index 0000000000..34530501b2 --- /dev/null +++ b/releasenotes/notes/add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + Add the unmanage volume API service method in v2 volumes_client library. + Define v2 volume_manage_client client for the volume service as library + interfaces, allowing other projects to use this module as stable libraries + without maintenance changes. + + * volume_manage_client(v2) diff --git a/tempest/api/volume/admin/v2/test_volume_manage.py b/tempest/api/volume/admin/v2/test_volume_manage.py new file mode 100644 index 0000000000..f983490784 --- /dev/null +++ b/tempest/api/volume/admin/v2/test_volume_manage.py @@ -0,0 +1,81 @@ +# Copyright 2017 FiberHome Telecommunication Technologies CO.,LTD +# 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 + +CONF = config.CONF + + +class VolumeManageAdminV2Test(base.BaseVolumeAdminTest): + + @classmethod + def skip_checks(cls): + super(VolumeManageAdminV2Test, cls).skip_checks() + + if not CONF.volume_feature_enabled.manage_volume: + raise cls.skipException("Manage volume tests are disabled") + + if len(CONF.volume.manage_volume_ref) != 2: + raise cls.skipException("Manage volume ref is not correctly " + "configured") + + @decorators.idempotent_id('70076c71-0ce1-4208-a8ff-36a66e65cc1e') + def test_unmanage_manage_volume(self): + # Create original volume + org_vol_id = self.create_volume()['id'] + org_vol_info = self.admin_volume_client.show_volume( + org_vol_id)['volume'] + + # Unmanage the original volume + self.admin_volume_client.unmanage_volume(org_vol_id) + self.admin_volume_client.wait_for_resource_deletion(org_vol_id) + + # Verify the original volume does not exist in volume list + params = {'all_tenants': 1} + all_tenants_volumes = self.admin_volume_client.list_volumes( + detail=True, params=params)['volumes'] + self.assertNotIn(org_vol_id, [v['id'] for v in all_tenants_volumes]) + + # Manage volume + new_vol_name = data_utils.rand_name( + self.__class__.__name__ + '-volume') + new_vol_ref = { + 'name': new_vol_name, + 'host': org_vol_info['os-vol-host-attr:host'], + 'ref': {CONF.volume.manage_volume_ref[0]: + CONF.volume.manage_volume_ref[1] % org_vol_id}, + 'volume_type': org_vol_info['volume_type'], + 'availability_zone': org_vol_info['availability_zone']} + new_vol_id = self.admin_volume_manage_client.manage_volume( + **new_vol_ref)['volume']['id'] + self.addCleanup(self.delete_volume, + self.admin_volume_client, new_vol_id) + waiters.wait_for_volume_resource_status(self.admin_volume_client, + new_vol_id, 'available') + + # Compare the managed volume with the original + new_vol_info = self.admin_volume_client.show_volume( + new_vol_id)['volume'] + self.assertNotIn(new_vol_id, [org_vol_id]) + self.assertEqual(new_vol_info['name'], new_vol_name) + for key in ['size', + 'volume_type', + 'availability_zone', + 'os-vol-host-attr:host']: + self.assertEqual(new_vol_info[key], org_vol_info[key]) diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py index f794920b92..84eada7b4f 100644 --- a/tempest/api/volume/base.py +++ b/tempest/api/volume/base.py @@ -230,6 +230,7 @@ class BaseVolumeAdminTest(BaseVolumeTest): cls.admin_volume_services_client = \ cls.os_adm.volume_services_v2_client cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client + cls.admin_volume_manage_client = cls.os_adm.volume_manage_v2_client cls.admin_volume_client = cls.os_adm.volumes_v2_client cls.admin_hosts_client = cls.os_adm.volume_hosts_v2_client cls.admin_snapshot_manage_client = \ diff --git a/tempest/clients.py b/tempest/clients.py index e75fa7903e..4d718aada8 100644 --- a/tempest/clients.py +++ b/tempest/clients.py @@ -262,6 +262,7 @@ class Manager(clients.ServiceClients): self.snapshot_manage_v2_client = self.volume_v2.SnapshotManageClient() self.snapshots_client = self.volume_v1.SnapshotsClient() self.snapshots_v2_client = self.volume_v2.SnapshotsClient() + self.volume_manage_v2_client = self.volume_v2.VolumeManageClient() self.volumes_client = self.volume_v1.VolumesClient() self.volumes_v2_client = self.volume_v2.VolumesClient() self.volume_v3_messages_client = self.volume_v3.MessagesClient() diff --git a/tempest/config.py b/tempest/config.py index d5c8ea99da..40891a6520 100644 --- a/tempest/config.py +++ b/tempest/config.py @@ -767,6 +767,12 @@ VolumeGroup = [ cfg.IntOpt('volume_size', default=1, help='Default size in GB for volumes created by volumes tests'), + cfg.ListOpt('manage_volume_ref', + default=['source-name', 'volume-%s'], + help="A reference to existing volume for volume manage. " + "It contains two elements, the first is ref type " + "(like 'source-name', 'source-id', etc), the second is " + "volume name template used in storage backend"), cfg.StrOpt('min_microversion', default=None, help="Lower version of the test target microversion range. " @@ -806,6 +812,9 @@ VolumeFeaturesGroup = [ cfg.BoolOpt('manage_snapshot', default=False, help='Runs Cinder manage snapshot tests'), + cfg.BoolOpt('manage_volume', + default=False, + help='Runs Cinder manage volume tests'), cfg.ListOpt('api_extensions', default=['all'], help='A list of enabled volume extensions with a special ' diff --git a/tempest/lib/services/volume/v2/__init__.py b/tempest/lib/services/volume/v2/__init__.py index 8acad0fe04..b4eb771388 100644 --- a/tempest/lib/services/volume/v2/__init__.py +++ b/tempest/lib/services/volume/v2/__init__.py @@ -31,10 +31,12 @@ from tempest.lib.services.volume.v2.snapshot_manage_client import \ SnapshotManageClient from tempest.lib.services.volume.v2.snapshots_client import SnapshotsClient from tempest.lib.services.volume.v2.types_client import TypesClient +from tempest.lib.services.volume.v2.volume_manage_client import \ + VolumeManageClient from tempest.lib.services.volume.v2.volumes_client import VolumesClient __all__ = ['AvailabilityZoneClient', 'BackupsClient', 'EncryptionTypesClient', 'ExtensionsClient', 'HostsClient', 'QosSpecsClient', 'QuotasClient', 'ServicesClient', 'SnapshotsClient', 'TypesClient', 'VolumesClient', 'LimitsClient', 'CapabilitiesClient', 'SchedulerStatsClient', - 'SnapshotManageClient'] + 'SnapshotManageClient', 'VolumeManageClient'] diff --git a/tempest/lib/services/volume/v2/volume_manage_client.py b/tempest/lib/services/volume/v2/volume_manage_client.py new file mode 100644 index 0000000000..12f4240a53 --- /dev/null +++ b/tempest/lib/services/volume/v2/volume_manage_client.py @@ -0,0 +1,37 @@ +# Copyright 2017 FiberHome Telecommunication Technologies CO.,LTD +# 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 + + +class VolumeManageClient(rest_client.RestClient): + """Volume manage V2 client.""" + + api_version = "v2" + + def manage_volume(self, **kwargs): + """Manage existing volume. + + For a full list of available parameters, please refer to the official + API reference: + https://developer.openstack.org/api-ref/block-storage/v2/#manage-existing-volume + """ + post_body = json.dumps({'volume': kwargs}) + resp, body = self.post('os-volume-manage', post_body) + self.expected_success(202, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) diff --git a/tempest/lib/services/volume/v2/volumes_client.py b/tempest/lib/services/volume/v2/volumes_client.py index 8b8e2498bb..2c109eaaf8 100644 --- a/tempest/lib/services/volume/v2/volumes_client.py +++ b/tempest/lib/services/volume/v2/volumes_client.py @@ -351,3 +351,15 @@ class VolumesClient(rest_client.RestClient): body = json.loads(body) self.expected_success(200, resp.status) return rest_client.ResponseBody(resp, body) + + def unmanage_volume(self, volume_id): + """Unmanage volume. + + For a full list of available parameters, please refer to the official + API reference: + https://developer.openstack.org/api-ref/block-storage/v2/#unmanage-volume + """ + post_body = json.dumps({'os-unmanage': {}}) + resp, body = self.post('volumes/%s/action' % volume_id, post_body) + self.expected_success(202, resp.status) + return rest_client.ResponseBody(resp, body)