Merge "Moved part of test cases to another class"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 9e93759..3147859 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -117,6 +117,10 @@
 # performed, which requires XenServer pools in case of using XS)
 use_block_migration_for_live_migration = false
 
+# Supports iSCSI block migration - depends on a XAPI supporting
+# relax-xsm-sr-check
+block_migrate_supports_cinder_iscsi = false
+
 # By default, rely on the status of the diskConfig extension to
 # decide if to execute disk config tests. When set to false, tests
 # are forced to skip, regardless of the extension status
diff --git a/tempest/config.py b/tempest/config.py
index f5f56a8..6d6bc2b 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -129,6 +129,10 @@
                 default=False,
                 help="Does the test environment use block devices for live "
                      "migration"),
+    cfg.BoolOpt('block_migrate_supports_cinder_iscsi',
+                default=False,
+                help="Does the test environment block migration support "
+                     "cinder iSCSI volumes"),
     cfg.BoolOpt('change_password_available',
                 default=False,
                 help="Does the test environment support changing the admin "
diff --git a/tempest/test.py b/tempest/test.py
index b7f4b9b..c69a94c 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -39,9 +39,13 @@
     def decorator(f):
         if 'type' in kwargs and isinstance(kwargs['type'], str):
             f = testtools.testcase.attr(kwargs['type'])(f)
+            if kwargs['type'] == 'smoke':
+                f = testtools.testcase.attr('gate')(f)
         elif 'type' in kwargs and isinstance(kwargs['type'], list):
             for attr in kwargs['type']:
                 f = testtools.testcase.attr(attr)(f)
+                if attr == 'smoke':
+                    f = testtools.testcase.attr('gate')(f)
         return nose.plugins.attrib.attr(*args, **kwargs)(f)
 
     return decorator
diff --git a/tempest/tests/compute/test_live_block_migration.py b/tempest/tests/compute/test_live_block_migration.py
index 30ff882..e22d45a 100644
--- a/tempest/tests/compute/test_live_block_migration.py
+++ b/tempest/tests/compute/test_live_block_migration.py
@@ -91,6 +91,13 @@
             self.created_server_ids.append(server_id)
             return server_id
 
+    def _volume_clean_up(self, server_id, volume_id):
+        resp, body = self.volumes_client.get_volume(volume_id)
+        if body['status'] == 'in-use':
+            self.servers_client.detach_volume(server_id, volume_id)
+            self.volumes_client.wait_for_volume_status(volume_id, 'available')
+        self.volumes_client.delete_volume(volume_id)
+
     @attr(type='positive')
     @testtools.skipIf(not CONF.compute.live_migration_available,
                       'Live migration not available')
@@ -117,6 +124,37 @@
                           server_id, target_host)
         self.assertEquals('ACTIVE', self._get_server_status(server_id))
 
+    @attr(type='positive')
+    @testtools.skipIf(not CONF.compute.live_migration_available or
+                      not CONF.compute.use_block_migration_for_live_migration,
+                      'Block Live migration not available')
+    @testtools.skipIf(not CONF.compute.block_migrate_supports_cinder_iscsi,
+                      'Block Live migration not configured for iSCSI')
+    def test_iscsi_volume(self):
+        # Live block migrate an instance to another host
+        if len(self._get_compute_hostnames()) < 2:
+            raise self.skipTest(
+                "Less than 2 compute nodes, skipping migration test.")
+        server_id = self._get_an_active_server()
+        actual_host = self._get_host_for_server(server_id)
+        target_host = self._get_host_other_than(actual_host)
+
+        resp, volume = self.volumes_client.create_volume(1,
+                                                         display_name='test')
+
+        self.volumes_client.wait_for_volume_status(volume['id'],
+                                                   'available')
+        self.addCleanup(self._volume_clean_up, server_id, volume['id'])
+
+        # Attach the volume to the server
+        self.servers_client.attach_volume(server_id, volume['id'],
+                                          device='/dev/xvdb')
+        self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
+
+        self._migrate_server_to(server_id, target_host)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+        self.assertEquals(target_host, self._get_host_for_server(server_id))
+
     @classmethod
     def tearDownClass(cls):
         for server_id in cls.created_server_ids:
diff --git a/tempest/tests/volume/admin/test_multi_backend.py b/tempest/tests/volume/admin/test_multi_backend.py
index c50586c..93b3b77 100644
--- a/tempest/tests/volume/admin/test_multi_backend.py
+++ b/tempest/tests/volume/admin/test_multi_backend.py
@@ -109,7 +109,7 @@
 
         super(VolumeMultiBackendTest, cls).tearDownClass()
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_multi_backend_enabled(self):
         # this test checks that multi backend is enabled for at least the
         # computes where the volumes created in setUp were made
