Merge "Bump hacking version in test-requirements.txt"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index b738e82..d8294f7 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -365,7 +365,7 @@
                     return address['addr']
             raise exceptions.ServerUnreachable(server_id=server['id'])
         else:
-            raise exceptions.InvalidConfiguration()
+            raise lib_exc.InvalidConfiguration()
 
     def setUp(self):
         super(BaseV2ComputeTest, self).setUp()
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 999233d..26d4efe 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -20,7 +20,7 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
-from tempest import exceptions
+from tempest.lib import exceptions
 from tempest import test
 
 CONF = config.CONF
diff --git a/tempest/api/network/admin/test_routers_dvr.py b/tempest/api/network/admin/test_routers_dvr.py
index 66feba8..aaac921 100644
--- a/tempest/api/network/admin/test_routers_dvr.py
+++ b/tempest/api/network/admin/test_routers_dvr.py
@@ -98,15 +98,22 @@
         attribute will be set to True
         """
         name = data_utils.rand_name('router')
+        tenant_id = self.routers_client.tenant_id
         # router needs to be in admin state down in order to be upgraded to DVR
         # l3ha routers are not upgradable to dvr, make it explicitly non ha
         router = self.admin_routers_client.create_router(name=name,
                                                          distributed=False,
                                                          admin_state_up=False,
-                                                         ha=False)
+                                                         ha=False,
+                                                         tenant_id=tenant_id)
+        router_id = router['router']['id']
         self.addCleanup(self.admin_routers_client.delete_router,
-                        router['router']['id'])
+                        router_id)
         self.assertFalse(router['router']['distributed'])
         router = self.admin_routers_client.update_router(
-            router['router']['id'], distributed=True)
+            router_id, distributed=True)
         self.assertTrue(router['router']['distributed'])
+        show_body = self.admin_routers_client.show_router(router_id)
+        self.assertTrue(show_body['router']['distributed'])
+        show_body = self.routers_client.show_router(router_id)
+        self.assertNotIn('distributed', show_body['router'])
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 6b0c20f..d2056c4 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -27,39 +27,11 @@
 CONF = config.CONF
 
 
-class NetworksTest(base.BaseNetworkTest):
-    """Tests the following operations in the Neutron API:
-
-        create a network for a project
-        list project's networks
-        show a project network details
-        create a subnet for a project
-        list project's subnets
-        show a project subnet details
-        network update
-        subnet update
-        delete a network also deletes its subnets
-        list external networks
-
-        All subnet tests are run once with ipv4 and once with ipv6.
-
-    v2.0 of the Neutron API is assumed. It is also assumed that the following
-    options are defined in the [network] section of etc/tempest.conf:
-
-        project_network_cidr with a block of cidr's from which smaller blocks
-        can be allocated for project ipv4 subnets
-
-        project_network_v6_cidr is the equivalent for ipv6 subnets
-
-        project_network_mask_bits with the mask bits to be used to partition
-        the block defined by project_network_cidr
-
-        project_network_v6_mask_bits is the equivalent for ipv6 subnets
-    """
+class BaseNetworkTestResources(base.BaseNetworkTest):
 
     @classmethod
     def resource_setup(cls):
-        super(NetworksTest, cls).resource_setup()
+        super(BaseNetworkTestResources, cls).resource_setup()
         cls.network = cls.create_network()
         cls.name = cls.network['name']
         cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
@@ -171,6 +143,37 @@
         self.networks.pop()
         self.subnets.pop()
 
+
+class NetworksTest(BaseNetworkTestResources):
+    """Tests the following operations in the Neutron API:
+
+        create a network for a project
+        list project's networks
+        show a project network details
+        create a subnet for a project
+        list project's subnets
+        show a project subnet details
+        network update
+        subnet update
+        delete a network also deletes its subnets
+        list external networks
+
+        All subnet tests are run once with ipv4 and once with ipv6.
+
+    v2.0 of the Neutron API is assumed. It is also assumed that the following
+    options are defined in the [network] section of etc/tempest.conf:
+
+        project_network_cidr with a block of cidr's from which smaller blocks
+        can be allocated for project ipv4 subnets
+
+        project_network_v6_cidr is the equivalent for ipv6 subnets
+
+        project_network_mask_bits with the mask bits to be used to partition
+        the block defined by project_network_cidr
+
+        project_network_v6_mask_bits is the equivalent for ipv6 subnets
+    """
+
     @test.attr(type='smoke')
     @test.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
     def test_create_update_delete_network_subnet(self):
@@ -559,7 +562,9 @@
                              'Subnet are not in the same network')
 
 
-class NetworksIpV6TestAttrs(NetworksIpV6Test):
+class NetworksIpV6TestAttrs(BaseNetworkTestResources):
+
+    _ip_version = 6
 
     @classmethod
     def skip_checks(cls):
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index de2e71f..ed6a302 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -390,35 +390,3 @@
 
 class RoutersIpV6Test(RoutersTest):
     _ip_version = 6
-
-
-class DvrRoutersTest(base.BaseRouterTest):
-
-    @classmethod
-    def skip_checks(cls):
-        super(DvrRoutersTest, cls).skip_checks()
-        if not test.is_extension_enabled('dvr', 'network'):
-            msg = "DVR extension not enabled."
-            raise cls.skipException(msg)
-
-    @test.idempotent_id('141297aa-3424-455d-aa8d-f2d95731e00a')
-    def test_create_distributed_router(self):
-        name = data_utils.rand_name('router')
-        create_body = self.admin_routers_client.create_router(
-            name=name, distributed=True)
-        self.addCleanup(self._delete_router,
-                        create_body['router']['id'],
-                        self.admin_routers_client)
-        self.assertTrue(create_body['router']['distributed'])
-
-    @test.idempotent_id('644d7a4a-01a1-4b68-bb8d-0c0042cb1729')
-    def test_convert_centralized_router(self):
-        router = self._create_router()
-        self.assertNotIn('distributed', router)
-        update_body = self.admin_routers_client.update_router(router['id'],
-                                                              distributed=True)
-        self.assertTrue(update_body['router']['distributed'])
-        show_body = self.admin_routers_client.show_router(router['id'])
-        self.assertTrue(show_body['router']['distributed'])
-        show_body = self.routers_client.show_router(router['id'])
-        self.assertNotIn('distributed', show_body['router'])
diff --git a/tempest/api/object_storage/test_account_bulk.py b/tempest/api/object_storage/test_account_bulk.py
index 7292ee9..a75ed98 100644
--- a/tempest/api/object_storage/test_account_bulk.py
+++ b/tempest/api/object_storage/test_account_bulk.py
@@ -66,7 +66,7 @@
         self.assertNotIn(container_name, body)
 
     @test.idempotent_id('a407de51-1983-47cc-9f14-47c2b059413c')
-    @test.requires_ext(extension='bulk', service='object')
+    @test.requires_ext(extension='bulk_upload', service='object')
     def test_extract_archive(self):
         # Test bulk operation of file upload with an archived file
         filepath, container_name, object_name = self._create_archive()
@@ -102,7 +102,7 @@
         self.assertIn(object_name, [c['name'] for c in contents_list])
 
     @test.idempotent_id('c075e682-0d2a-43b2-808d-4116200d736d')
-    @test.requires_ext(extension='bulk', service='object')
+    @test.requires_ext(extension='bulk_delete', service='object')
     def test_bulk_delete(self):
         # Test bulk operation of deleting multiple files
         filepath, container_name, object_name = self._create_archive()
@@ -129,7 +129,7 @@
         self._check_contents_deleted(container_name)
 
     @test.idempotent_id('dbea2bcb-efbb-4674-ac8a-a5a0e33d1d79')
-    @test.requires_ext(extension='bulk', service='object')
+    @test.requires_ext(extension='bulk_delete', service='object')
     def test_bulk_delete_by_POST(self):
         # Test bulk operation of deleting multiple files
         filepath, container_name, object_name = self._create_archive()
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 7717027..03996af 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -73,9 +73,13 @@
             val0 = fetched_volume[0][sort_key]
             val1 = fetched_volume[1][sort_key]
             if sort_dir == 'asc':
-                self.assertLess(val0, val1, "%s < %s" % (val0, val1))
+                self.assertLess(val0, val1,
+                                "list is not in asc order with sort_key: %s."
+                                " %s" % (sort_key, fetched_volume))
             elif sort_dir == 'desc':
-                self.assertGreater(val0, val1, "%s > %s" % (val0, val1))
+                self.assertGreater(val0, val1,
+                                   "list is not in desc order with sort_key: "
+                                   "%s. %s" % (sort_key, fetched_volume))
 
         _list_details_with_multiple_params()
         _list_details_with_multiple_params(sort_dir='desc')
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 9770f20..8b86267 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -141,6 +141,9 @@
         if clients is None:
             clients = self.manager
 
+        if name is None:
+            name = data_utils.rand_name(self.__class__.__name__ + "-server")
+
         vnic_type = CONF.network.port_vnic_type
 
         # If vnic_type is configured create port for
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 60b030d..0605902 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -35,6 +35,12 @@
     """
 
     @classmethod
