Merge "Add tempest tests for volume retype with migration"
diff --git a/tempest/api/volume/admin/test_volume_retype_with_migration.py b/tempest/api/volume/admin/test_volume_retype_with_migration.py
new file mode 100644
index 0000000..8a69ea3
--- /dev/null
+++ b/tempest/api/volume/admin/test_volume_retype_with_migration.py
@@ -0,0 +1,109 @@
+#    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_log import log as logging
+
+from tempest.api.volume import base
+from tempest.common import waiters
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+
+class VolumeRetypeWithMigrationV2Test(base.BaseVolumeAdminTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(VolumeRetypeWithMigrationV2Test, cls).skip_checks()
+
+        if not CONF.volume_feature_enabled.multi_backend:
+            raise cls.skipException("Cinder multi-backend feature disabled.")
+
+        if len(set(CONF.volume.backend_names)) < 2:
+            raise cls.skipException("Requires at least two different "
+                                    "backend names")
+
+    @classmethod
+    def resource_setup(cls):
+        super(VolumeRetypeWithMigrationV2Test, cls).resource_setup()
+        # read backend name from a list.
+        cls.backend_src = CONF.volume.backend_names[0]
+        cls.backend_dst = CONF.volume.backend_names[1]
+
+        extra_specs_src = {"volume_backend_name": cls.backend_src}
+        extra_specs_dst = {"volume_backend_name": cls.backend_dst}
+
+        cls.src_vol_type = cls.create_volume_type(extra_specs=extra_specs_src)
+        cls.dst_vol_type = cls.create_volume_type(extra_specs=extra_specs_dst)
+
+        cls.src_vol = cls.create_volume(volume_type=cls.src_vol_type['name'])
+
+    @classmethod
+    def resource_cleanup(cls):
+        # When retyping a volume, Cinder creates an internal volume in the
+        # target backend. The volume in the source backend is deleted after
+        # the migration, so we need to wait for Cinder delete this volume
+        # before deleting the types we've created.
+
+        # This list should return 2 volumes until the copy and cleanup
+        # process is finished.
+        fetched_list = cls.admin_volume_client.list_volumes(
+            params={'all_tenants': True,
+                    'display_name': cls.src_vol['name']})['volumes']
+
+        for fetched_vol in fetched_list:
+            if fetched_vol['id'] != cls.src_vol['id']:
+                # This is the Cinder internal volume
+                LOG.debug('Waiting for internal volume %s deletion',
+                          fetched_vol['id'])
+                cls.admin_volume_client.wait_for_resource_deletion(
+                    fetched_vol['id'])
+                break
+
+        super(VolumeRetypeWithMigrationV2Test, cls).resource_cleanup()
+
+    @test.idempotent_id('a1a41f3f-9dad-493e-9f09-3ff197d477cd')
+    def test_available_volume_retype_with_migration(self):
+
+        keys_with_no_change = ('id', 'size', 'description', 'name', 'user_id',
+                               'os-vol-tenant-attr:tenant_id')
+        keys_with_change = ('volume_type', 'os-vol-host-attr:host')
+
+        volume_source = self.admin_volume_client.show_volume(
+            self.src_vol['id'])['volume']
+
+        # TODO(erlon): change this to volumes_client client after Bug
+        # #1657806 is fixed
+        self.admin_volume_client.retype_volume(
+            self.src_vol['id'],
+            new_type=self.dst_vol_type['name'],
+            migration_policy='on-demand')
+
+        waiters.wait_for_volume_retype(self.volumes_client, self.src_vol['id'],
+                                       self.dst_vol_type['name'])
+        volume_dest = self.admin_volume_client.show_volume(
+            self.src_vol['id'])['volume']
+
+        # Check the volume information after the migration.
+        self.assertEqual('success',
+                         volume_dest['os-vol-mig-status-attr:migstat'])
+        self.assertEqual('success', volume_dest['migration_status'])
+
+        for key in keys_with_no_change:
+            self.assertEqual(volume_source[key], volume_dest[key])
+
+        for key in keys_with_change:
+            self.assertNotEqual(volume_source[key], volume_dest[key])