diff --git a/tempest/tests/volume/admin/test_volume_types.py b/tempest/tests/volume/admin/test_volume_types.py
index 8fccd24..a35f017 100644
--- a/tempest/tests/volume/admin/test_volume_types.py
+++ b/tempest/tests/volume/admin/test_volume_types.py
@@ -38,7 +38,7 @@
                                                                auth_url,
                                                                adm_tenant)
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_type_list(self):
         # List Volume types.
         try:
@@ -48,7 +48,7 @@
         except Exception:
             self.fail("Could not list volume types")
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_create_get_delete_volume_with_volume_type_and_extra_specs(self):
         # Create/get/delete volume with volume_type and extra spec.
         try:
@@ -100,7 +100,7 @@
                 resp, _ = self.client.delete_volume_type(body['id'])
                 self.assertEqual(202, resp.status)
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_type_create_delete(self):
         # Create/Delete volume type.
         try:
@@ -123,7 +123,7 @@
         except Exception:
             self.fail("Could not create a volume_type")
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_type_create_get(self):
         # Create/get volume type.
         try:
diff --git a/tempest/tests/volume/admin/test_volume_types_extra_specs.py b/tempest/tests/volume/admin/test_volume_types_extra_specs.py
index 85edd64..aeb58c7 100644
--- a/tempest/tests/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/tests/volume/admin/test_volume_types_extra_specs.py
@@ -34,7 +34,7 @@
         cls.client.delete_volume_type(cls.volume_type['id'])
         super(VolumeTypesExtraSpecsTest, cls).tearDownClass()
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_type_extra_specs_list(self):
         # List Volume types extra specs.
         try:
@@ -77,7 +77,7 @@
         except Exception:
             self.fail("Couldnt update volume type extra spec")
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_type_extra_spec_create_get_delete(self):
         # Create/Get/Delete volume type extra spec.
         try:
diff --git a/tempest/tests/volume/test_volumes_actions.py b/tempest/tests/volume/test_volumes_actions.py
index 5396fa4..8664a7d 100644
--- a/tempest/tests/volume/test_volumes_actions.py
+++ b/tempest/tests/volume/test_volumes_actions.py
@@ -52,7 +52,7 @@
 
         super(VolumesActionsTest, cls).tearDownClass()
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_attach_detach_volume_to_instance(self):
         # Volume is attached and detached successfully from an instance
         try:
diff --git a/tempest/tests/volume/test_volumes_get.py b/tempest/tests/volume/test_volumes_get.py
index fdaf09b..65748e8 100644
--- a/tempest/tests/volume/test_volumes_get.py
+++ b/tempest/tests/volume/test_volumes_get.py
@@ -105,11 +105,11 @@
                 self.assertEqual(202, resp.status)
                 self.client.wait_for_resource_deletion(volume['id'])
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_create_get_delete(self):
         self._volume_create_get_delete(image_ref=None)
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_from_image(self):
         self._volume_create_get_delete(image_ref=self.config.compute.image_ref)
 
diff --git a/tempest/tests/volume/test_volumes_list.py b/tempest/tests/volume/test_volumes_list.py
index 2468705..7f5c756 100644
--- a/tempest/tests/volume/test_volumes_list.py
+++ b/tempest/tests/volume/test_volumes_list.py
@@ -76,7 +76,7 @@
             cls.client.wait_for_resource_deletion(volid)
         super(VolumesListTest, cls).tearDownClass()
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_list(self):
         # Get a list of Volumes
         # Fetch all volumes
diff --git a/tempest/tests/volume/test_volumes_snapshots.py b/tempest/tests/volume/test_volumes_snapshots.py
index edc02ac..935d42e 100644
--- a/tempest/tests/volume/test_volumes_snapshots.py
+++ b/tempest/tests/volume/test_volumes_snapshots.py
@@ -37,7 +37,7 @@
     def tearDownClass(cls):
         super(VolumesSnapshotTest, cls).tearDownClass()
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_snapshot_create_get_delete(self):
         # Create a snapshot, get some of the details and then deletes it
         resp, snapshot = self.snapshots_client.create_snapshot(
@@ -52,7 +52,7 @@
         self.snapshots_client.delete_snapshot(snapshot['id'])
         self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
 
-    @attr(type=['smoke', 'gate'])
+    @attr(type=['smoke'])
     def test_volume_from_snapshot(self):
         # Create a temporary snap using wrapper method from base, then
         # create a snap based volume, check resp code and deletes it