+    def setup_clients(cls):
+        super(TestNetworkAdvancedServerOps, cls).setup_clients()
+        cls.admin_servers_client = cls.os_adm.servers_client
+        cls.admin_hosts_client = cls.os_adm.hosts_client
+
+    @classmethod
     def skip_checks(cls):
         super(TestNetworkAdvancedServerOps, cls).skip_checks()
         if not (CONF.network.project_networks_reachable
@@ -94,6 +100,10 @@
                                        'ACTIVE')
         self._check_network_connectivity(server, keypair, floating_ip)
 
+    def _get_host_for_server(self, server_id):
+        body = self.admin_servers_client.show_server(server_id)['server']
+        return body['OS-EXT-SRV-ATTR:host']
+
     @test.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
     @test.services('compute', 'network')
     def test_server_connectivity_stop_start(self):
@@ -184,3 +194,29 @@
         self.servers_client.confirm_resize_server(server['id'])
         self._wait_server_status_and_check_network_connectivity(
             server, keypair, floating_ip)
+
+    @test.idempotent_id('a4858f6c-401e-4155-9a49-d5cd053d1a2f')
+    @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
+                          'Cold migration is not available.')
+    @test.services('compute', 'network')
+    def test_server_connectivity_cold_migration(self):
+        if CONF.compute.min_compute_nodes < 2:
+            msg = "Less than 2 compute nodes, skipping multinode tests."
+            raise self.skipException(msg)
+
+        keypair = self.create_keypair()
+        server = self._setup_server(keypair)
+        floating_ip = self._setup_network(server, keypair)
+        src_host = self._get_host_for_server(server['id'])
+        self._wait_server_status_and_check_network_connectivity(
+            server, keypair, floating_ip)
+
+        self.admin_servers_client.migrate_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'VERIFY_RESIZE')
+        self.servers_client.confirm_resize_server(server['id'])
+        self._wait_server_status_and_check_network_connectivity(
+            server, keypair, floating_ip)
+        dst_host = self._get_host_for_server(server['id'])
+
+        self.assertNotEqual(src_host, dst_host)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index e177cb0..af313a5 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -19,7 +19,6 @@
 from oslo_log import log as logging
 import testtools
 
-from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
 from tempest.lib.common.utils import test_utils
@@ -116,8 +115,7 @@
             self.port_id = self._create_port(self.network['id'])['id']
             self.ports.append({'port': self.port_id})
 
-        name = data_utils.rand_name('server-smoke')
-        server = self._create_server(name, self.network, self.port_id)
+        server = self._create_server(self.network, self.port_id)
         self._check_tenant_network_connectivity()
 
         floating_ip = self.create_floating_ip(server)
@@ -151,7 +149,7 @@
             self.assertIn(self.router['id'],
                           seen_router_ids)
 
-    def _create_server(self, name, network, port_id=None):
+    def _create_server(self, network, port_id=None):
         keypair = self.create_keypair()
         self.keypairs[keypair['name']] = keypair
         security_groups = [{'name': self.security_group['name']}]
@@ -160,7 +158,6 @@
             network['port'] = port_id
 
         server = self.create_server(
-            name=name,
             networks=[network],
             key_name=keypair['name'],
             security_groups=security_groups,
@@ -220,9 +217,8 @@
 
     def _reassociate_floating_ips(self):
         floating_ip, server = self.floating_ip_tuple
-        name = data_utils.rand_name('new_server-smoke')
         # create a new server for the floating ip
-        server = self._create_server(name, self.network)
+        server = self._create_server(self.network)
         self._associate_floating_ip(floating_ip, server)
         self.floating_ip_tuple = Floating_IP_tuple(
             floating_ip, server)
@@ -459,8 +455,7 @@
         self._check_network_internal_connectivity(network=self.network)
         self._check_network_external_connectivity()
         self._create_new_network(create_gateway=True)
-        name = data_utils.rand_name('server-smoke')
-        self._create_server(name, self.new_net)
+        self._create_server(self.new_net)
         self._check_network_internal_connectivity(network=self.new_net,
                                                   should_connect=False)
         router_id = self.router['id']
@@ -688,8 +683,7 @@
 
         # Boot another server with the same port to make sure nothing was
         # left around that could cause issues.
-        name = data_utils.rand_name('reuse-port')
-        server = self._create_server(name, self.network, port['id'])
+        server = self._create_server(self.network, port['id'])
         port_list = self._list_ports(device_id=server['id'],
                                      network_id=self.network['id'])
         self.assertEqual(1, len(port_list),
@@ -813,8 +807,7 @@
         ssh_client = self.get_remote_client(fip['floating_ip_address'],
                                             private_key=private_key)
         spoof_nic = ssh_client.get_nic_name_by_mac(spoof_port["mac_address"])
-        name = data_utils.rand_name('peer')
-        peer = self._create_server(name, self.new_net)
+        peer = self._create_server(self.new_net)
         peer_address = peer['addresses'][self.new_net['name']][0]['addr']
         self._check_remote_connectivity(ssh_client, dest=peer_address,
                                         nic=spoof_nic, should_succeed=True)