Merge "Remove deprecated compute config options for validation"
diff --git a/doc/source/library/clients.rst b/doc/source/library/clients.rst
index 086cfc9..0f4ba4c 100644
--- a/doc/source/library/clients.rst
+++ b/doc/source/library/clients.rst
@@ -16,9 +16,18 @@
 The ``ServiceClients`` class provides a convenient way to get access to all
 available service clients initialized with a provided set of credentials.
 
-------------------
-The clients module
-------------------
+-----------------------------
+The clients management module
+-----------------------------
 
 .. automodule:: tempest.lib.services.clients
    :members:
+
+------------------------------
+Compute service client modules
+------------------------------
+
+.. toctree::
+   :maxdepth: 2
+
+   service_clients/compute_clients
diff --git a/doc/source/library/service_clients/compute_clients.rst b/doc/source/library/service_clients/compute_clients.rst
new file mode 100644
index 0000000..4ca55d4
--- /dev/null
+++ b/doc/source/library/service_clients/compute_clients.rst
@@ -0,0 +1,7 @@
+.. _servers_client:
+
+Compute Client Usage
+====================
+
+.. automodule:: tempest.lib.services.compute.servers_client
+   :members:
diff --git a/releasenotes/notes/remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml b/releasenotes/notes/remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml
new file mode 100644
index 0000000..b1c0c62
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml
@@ -0,0 +1,9 @@
+---
+upgrade:
+  - The deprecated compute microversion config options from
+    'compute-feature-enabled' group have been removed. Those config options
+    are available under 'compute' group to configure the min and max
+    microversion for compute service.
+
+    * CONF.compute.min_microversion
+    * CONF.compute.max_microversion
diff --git a/releasenotes/notes/remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml b/releasenotes/notes/remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml
new file mode 100644
index 0000000..371c061
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml
@@ -0,0 +1,6 @@
+---
+upgrade:
+  - The deprecated input-scenario config options and group
+    have been removed.
+    The input scenarios functionality already being removed from tempest
+    and from this release, their corresponding config options too.
diff --git a/releasenotes/notes/remove-deprecated-network-config-options-f9ce276231578fe6.yaml b/releasenotes/notes/remove-deprecated-network-config-options-f9ce276231578fe6.yaml
new file mode 100644
index 0000000..e445fb3
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-network-config-options-f9ce276231578fe6.yaml
@@ -0,0 +1,11 @@
+---
+upgrade:
+  - |
+    Below deprecated network config options have been removed.
+    Those config options already been renamed to below meaningful names.
+
+    - ``tenant_network_cidr`` (removed) -> ``project_network_cidr``
+    - ``tenant_network_mask_bits`` (removed) -> ``project_network_mask_bits``
+    - ``tenant_network_v6_cidr`` (removed) -> ``project_network_v6_cidr``
+    - ``tenant_network_v6_mask_bits`` (removed) -> ``project_network_v6_mask_bits``
+    - ``tenant_networks_reachable`` (removed) -> ``project_networks_reachable``
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index deded73..00107cd 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -34,7 +34,6 @@
     def resource_setup(cls):
         super(AggregatesAdminNegativeTestJSON, cls).resource_setup()
         cls.aggregate_name_prefix = 'test_aggregate'
-        cls.az_name_prefix = 'test_az'
 
         hosts_all = cls.os_adm.hosts_client.list_hosts()['hosts']
         hosts = ([host['host_name']
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index f615c8a..f3a5e01 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -33,12 +33,6 @@
             raise cls.skipException(msg)
 
     @classmethod
-    def setup_clients(cls):
-        super(FlavorsAdminTestJSON, cls).setup_clients()
-        cls.client = cls.os_adm.flavors_client
-        cls.user_client = cls.os.flavors_client
-
-    @classmethod
     def resource_setup(cls):
         super(FlavorsAdminTestJSON, cls).resource_setup()
 
@@ -94,7 +88,8 @@
                                     rxtx_factor=self.rxtx)
         flag = False
         # Verify flavor is retrieved
-        flavors = self.client.list_flavors(detail=True)['flavors']
+        flavors = self.admin_flavors_client.list_flavors(
+            detail=True)['flavors']
         for flavor in flavors:
             if flavor['name'] == flavor_name:
                 flag = True
@@ -128,13 +123,13 @@
         verify_flavor_response_extension(flavor)
 
         # Verify flavor is retrieved
-        flavor = self.client.show_flavor(new_flavor_id)['flavor']
+        flavor = self.admin_flavors_client.show_flavor(new_flavor_id)['flavor']
         self.assertEqual(flavor['name'], flavor_name)
         verify_flavor_response_extension(flavor)
 
         # Check if flavor is present in list
         flag = False
-        flavors = self.user_client.list_flavors(detail=True)['flavors']
+        flavors = self.flavors_client.list_flavors(detail=True)['flavors']
         for flavor in flavors:
             if flavor['name'] == flavor_name:
                 verify_flavor_response_extension(flavor)
@@ -156,7 +151,8 @@
                                     is_public="False")
         # Verify flavor is retrieved
         flag = False
-        flavors = self.client.list_flavors(detail=True)['flavors']
+        flavors = self.admin_flavors_client.list_flavors(
+            detail=True)['flavors']
         for flavor in flavors:
             if flavor['name'] == flavor_name:
                 flag = True
@@ -164,7 +160,7 @@
 
         # Verify flavor is not retrieved with other user
         flag = False
-        flavors = self.user_client.list_flavors(detail=True)['flavors']
+        flavors = self.flavors_client.list_flavors(detail=True)['flavors']
         for flavor in flavors:
             if flavor['name'] == flavor_name:
                 flag = True
@@ -195,9 +191,8 @@
                                     disk=self.disk,
                                     is_public="True")
         flag = False
-        self.new_client = self.flavors_client
         # Verify flavor is retrieved with new user
-        flavors = self.new_client.list_flavors(detail=True)['flavors']
+        flavors = self.flavors_client.list_flavors(detail=True)['flavors']
         for flavor in flavors:
             if flavor['name'] == flavor_name:
                 flag = True
@@ -229,7 +224,8 @@
         def _test_string_variations(variations, flavor_name):
             for string in variations:
                 params = {'is_public': string}
-                flavors = (self.client.list_flavors(detail=True, **params)
+                flavors = (self.admin_flavors_client.list_flavors(detail=True,
+                                                                  **params)
                            ['flavors'])
                 flavor = _flavor_lookup(flavors, flavor_name)
                 self.assertIsNotNone(flavor)
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 38ff4c0..04b0c2d 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -33,11 +33,6 @@
             raise cls.skipException(msg)
 
     @classmethod
-    def setup_clients(cls):
-        super(FlavorsAccessTestJSON, cls).setup_clients()
-        cls.client = cls.os_adm.flavors_client
-
-    @classmethod
     def resource_setup(cls):
         super(FlavorsAccessTestJSON, cls).resource_setup()
 
@@ -54,14 +49,16 @@
         # private flavor will return an empty access list
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
-        new_flavor = self.client.create_flavor(name=flavor_name,
-                                               ram=self.ram, vcpus=self.vcpus,
-                                               disk=self.disk,
-                                               id=new_flavor_id,
-                                               is_public='False')['flavor']
-        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
-        flavor_access = (self.client.list_flavor_access(new_flavor_id)
-                         ['flavor_access'])
+        new_flavor = self.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=self.ram, vcpus=self.vcpus,
+            disk=self.disk,
+            id=new_flavor_id,
+            is_public='False')['flavor']
+        self.addCleanup(self.admin_flavors_client.delete_flavor,
+                        new_flavor['id'])
+        flavor_access = (self.admin_flavors_client.list_flavor_access(
+            new_flavor_id)['flavor_access'])
         self.assertEqual(len(flavor_access), 0, str(flavor_access))
 
     @decorators.idempotent_id('59e622f6-bdf6-45e3-8ba8-fedad905a6b4')
@@ -69,20 +66,21 @@
         # Test to add and remove flavor access to a given tenant.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
-        new_flavor = self.client.create_flavor(name=flavor_name,
-                                               ram=self.ram, vcpus=self.vcpus,
-                                               disk=self.disk,
-                                               id=new_flavor_id,
-                                               is_public='False')['flavor']
-        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        new_flavor = self.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=self.ram, vcpus=self.vcpus,
+            disk=self.disk,
+            id=new_flavor_id,
+            is_public='False')['flavor']
+        self.addCleanup(self.admin_flavors_client.delete_flavor,
+                        new_flavor['id'])
         # Add flavor access to a tenant.
         resp_body = {
             "tenant_id": str(self.tenant_id),
             "flavor_id": str(new_flavor['id']),
         }
-        add_body = (self.client.add_flavor_access(new_flavor['id'],
-                                                  self.tenant_id)
-                    ['flavor_access'])
+        add_body = (self.admin_flavors_client.add_flavor_access(
+            new_flavor['id'], self.tenant_id)['flavor_access'])
         self.assertIn(resp_body, add_body)
 
         # The flavor is present in list.
@@ -90,9 +88,8 @@
         self.assertIn(new_flavor['id'], map(lambda x: x['id'], flavors))
 
         # Remove flavor access from a tenant.
-        remove_body = (self.client.remove_flavor_access(new_flavor['id'],
-                                                        self.tenant_id)
-                       ['flavor_access'])
+        remove_body = (self.admin_flavors_client.remove_flavor_access(
+            new_flavor['id'], self.tenant_id)['flavor_access'])
         self.assertNotIn(resp_body, remove_body)
 
         # The flavor is not present in list.
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index 2719cc4..bd72d13 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -34,11 +34,6 @@
             raise cls.skipException(msg)
 
     @classmethod
-    def setup_clients(cls):
-        super(FlavorsAccessNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.os_adm.flavors_client
-
-    @classmethod
     def resource_setup(cls):
         super(FlavorsAccessNegativeTestJSON, cls).resource_setup()
 
@@ -54,14 +49,16 @@
         # Test to list flavor access with exceptions by querying public flavor
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
-        new_flavor = self.client.create_flavor(name=flavor_name,
-                                               ram=self.ram, vcpus=self.vcpus,
-                                               disk=self.disk,
-                                               id=new_flavor_id,
-                                               is_public='True')['flavor']
-        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        new_flavor = self.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=self.ram, vcpus=self.vcpus,
+            disk=self.disk,
+            id=new_flavor_id,
+            is_public='True')['flavor']
+        self.addCleanup(self.admin_flavors_client.delete_flavor,
+                        new_flavor['id'])
         self.assertRaises(lib_exc.NotFound,
-                          self.client.list_flavor_access,
+                          self.admin_flavors_client.list_flavor_access,
                           new_flavor_id)
 
     @test.attr(type=['negative'])
@@ -70,12 +67,14 @@
         # Test to add flavor access as a user without admin privileges.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
-        new_flavor = self.client.create_flavor(name=flavor_name,
-                                               ram=self.ram, vcpus=self.vcpus,
-                                               disk=self.disk,
-                                               id=new_flavor_id,
-                                               is_public='False')['flavor']
-        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        new_flavor = self.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=self.ram, vcpus=self.vcpus,
+            disk=self.disk,
+            id=new_flavor_id,
+            is_public='False')['flavor']
+        self.addCleanup(self.admin_flavors_client.delete_flavor,
+                        new_flavor['id'])
         self.assertRaises(lib_exc.Forbidden,
                           self.flavors_client.add_flavor_access,
                           new_flavor['id'],
@@ -87,15 +86,18 @@
         # Test to remove flavor access as a user without admin privileges.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
-        new_flavor = self.client.create_flavor(name=flavor_name,
-                                               ram=self.ram, vcpus=self.vcpus,
-                                               disk=self.disk,
-                                               id=new_flavor_id,
-                                               is_public='False')['flavor']
-        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        new_flavor = self.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=self.ram, vcpus=self.vcpus,
+            disk=self.disk,
+            id=new_flavor_id,
+            is_public='False')['flavor']
+        self.addCleanup(self.admin_flavors_client.delete_flavor,
+                        new_flavor['id'])
         # Add flavor access to a tenant.
-        self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
-        self.addCleanup(self.client.remove_flavor_access,
+        self.admin_flavors_client.add_flavor_access(new_flavor['id'],
+                                                    self.tenant_id)
+        self.addCleanup(self.admin_flavors_client.remove_flavor_access,
                         new_flavor['id'], self.tenant_id)
         self.assertRaises(lib_exc.Forbidden,
                           self.flavors_client.remove_flavor_access,
@@ -108,22 +110,25 @@
         # Create a new flavor.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
-        new_flavor = self.client.create_flavor(name=flavor_name,
-                                               ram=self.ram, vcpus=self.vcpus,
-                                               disk=self.disk,
-                                               id=new_flavor_id,
-                                               is_public='False')['flavor']
-        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        new_flavor = self.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=self.ram, vcpus=self.vcpus,
+            disk=self.disk,
+            id=new_flavor_id,
+            is_public='False')['flavor']
+        self.addCleanup(self.admin_flavors_client.delete_flavor,
+                        new_flavor['id'])
 
         # Add flavor access to a tenant.
-        self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
-        self.addCleanup(self.client.remove_flavor_access,
+        self.admin_flavors_client.add_flavor_access(new_flavor['id'],
+                                                    self.tenant_id)
+        self.addCleanup(self.admin_flavors_client.remove_flavor_access,
                         new_flavor['id'], self.tenant_id)
 
         # An exception should be raised when adding flavor access to the same
         # tenant
         self.assertRaises(lib_exc.Conflict,
-                          self.client.add_flavor_access,
+                          self.admin_flavors_client.add_flavor_access,
                           new_flavor['id'],
                           self.tenant_id)
 
@@ -133,15 +138,17 @@
         # Create a new flavor.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
-        new_flavor = self.client.create_flavor(name=flavor_name,
-                                               ram=self.ram, vcpus=self.vcpus,
-                                               disk=self.disk,
-                                               id=new_flavor_id,
-                                               is_public='False')['flavor']
-        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        new_flavor = self.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=self.ram, vcpus=self.vcpus,
+            disk=self.disk,
+            id=new_flavor_id,
+            is_public='False')['flavor']
+        self.addCleanup(self.admin_flavors_client.delete_flavor,
+                        new_flavor['id'])
 
         # An exception should be raised when flavor access is not found
         self.assertRaises(lib_exc.NotFound,
-                          self.client.remove_flavor_access,
+                          self.admin_flavors_client.remove_flavor_access,
                           new_flavor['id'],
                           data_utils.rand_uuid())
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index 70e662c..8ec6400 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -34,11 +34,6 @@
             raise cls.skipException(msg)
 
     @classmethod
-    def setup_clients(cls):
-        super(FlavorsExtraSpecsTestJSON, cls).setup_clients()
-        cls.client = cls.os_adm.flavors_client
-
-    @classmethod
     def resource_setup(cls):
         super(FlavorsExtraSpecsTestJSON, cls).resource_setup()
         flavor_name = data_utils.rand_name('test_flavor')
@@ -50,18 +45,19 @@
         swap = 1024
         rxtx = 1
         # Create a flavor so as to set/get/unset extra specs
-        cls.flavor = cls.client.create_flavor(name=flavor_name,
-                                              ram=ram, vcpus=vcpus,
-                                              disk=disk,
-                                              id=cls.new_flavor_id,
-                                              ephemeral=ephemeral,
-                                              swap=swap,
-                                              rxtx_factor=rxtx)['flavor']
+        cls.flavor = cls.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=ram, vcpus=vcpus,
+            disk=disk,
+            id=cls.new_flavor_id,
+            ephemeral=ephemeral,
+            swap=swap,
+            rxtx_factor=rxtx)['flavor']
 
     @classmethod
     def resource_cleanup(cls):
-        cls.client.delete_flavor(cls.flavor['id'])
-        cls.client.wait_for_resource_deletion(cls.flavor['id'])
+        cls.admin_flavors_client.delete_flavor(cls.flavor['id'])
+        cls.admin_flavors_client.wait_for_resource_deletion(cls.flavor['id'])
         super(FlavorsExtraSpecsTestJSON, cls).resource_cleanup()
 
     @decorators.idempotent_id('0b2f9d4b-1ca2-4b99-bb40-165d4bb94208')
@@ -71,46 +67,47 @@
         # Assigning extra specs values that are to be set
         specs = {"key1": "value1", "key2": "value2"}
         # SET extra specs to the flavor created in setUp
-        set_body = self.client.set_flavor_extra_spec(self.flavor['id'],
-                                                     **specs)['extra_specs']
+        set_body = self.admin_flavors_client.set_flavor_extra_spec(
+            self.flavor['id'], **specs)['extra_specs']
         self.assertEqual(set_body, specs)
         # GET extra specs and verify
-        get_body = (self.client.list_flavor_extra_specs(self.flavor['id'])
-                    ['extra_specs'])
+        get_body = (self.admin_flavors_client.list_flavor_extra_specs(
+            self.flavor['id'])['extra_specs'])
         self.assertEqual(get_body, specs)
 
         # UPDATE the value of the extra specs key1
         update_body = \
-            self.client.update_flavor_extra_spec(self.flavor['id'],
-                                                 "key1",
-                                                 key1="value")
+            self.admin_flavors_client.update_flavor_extra_spec(
+                self.flavor['id'], "key1", key1="value")
         self.assertEqual({"key1": "value"}, update_body)
 
         # GET extra specs and verify the value of the key2
         # is the same as before
-        get_body = (self.client.list_flavor_extra_specs(self.flavor['id'])
-                    ['extra_specs'])
+        get_body = (self.admin_flavors_client.list_flavor_extra_specs(
+            self.flavor['id'])['extra_specs'])
         self.assertEqual(get_body, {"key1": "value", "key2": "value2"})
 
         # UNSET extra specs that were set in this test
-        self.client.unset_flavor_extra_spec(self.flavor['id'], "key1")
-        self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
+        self.admin_flavors_client.unset_flavor_extra_spec(self.flavor['id'],
+                                                          "key1")
+        self.admin_flavors_client.unset_flavor_extra_spec(self.flavor['id'],
+                                                          "key2")
 
     @decorators.idempotent_id('a99dad88-ae1c-4fba-aeb4-32f898218bd0')
     def test_flavor_non_admin_get_all_keys(self):
         specs = {"key1": "value1", "key2": "value2"}
-        self.client.set_flavor_extra_spec(self.flavor['id'], **specs)
-        body = (self.flavors_client.list_flavor_extra_specs(self.flavor['id'])
-                ['extra_specs'])
+        self.admin_flavors_client.set_flavor_extra_spec(self.flavor['id'],
+                                                        **specs)
+        body = (self.flavors_client.list_flavor_extra_specs(
+            self.flavor['id'])['extra_specs'])
 
         for key in specs:
             self.assertEqual(body[key], specs[key])
 
     @decorators.idempotent_id('12805a7f-39a3-4042-b989-701d5cad9c90')
     def test_flavor_non_admin_get_specific_key(self):
-        body = self.client.set_flavor_extra_spec(self.flavor['id'],
-                                                 key1="value1",
-                                                 key2="value2")['extra_specs']
+        body = self.admin_flavors_client.set_flavor_extra_spec(
+            self.flavor['id'], key1="value1", key2="value2")['extra_specs']
         self.assertEqual(body['key1'], 'value1')
         self.assertIn('key2', body)
         body = self.flavors_client.show_flavor_extra_spec(
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
index 767a1ca..79a9068 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
@@ -35,11 +35,6 @@
             raise cls.skipException(msg)
 
     @classmethod
-    def setup_clients(cls):
-        super(FlavorsExtraSpecsNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.os_adm.flavors_client
-
-    @classmethod
     def resource_setup(cls):
         super(FlavorsExtraSpecsNegativeTestJSON, cls).resource_setup()
 
@@ -52,18 +47,19 @@
         swap = 1024
         rxtx = 1
         # Create a flavor
-        cls.flavor = cls.client.create_flavor(name=flavor_name,
-                                              ram=ram, vcpus=vcpus,
-                                              disk=disk,
-                                              id=cls.new_flavor_id,
-                                              ephemeral=ephemeral,
-                                              swap=swap,
-                                              rxtx_factor=rxtx)['flavor']
+        cls.flavor = cls.admin_flavors_client.create_flavor(
+            name=flavor_name,
+            ram=ram, vcpus=vcpus,
+            disk=disk,
+            id=cls.new_flavor_id,
+            ephemeral=ephemeral,
+            swap=swap,
+            rxtx_factor=rxtx)['flavor']
 
     @classmethod
     def resource_cleanup(cls):
-        cls.client.delete_flavor(cls.flavor['id'])
-        cls.client.wait_for_resource_deletion(cls.flavor['id'])
+        cls.admin_flavors_client.delete_flavor(cls.flavor['id'])
+        cls.admin_flavors_client.wait_for_resource_deletion(cls.flavor['id'])
         super(FlavorsExtraSpecsNegativeTestJSON, cls).resource_cleanup()
 
     @test.attr(type=['negative'])
@@ -79,7 +75,7 @@
     @decorators.idempotent_id('1ebf4ef8-759e-48fe-a801-d451d80476fb')
     def test_flavor_non_admin_update_specific_key(self):
         # non admin user is not allowed to update flavor extra spec
-        body = self.client.set_flavor_extra_spec(
+        body = self.admin_flavors_client.set_flavor_extra_spec(
             self.flavor['id'], key1="value1", key2="value2")['extra_specs']
         self.assertEqual(body['key1'], 'value1')
         self.assertRaises(lib_exc.Forbidden,
@@ -92,8 +88,8 @@
     @test.attr(type=['negative'])
     @decorators.idempotent_id('28f12249-27c7-44c1-8810-1f382f316b11')
     def test_flavor_non_admin_unset_keys(self):
-        self.client.set_flavor_extra_spec(self.flavor['id'],
-                                          key1="value1", key2="value2")
+        self.admin_flavors_client.set_flavor_extra_spec(
+            self.flavor['id'], key1="value1", key2="value2")
 
         self.assertRaises(lib_exc.Forbidden,
                           self.flavors_client.unset_flavor_extra_spec,
@@ -104,7 +100,7 @@
     @decorators.idempotent_id('440b9f3f-3c7f-4293-a106-0ceda350f8de')
     def test_flavor_unset_nonexistent_key(self):
         self.assertRaises(lib_exc.NotFound,
-                          self.client.unset_flavor_extra_spec,
+                          self.admin_flavors_client.unset_flavor_extra_spec,
                           self.flavor['id'],
                           'nonexistent_key')
 
@@ -121,7 +117,7 @@
     def test_flavor_update_mismatch_key(self):
         # the key will be updated should be match the key in the body
         self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_flavor_extra_spec,
+                          self.admin_flavors_client.update_flavor_extra_spec,
                           self.flavor['id'],
                           "key2",
                           key1="value")
@@ -131,7 +127,7 @@
     def test_flavor_update_more_key(self):
         # there should be just one item in the request body
         self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_flavor_extra_spec,
+                          self.admin_flavors_client.update_flavor_extra_spec,
                           self.flavor['id'],
                           "key1",
                           key1="value",
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 1283629..b53ced9 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -42,9 +42,7 @@
         super(ServersAdminNegativeTestJSON, cls).resource_setup()
         cls.tenant_id = cls.client.tenant_id
 
-        cls.s1_name = data_utils.rand_name(cls.__name__ + '-server')
-        server = cls.create_test_server(name=cls.s1_name,
-                                        wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.s1_id = server['id']
 
     def _get_unused_flavor_id(self):
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 546667f..89051c1 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -22,17 +22,12 @@
     _min_disk = 'minDisk'
     _min_ram = 'minRam'
 
-    @classmethod
-    def setup_clients(cls):
-        super(FlavorsV2TestJSON, cls).setup_clients()
-        cls.client = cls.flavors_client
-
     @test.attr(type='smoke')
     @decorators.idempotent_id('e36c0eaa-dff5-4082-ad1f-3f9a80aa3f59')
     def test_list_flavors(self):
         # List of all flavors should contain the expected flavor
-        flavors = self.client.list_flavors()['flavors']
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavors = self.flavors_client.list_flavors()['flavors']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_min_detail = {'id': flavor['id'], 'links': flavor['links'],
                              'name': flavor['name']}
         self.assertIn(flavor_min_detail, flavors)
@@ -40,89 +35,93 @@
     @decorators.idempotent_id('6e85fde4-b3cd-4137-ab72-ed5f418e8c24')
     def test_list_flavors_with_detail(self):
         # Detailed list of all flavors should contain the expected flavor
-        flavors = self.client.list_flavors(detail=True)['flavors']
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavors = self.flavors_client.list_flavors(detail=True)['flavors']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         self.assertIn(flavor, flavors)
 
     @test.attr(type='smoke')
     @decorators.idempotent_id('1f12046b-753d-40d2-abb6-d8eb8b30cb2f')
     def test_get_flavor(self):
         # The expected flavor details should be returned
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         self.assertEqual(self.flavor_ref, flavor['id'])
 
     @decorators.idempotent_id('8d7691b3-6ed4-411a-abc9-2839a765adab')
     def test_list_flavors_limit_results(self):
         # Only the expected number of flavors should be returned
         params = {'limit': 1}
-        flavors = self.client.list_flavors(**params)['flavors']
+        flavors = self.flavors_client.list_flavors(**params)['flavors']
         self.assertEqual(1, len(flavors))
 
     @decorators.idempotent_id('b26f6327-2886-467a-82be-cef7a27709cb')
     def test_list_flavors_detailed_limit_results(self):
         # Only the expected number of flavors (detailed) should be returned
         params = {'limit': 1}
-        flavors = self.client.list_flavors(detail=True, **params)['flavors']
+        flavors = self.flavors_client.list_flavors(detail=True,
+                                                   **params)['flavors']
         self.assertEqual(1, len(flavors))
 
     @decorators.idempotent_id('e800f879-9828-4bd0-8eae-4f17189951fb')
     def test_list_flavors_using_marker(self):
         # The list of flavors should start from the provided marker
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
         params = {'marker': flavor_id}
-        flavors = self.client.list_flavors(**params)['flavors']
+        flavors = self.flavors_client.list_flavors(**params)['flavors']
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]),
                          'The list of flavors did not start after the marker.')
 
     @decorators.idempotent_id('6db2f0c0-ddee-4162-9c84-0703d3dd1107')
     def test_list_flavors_detailed_using_marker(self):
         # The list of flavors should start from the provided marker
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
         params = {'marker': flavor_id}
-        flavors = self.client.list_flavors(detail=True, **params)['flavors']
+        flavors = self.flavors_client.list_flavors(detail=True,
+                                                   **params)['flavors']
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]),
                          'The list of flavors did not start after the marker.')
 
     @decorators.idempotent_id('3df2743e-3034-4e57-a4cb-b6527f6eac79')
     def test_list_flavors_detailed_filter_by_min_disk(self):
         # The detailed list of flavors should be filtered by disk space
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
         params = {self._min_disk: flavor['disk'] + 1}
-        flavors = self.client.list_flavors(detail=True, **params)['flavors']
+        flavors = self.flavors_client.list_flavors(detail=True,
+                                                   **params)['flavors']
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @decorators.idempotent_id('09fe7509-b4ee-4b34-bf8b-39532dc47292')
     def test_list_flavors_detailed_filter_by_min_ram(self):
         # The detailed list of flavors should be filtered by RAM
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
         params = {self._min_ram: flavor['ram'] + 1}
-        flavors = self.client.list_flavors(detail=True, **params)['flavors']
+        flavors = self.flavors_client.list_flavors(detail=True,
+                                                   **params)['flavors']
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @decorators.idempotent_id('10645a4d-96f5-443f-831b-730711e11dd4')
     def test_list_flavors_filter_by_min_disk(self):
         # The list of flavors should be filtered by disk space
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
         params = {self._min_disk: flavor['disk'] + 1}
-        flavors = self.client.list_flavors(**params)['flavors']
+        flavors = self.flavors_client.list_flavors(**params)['flavors']
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @decorators.idempotent_id('935cf550-e7c8-4da6-8002-00f92d5edfaa')
     def test_list_flavors_filter_by_min_ram(self):
         # The list of flavors should be filtered by RAM
-        flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+        flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
         params = {self._min_ram: flavor['ram'] + 1}
-        flavors = self.client.list_flavors(**params)['flavors']
+        flavors = self.flavors_client.list_flavors(**params)['flavors']
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
new file mode 100644
index 0000000..a70c0a9
--- /dev/null
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -0,0 +1,89 @@
+# Copyright 2017 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.
+
+import random
+
+import six
+
+from tempest.api.compute import base
+from tempest.common import image as common_image
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest.lib import exceptions as lib_exc
+from tempest import test
+
+CONF = config.CONF
+
+
+class FlavorsV2NegativeTest(base.BaseV2ComputeTest):
+
+    @classmethod
+    def setup_clients(cls):
+        super(FlavorsV2NegativeTest, cls).setup_clients()
+        if CONF.image_feature_enabled.api_v1:
+            cls.images_client = cls.os.image_client
+        elif CONF.image_feature_enabled.api_v2:
+            cls.images_client = cls.os.image_client_v2
+        else:
+            raise lib_exc.InvalidConfiguration(
+                'Either api_v1 or api_v2 must be True in '
+                '[image-feature-enabled].')
+
+    @test.attr(type=['negative'])
+    @test.services('image')
+    @test.idempotent_id('90f0d93a-91c1-450c-91e6-07d18172cefe')
+    def test_boot_with_low_ram(self):
+        """Try boot a vm with lower than min ram
+
+        Create an image with min_ram value
+        Try to create server with flavor of insufficient ram size from
+        that image
+        """
+        flavor = self.flavors_client.show_flavor(
+            CONF.compute.flavor_ref)['flavor']
+        min_img_ram = flavor['ram'] + 1
+        size = random.randint(1024, 4096)
+        image_file = six.BytesIO(data_utils.random_bytes(size))
+        params = {
+            'name': data_utils.rand_name('image'),
+            'container_format': CONF.image.container_formats[0],
+            'disk_format': CONF.image.disk_formats[0],
+            'min_ram': min_img_ram
+        }
+
+        if CONF.image_feature_enabled.api_v1:
+            params.update({'is_public': False})
+            params = {'headers': common_image.image_meta_to_headers(**params)}
+        else:
+            params.update({'visibility': 'private'})
+
+        image = self.images_client.create_image(**params)
+        image = image['image'] if 'image' in image else image
+        self.addCleanup(self.images_client.delete_image, image['id'])
+
+        if CONF.image_feature_enabled.api_v1:
+            self.images_client.update_image(image['id'], data=image_file)
+        else:
+            self.images_client.store_image_file(image['id'], data=image_file)
+
+        self.assertEqual(min_img_ram, image['min_ram'])
+
+        # Try to create server with flavor of insufficient ram size
+        self.assertRaisesRegexp(lib_exc.BadRequest,
+                                "Flavor's memory is too small for "
+                                "requested image",
+                                self.create_test_server,
+                                image_id=image['id'],
+                                flavor=flavor['id'])
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index 4d8416f..2769245 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.api.compute.floating_ips import base
 from tempest import config
 from tempest.lib.common.utils import test_utils
@@ -86,6 +88,8 @@
 
     @decorators.idempotent_id('307efa27-dc6f-48a0-8cd2-162ce3ef0b52')
     @test.services('network')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_associate_disassociate_floating_ip(self):
         # Positive test:Associate and disassociate the provided floating IP
         # to a specific server should be successful
@@ -107,6 +111,8 @@
 
     @decorators.idempotent_id('6edef4b2-aaf1-4abc-bbe3-993e2561e0fe')
     @test.services('network')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_associate_already_associated_floating_ip(self):
         # positive test:Association of an already associated floating IP
         # to specific server should change the association of the Floating IP
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 7658848..b82fa3b 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -31,7 +31,6 @@
     @classmethod
     def resource_setup(cls):
         super(SecurityGroupRulesTestJSON, cls).resource_setup()
-        cls.neutron_available = CONF.service_available.neutron
         cls.ip_protocol = 'tcp'
         cls.from_port = 22
         cls.to_port = 22
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index ad18861..48bb1b6 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -32,11 +32,6 @@
         super(SecurityGroupsNegativeTestJSON, cls).setup_clients()
         cls.client = cls.security_groups_client
 
-    @classmethod
-    def resource_setup(cls):
-        super(SecurityGroupsNegativeTestJSON, cls).resource_setup()
-        cls.neutron_available = CONF.service_available.neutron
-
     @test.attr(type=['negative'])
     @decorators.idempotent_id('673eaec1-9b3e-48ed-bdf1-2786c1b9661c')
     @test.services('network')
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index d9e83a6..5bcbdac 100644
--- a/tempest/api/compute/servers/test_device_tagging.py
+++ b/tempest/api/compute/servers/test_device_tagging.py
@@ -20,6 +20,7 @@
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux import remote_client
 from tempest import config
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions
 from tempest import test
@@ -249,9 +250,9 @@
                 self.verify_device_metadata(md_json)
                 return True
 
-            if not test.call_until_true(get_and_verify_metadata,
-                                        CONF.compute.build_timeout,
-                                        CONF.compute.build_interval):
+            if not test_utils.call_until_true(get_and_verify_metadata,
+                                              CONF.compute.build_timeout,
+                                              CONF.compute.build_interval):
                 raise exceptions.TimeoutException('Timeout while verifying '
                                                   'metadata on server.')
 
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 594c5c9..3010caf 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -35,11 +35,9 @@
         # by the test methods in this class. These
         # servers are cleaned up automatically in the
         # tearDownClass method of the super-class.
-        cls.existing_fixtures = []
         cls.deleted_fixtures = []
         for _ in range(2):
             srv = cls.create_test_server(wait_until='ACTIVE')
-            cls.existing_fixtures.append(srv)
 
         srv = cls.create_test_server(wait_until='ACTIVE')
         cls.client.delete_server(srv['id'])
diff --git a/tempest/api/compute/servers/test_novnc.py b/tempest/api/compute/servers/test_novnc.py
index d10f370..04fe11f 100644
--- a/tempest/api/compute/servers/test_novnc.py
+++ b/tempest/api/compute/servers/test_novnc.py
@@ -22,7 +22,7 @@
 
 from tempest.api.compute import base
 from tempest import config
-from tempest import test
+from tempest.lib import decorators
 
 CONF = config.CONF
 
@@ -137,7 +137,7 @@
         # Turn the Socket into a WebSocket to do the communication
         return _WebSocket(client_socket, url)
 
-    @test.idempotent_id('c640fdff-8ab4-45a4-a5d8-7e6146cbd0dc')
+    @decorators.idempotent_id('c640fdff-8ab4-45a4-a5d8-7e6146cbd0dc')
     def test_novnc(self):
         body = self.client.get_vnc_console(self.server['id'],
                                            type='novnc')['console']
@@ -151,7 +151,7 @@
         # Validate the RFB Negotiation to determine if a valid VNC session
         self._validate_rfb_negotiation()
 
-    @test.idempotent_id('f9c79937-addc-4aaa-9e0e-841eef02aeb7')
+    @decorators.idempotent_id('f9c79937-addc-4aaa-9e0e-841eef02aeb7')
     def test_novnc_bad_token(self):
         body = self.client.get_vnc_console(self.server['id'],
                                            type='novnc')['console']
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 5db7f4f..f74a5a4 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest.common import waiters
@@ -85,6 +87,8 @@
                                        'ACTIVE')
 
     @decorators.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_rescued_vm_associate_dissociate_floating_ip(self):
         # Rescue the server
         self.servers_client.rescue_server(
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index dd9d408..0d8214f 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -44,13 +44,11 @@
         super(VolumesTestJSON, cls).resource_setup()
         # Create 3 Volumes
         cls.volume_list = []
-        cls.volume_id_list = []
         for _ in range(3):
             metadata = {'Type': 'work'}
             volume = cls.create_volume(metadata=metadata)
             volume = cls.client.show_volume(volume['id'])['volume']
             cls.volume_list.append(volume)
-            cls.volume_id_list.append(volume['id'])
 
     @decorators.idempotent_id('bc2dd1a0-15af-48e5-9990-f2e75a48325d')
     def test_volume_list(self):
diff --git a/tempest/api/identity/admin/v3/test_domains_negative.py b/tempest/api/identity/admin/v3/test_domains_negative.py
index 280a5a8..4555a6a 100644
--- a/tempest/api/identity/admin/v3/test_domains_negative.py
+++ b/tempest/api/identity/admin/v3/test_domains_negative.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 from tempest.api.identity import base
-from tempest.lib.common.utils import data_utils
+from tempest.common.utils import data_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 9515788..3bbe47a 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -67,7 +67,7 @@
             return role[0]
 
     def _create_test_user(self, **kwargs):
-        if kwargs['password'] is None:
+        if kwargs.get('password', None) is None:
             user_password = data_utils.rand_password()
             kwargs['password'] = user_password
         user = self.users_client.create_user(**kwargs)['user']
diff --git a/tempest/api/identity/v3/test_api_discovery.py b/tempest/api/identity/v3/test_api_discovery.py
index 74e9ec1..2eed3c8 100644
--- a/tempest/api/identity/v3/test_api_discovery.py
+++ b/tempest/api/identity/v3/test_api_discovery.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.api.identity import base
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -21,7 +22,7 @@
     """Tests for API discovery features."""
 
     @test.attr(type='smoke')
-    @test.idempotent_id('b9232f5e-d9e5-4d97-b96c-28d3db4de1bd')
+    @decorators.idempotent_id('b9232f5e-d9e5-4d97-b96c-28d3db4de1bd')
     def test_api_version_resources(self):
         descr = self.non_admin_client.show_api_description()['version']
         expected_resources = ('id', 'links', 'media-types', 'status',
@@ -32,7 +33,7 @@
             self.assertIn(res, keys)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('657c1970-4722-4189-8831-7325f3bc4265')
+    @decorators.idempotent_id('657c1970-4722-4189-8831-7325f3bc4265')
     def test_api_media_types(self):
         descr = self.non_admin_client.show_api_description()['version']
         # Get MIME type bases and descriptions
@@ -47,7 +48,7 @@
             self.assertIn(s_type, media_types)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('8879a470-abfb-47bb-bb8d-5a7fd279ad1e')
+    @decorators.idempotent_id('8879a470-abfb-47bb-bb8d-5a7fd279ad1e')
     def test_api_version_statuses(self):
         descr = self.non_admin_client.show_api_description()['version']
         status = descr['status'].lower()
diff --git a/tempest/api/identity/v3/test_projects.py b/tempest/api/identity/v3/test_projects.py
index 26cb90b..570be99 100644
--- a/tempest/api/identity/v3/test_projects.py
+++ b/tempest/api/identity/v3/test_projects.py
@@ -14,15 +14,15 @@
 #    under the License.
 
 from tempest.api.identity import base
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
-from tempest import test
 
 
 class IdentityV3ProjectsTest(base.BaseIdentityV3Test):
 
     credentials = ['primary', 'alt']
 
-    @test.idempotent_id('86128d46-e170-4644-866a-cc487f699e1d')
+    @decorators.idempotent_id('86128d46-e170-4644-866a-cc487f699e1d')
     def test_list_projects_returns_only_authorized_projects(self):
         alt_project_name =\
             self.alt_manager.credentials.project_name
diff --git a/tempest/api/identity/v3/test_tokens.py b/tempest/api/identity/v3/test_tokens.py
index b410da6..1dc1df6 100644
--- a/tempest/api/identity/v3/test_tokens.py
+++ b/tempest/api/identity/v3/test_tokens.py
@@ -16,12 +16,12 @@
 from oslo_utils import timeutils
 import six
 from tempest.api.identity import base
-from tempest import test
+from tempest.lib import decorators
 
 
 class TokensV3Test(base.BaseIdentityV3Test):
 
-    @test.idempotent_id('6f8e4436-fc96-4282-8122-e41df57197a9')
+    @decorators.idempotent_id('6f8e4436-fc96-4282-8122-e41df57197a9')
     def test_create_token(self):
 
         creds = self.os.credentials
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index 9592cb9..f263258 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -20,8 +20,8 @@
 from tempest.api.identity import base
 from tempest import config
 from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
 from tempest.lib import exceptions
-from tempest import test
 
 
 CONF = config.CONF
@@ -78,7 +78,7 @@
         time.sleep(1)
         self.non_admin_users_client.auth_provider.set_auth()
 
-    @test.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
+    @decorators.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
     def test_user_update_own_password(self):
         old_pass = self.creds.password
         old_token = self.non_admin_client.token
@@ -103,7 +103,7 @@
 
     @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
                           'Security compliance not available.')
-    @test.idempotent_id('941784ee-5342-4571-959b-b80dd2cea516')
+    @decorators.idempotent_id('941784ee-5342-4571-959b-b80dd2cea516')
     def test_password_history_check_self_service_api(self):
         old_pass = self.creds.password
         new_pass1 = data_utils.rand_password()
@@ -133,7 +133,7 @@
 
     @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
                           'Security compliance not available.')
-    @test.idempotent_id('a7ad8bbf-2cff-4520-8c1d-96332e151658')
+    @decorators.idempotent_id('a7ad8bbf-2cff-4520-8c1d-96332e151658')
     def test_user_account_lockout(self):
         password = self.creds.password
 
diff --git a/tempest/api/image/admin/v2/test_images.py b/tempest/api/image/admin/v2/test_images.py
index fc5ed79..11b595a 100644
--- a/tempest/api/image/admin/v2/test_images.py
+++ b/tempest/api/image/admin/v2/test_images.py
@@ -17,8 +17,8 @@
 import testtools
 
 from tempest.api.image import base
+from tempest.common.utils import data_utils
 from tempest import config
-from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 868771f..485c8f5 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -32,7 +32,7 @@
         # Create a network and make sure it will be hosted by a
         # dhcp agent: this is done by creating a regular port
         cls.network = cls.create_network()
-        cls.subnet = cls.create_subnet(cls.network)
+        cls.create_subnet(cls.network)
         cls.port = cls.create_port(cls.network)
 
     @decorators.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
diff --git a/tempest/api/network/admin/test_external_networks_negative.py b/tempest/api/network/admin/test_external_networks_negative.py
index 743089a..770d91f 100644
--- a/tempest/api/network/admin/test_external_networks_negative.py
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -12,6 +12,7 @@
 #    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 testtools
 
 from tempest.api.network import base
 from tempest import config
@@ -27,6 +28,8 @@
 
     @test.attr(type=['negative'])
     @decorators.idempotent_id('d402ae6c-0be0-4d8e-833b-a738895d98d0')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_create_port_with_precreated_floatingip_as_fixed_ip(self):
         # NOTE: External networks can be used to create both floating-ip as
         # well as instance-ip. So, creating an instance-ip with a value of a
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index c36323a..9a17817 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -31,6 +31,9 @@
         if not test.is_extension_enabled('router', 'network'):
             msg = "router extension not enabled."
             raise cls.skipException(msg)
+        if not CONF.network.public_network_id:
+            msg = "The public_network_id option must be specified."
+            raise cls.skipException(msg)
 
     @classmethod
     def setup_clients(cls):
@@ -43,9 +46,9 @@
         cls.ext_net_id = CONF.network.public_network_id
         cls.floating_ip = cls.create_floatingip(cls.ext_net_id)
         cls.network = cls.create_network()
-        cls.subnet = cls.create_subnet(cls.network)
-        cls.router = cls.create_router(external_network_id=cls.ext_net_id)
-        cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+        subnet = cls.create_subnet(cls.network)
+        router = cls.create_router(external_network_id=cls.ext_net_id)
+        cls.create_router_interface(router['id'], subnet['id'])
         cls.port = cls.create_port(cls.network)
 
     @decorators.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index 5a54ae0..e1970b9 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -79,7 +79,7 @@
                     cls.router['id'])['router'].get('distributed', False)
                 if cls.is_dvr_router:
                     cls.network = cls.create_network()
-                    cls.subnet = cls.create_subnet(cls.network)
+                    cls.create_subnet(cls.network)
                     cls.port = cls.create_port(cls.network)
                     cls.routers_client.add_router_interface(
                         cls.router['id'], port_id=cls.port['id'])
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index fa4010d..136f9e6 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import netaddr
 import random
 
+import netaddr
+
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest.common.utils import net_info
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index 52507f9..1156275 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -43,16 +43,16 @@
     def resource_setup(cls):
         super(ExtraDHCPOptionsTestJSON, cls).resource_setup()
         cls.network = cls.create_network()
-        cls.subnet = cls.create_subnet(cls.network)
+        cls.create_subnet(cls.network)
         cls.port = cls.create_port(cls.network)
-        cls.ip_tftp = ('123.123.123.123' if cls._ip_version == 4
-                       else '2015::dead')
-        cls.ip_server = ('123.123.123.45' if cls._ip_version == 4
-                         else '2015::badd')
+        ip_tftp = ('123.123.123.123' if cls._ip_version == 4
+                   else '2015::dead')
+        ip_server = ('123.123.123.45' if cls._ip_version == 4
+                     else '2015::badd')
         cls.extra_dhcp_opts = [
             {'opt_value': 'pxelinux.0', 'opt_name': 'bootfile-name'},
-            {'opt_value': cls.ip_tftp, 'opt_name': 'tftp-server'},
-            {'opt_value': cls.ip_server, 'opt_name': 'server-ip-address'}
+            {'opt_value': ip_tftp, 'opt_name': 'tftp-server'},
+            {'opt_value': ip_server, 'opt_name': 'server-ip-address'}
         ]
 
     @decorators.idempotent_id('d2c17063-3767-4a24-be4f-a23dbfa133c9')
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 23614d6..1dc574b 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -46,6 +46,9 @@
         if not test.is_extension_enabled('router', 'network'):
             msg = "router extension not enabled."
             raise cls.skipException(msg)
+        if not CONF.network.public_network_id:
+            msg = "The public_network_id option must be specified."
+            raise cls.skipException(msg)
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index 9ccda05..cb29d3d 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -37,6 +37,9 @@
         if not test.is_extension_enabled('router', 'network'):
             msg = "router extension not enabled."
             raise cls.skipException(msg)
+        if not CONF.network.public_network_id:
+            msg = "The public_network_id option must be specified."
+            raise cls.skipException(msg)
 
     @classmethod
     def resource_setup(cls):
@@ -44,9 +47,9 @@
         cls.ext_net_id = CONF.network.public_network_id
         # Create a network with a subnet connected to a router.
         cls.network = cls.create_network()
-        cls.subnet = cls.create_subnet(cls.network)
-        cls.router = cls.create_router()
-        cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+        subnet = cls.create_subnet(cls.network)
+        router = cls.create_router()
+        cls.create_router_interface(router['id'], subnet['id'])
         cls.port = cls.create_port(cls.network)
 
     @test.attr(type=['negative'])
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 1426798..69d4ebe 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -34,7 +34,6 @@
     def resource_setup(cls):
         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,
                                                                cls._ip_version)
         cls._subnet_data = {6: {'gateway':
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 524ab9e..694b86b 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 import netaddr
+import testtools
 
 from tempest.api.network import base_routers as base
 from tempest.common.utils import data_utils
@@ -42,6 +43,8 @@
 
     @test.attr(type='smoke')
     @decorators.idempotent_id('f64403e2-8483-4b34-8ccd-b09a87bcc68c')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_create_show_list_update_delete_router(self):
         # Create a router
         router = self._create_router(
@@ -89,6 +92,8 @@
 
     @decorators.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
     @test.requires_ext(extension='ext-gw-mode', service='network')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_create_router_with_default_snat_value(self):
         # Create a router with default snat rule
         router = self._create_router(
@@ -99,6 +104,8 @@
 
     @decorators.idempotent_id('ea74068d-09e9-4fd7-8995-9b6a1ace920f')
     @test.requires_ext(extension='ext-gw-mode', service='network')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_create_router_with_snat_explicit(self):
         name = data_utils.rand_name('snat-router')
         # Create a router enabling snat attributes
@@ -184,6 +191,8 @@
             self.assertIn(subnet_id, public_subnet_ids)
 
     @decorators.idempotent_id('6cc285d8-46bf-4f36-9b1a-783e3008ba79')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_update_router_set_gateway(self):
         router = self._create_router()
         self.routers_client.update_router(
@@ -198,6 +207,8 @@
 
     @decorators.idempotent_id('b386c111-3b21-466d-880c-5e72b01e1a33')
     @test.requires_ext(extension='ext-gw-mode', service='network')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_update_router_set_gateway_with_snat_explicit(self):
         router = self._create_router()
         self.admin_routers_client.update_router(
@@ -213,6 +224,8 @@
 
     @decorators.idempotent_id('96536bc7-8262-4fb2-9967-5c46940fa279')
     @test.requires_ext(extension='ext-gw-mode', service='network')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_update_router_set_gateway_without_snat(self):
         router = self._create_router()
         self.admin_routers_client.update_router(
@@ -227,6 +240,8 @@
         self._verify_gateway_port(router['id'])
 
     @decorators.idempotent_id('ad81b7ee-4f81-407b-a19c-17e623f763e8')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_update_router_unset_gateway(self):
         router = self._create_router(
             external_network_id=CONF.network.public_network_id)
@@ -241,6 +256,8 @@
 
     @decorators.idempotent_id('f2faf994-97f4-410b-a831-9bc977b64374')
     @test.requires_ext(extension='ext-gw-mode', service='network')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     def test_update_router_reset_gateway_without_snat(self):
         router = self._create_router(
             external_network_id=CONF.network.public_network_id)
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index e0216fd..642c1ac 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -16,8 +16,8 @@
 import time
 
 from tempest.common import custom_matchers
+from tempest.common.utils import data_utils
 from tempest import config
-from tempest.lib.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
 from tempest.lib import exceptions as lib_exc
 import tempest.test
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index d779d42..cf7dbe8 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -253,6 +253,18 @@
             self.assertEqual(True, container.decode(
                 'utf-8').startswith(prefix))
 
+    @decorators.idempotent_id('b1811cff-d1ed-4c15-a52e-efd8de41cf34')
+    def test_list_containers_reverse_order(self):
+        # list containers in reverse order
+        _, orig_container_list = self.account_client.list_account_containers()
+
+        params = {'reverse': True}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertEqual(sorted(orig_container_list, reverse=True),
+                         container_list)
+
     @test.attr(type='smoke')
     @decorators.idempotent_id('4894c312-6056-4587-8d6f-86ffbf861f80')
     def test_list_account_metadata(self):
@@ -291,7 +303,7 @@
         self.account_client.delete_account_metadata(metadata)
 
     @decorators.idempotent_id('9f60348d-c46f-4465-ae06-d51dbd470953')
-    def test_update_account_metadata_with_delete_matadata(self):
+    def test_update_account_metadata_with_delete_metadata(self):
         # delete metadata from account
         metadata = {'test-account-meta1': 'Meta1'}
         self.account_client.create_account_metadata(metadata)
@@ -302,7 +314,7 @@
         self.assertNotIn('x-account-meta-test-account-meta1', resp)
 
     @decorators.idempotent_id('64fd53f3-adbd-4639-af54-436e4982dbfb')
-    def test_update_account_metadata_with_create_matadata_key(self):
+    def test_update_account_metadata_with_create_metadata_key(self):
         # if the value of metadata is not set, the metadata is not
         # registered at a server
         metadata = {'test-account-meta1': ''}
@@ -313,7 +325,7 @@
         self.assertNotIn('x-account-meta-test-account-meta1', resp)
 
     @decorators.idempotent_id('d4d884d3-4696-4b85-bc98-4f57c4dd2bf1')
-    def test_update_account_metadata_with_delete_matadata_key(self):
+    def test_update_account_metadata_with_delete_metadata_key(self):
         # Although the value of metadata is not set, the feature of
         # deleting metadata is valid
         metadata_1 = {'test-account-meta1': 'Meta1'}
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index 4b65584..2e617f3 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 from tempest.api.object_storage import base
-from tempest.lib.common.utils import data_utils
+from tempest.common.utils import data_utils
 from tempest.lib import decorators
 from tempest import test
 
@@ -166,7 +166,7 @@
         container_name = self.create_container()
         object_name, _ = self.create_object(container_name)
 
-        params = {'end_marker': 'ZzzzObject1234567890'}
+        params = {'end_marker': object_name + 'zzzz'}
         resp, object_list = self.container_client.list_container_contents(
             container_name,
             params=params)
@@ -246,7 +246,8 @@
     def test_list_container_contents_with_path(self):
         # get container contents list using path param
         container_name = self.create_container()
-        object_name = data_utils.rand_name(name='Swift/TestObject')
+        object_name = data_utils.rand_name(name='TestObject')
+        object_name = 'Swift/' + object_name
         self.create_object(container_name, object_name)
 
         params = {'path': 'Swift'}
diff --git a/tempest/api/object_storage/test_container_services_negative.py b/tempest/api/object_storage/test_container_services_negative.py
index be066ba..ebbb84e 100644
--- a/tempest/api/object_storage/test_container_services_negative.py
+++ b/tempest/api/object_storage/test_container_services_negative.py
@@ -16,8 +16,8 @@
 import testtools
 
 from tempest.api.object_storage import base
+from tempest.common.utils import data_utils
 from tempest import config
-from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions
 from tempest import test
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 72d71c7..f68f19a 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -37,7 +37,6 @@
         cls.backend_names = set(CONF.volume.backend_names)
 
         cls.name_field = cls.special_fields['name_field']
-        cls.volume_type_id_list = []
         cls.volume_id_list_with_prefix = []
         cls.volume_id_list_without_prefix = []
 
@@ -63,8 +62,8 @@
             extra_specs = {spec_key_with_prefix: backend_name_key}
         else:
             extra_specs = {spec_key_without_prefix: backend_name_key}
-        cls.type = cls.create_volume_type(name=type_name,
-                                          extra_specs=extra_specs)
+        cls.create_volume_type(name=type_name,
+                               extra_specs=extra_specs)
 
         params = {cls.name_field: vol_name, 'volume_type': type_name,
                   'size': CONF.volume.volume_size}
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 8d94cd2..5477770 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -30,7 +30,6 @@
 
         cls.client = cls.volumes_client
         cls.alt_client = cls.os_alt.volumes_client
-        cls.alt_tenant_id = cls.alt_client.tenant_id
         cls.adm_client = cls.os_adm.volumes_client
 
     @decorators.idempotent_id('4d75b645-a478-48b1-97c8-503f64242f1a')
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 9b17515..4776545 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -15,6 +15,7 @@
 #    under the License.
 
 import random
+
 from six.moves.urllib import parse
 
 from tempest.api.volume import base
diff --git a/tempest/api/volume/v2/test_volumes_snapshots_list.py b/tempest/api/volume/v2/test_volumes_snapshots_list.py
index f389b59..e2f11e8 100644
--- a/tempest/api/volume/v2/test_volumes_snapshots_list.py
+++ b/tempest/api/volume/v2/test_volumes_snapshots_list.py
@@ -15,7 +15,7 @@
 
 from tempest.api.volume import base
 from tempest import config
-from tempest import test
+from tempest.lib import decorators
 
 CONF = config.CONF
 
@@ -34,7 +34,6 @@
         cls.snapshot_id_list = []
         # Create a volume
         cls.volume_origin = cls.create_volume()
-        cls.name_field = cls.special_fields['name_field']
         # Create 3 snapshots
         for _ in range(3):
             snapshot = cls.create_snapshot(cls.volume_origin['id'])
@@ -56,33 +55,33 @@
         self.assertEqual(sorted(sorted_list, reverse=(sort_dir == 'desc')),
                          sorted_list, msg)
 
-    @test.idempotent_id('c5513ada-64c1-4d28-83b9-af3307ec1388')
+    @decorators.idempotent_id('c5513ada-64c1-4d28-83b9-af3307ec1388')
     def test_snapshot_list_param_sort_id_asc(self):
         self._list_snapshots_param_sort(sort_key='id', sort_dir='asc')
 
-    @test.idempotent_id('8a7fe058-0b41-402a-8afd-2dbc5a4a718b')
+    @decorators.idempotent_id('8a7fe058-0b41-402a-8afd-2dbc5a4a718b')
     def test_snapshot_list_param_sort_id_desc(self):
         self._list_snapshots_param_sort(sort_key='id', sort_dir='desc')
 
-    @test.idempotent_id('4052c3a0-2415-440a-a8cc-305a875331b0')
+    @decorators.idempotent_id('4052c3a0-2415-440a-a8cc-305a875331b0')
     def test_snapshot_list_param_sort_created_at_asc(self):
         self._list_snapshots_param_sort(sort_key='created_at', sort_dir='asc')
 
-    @test.idempotent_id('dcbbe24a-f3c0-4ec8-9274-55d48db8d1cf')
+    @decorators.idempotent_id('dcbbe24a-f3c0-4ec8-9274-55d48db8d1cf')
     def test_snapshot_list_param_sort_created_at_desc(self):
         self._list_snapshots_param_sort(sort_key='created_at', sort_dir='desc')
 
-    @test.idempotent_id('d58b5fed-0c37-42d3-8c5d-39014ac13c00')
+    @decorators.idempotent_id('d58b5fed-0c37-42d3-8c5d-39014ac13c00')
     def test_snapshot_list_param_sort_name_asc(self):
         self._list_snapshots_param_sort(sort_key='display_name',
                                         sort_dir='asc')
 
-    @test.idempotent_id('96ba6f4d-1f18-47e1-b4bc-76edc6c21250')
+    @decorators.idempotent_id('96ba6f4d-1f18-47e1-b4bc-76edc6c21250')
     def test_snapshot_list_param_sort_name_desc(self):
         self._list_snapshots_param_sort(sort_key='display_name',
                                         sort_dir='desc')
 
-    @test.idempotent_id('05489dde-44bc-4961-a1f5-3ce7ee7824f7')
+    @decorators.idempotent_id('05489dde-44bc-4961-a1f5-3ce7ee7824f7')
     def test_snapshot_list_param_marker(self):
         # The list of snapshots should end before the provided marker
         params = {'marker': self.snapshot_id_list[1]}
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 01de704..55bc93e 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -17,10 +17,10 @@
 from oslo_utils import excutils
 
 from tempest.common import fixed_network
+from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
 from tempest.lib.common import rest_client
-from tempest.lib.common.utils import data_utils
 
 CONF = config.CONF
 
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 632a876..88fe26c 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -293,12 +293,12 @@
         return resp_body['subnet']
 
     def _create_router(self, router_name, tenant_id):
-        external_net_id = dict(
-            network_id=self.public_network_id)
-        resp_body = self.routers_admin_client.create_router(
-            name=router_name,
-            external_gateway_info=external_net_id,
-            tenant_id=tenant_id)
+        kwargs = {'name': router_name,
+                  'tenant_id': tenant_id}
+        if self.public_network_id:
+            kwargs['external_gateway_info'] = dict(
+                network_id=self.public_network_id)
+        resp_body = self.routers_admin_client.create_router(**kwargs)
         return resp_body['router']
 
     def _add_router_interface(self, router_id, subnet_id):
diff --git a/tempest/common/fixed_network.py b/tempest/common/fixed_network.py
index f50edbd..4032c90 100644
--- a/tempest/common/fixed_network.py
+++ b/tempest/common/fixed_network.py
@@ -11,6 +11,7 @@
 #    under the License.
 
 import copy
+
 from oslo_log import log as logging
 
 from tempest import exceptions
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 009812e..1487c1d 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -10,12 +10,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import netaddr
 import re
-import six
 import sys
 import time
 
+import netaddr
+import six
+
 from oslo_log import log as logging
 
 from tempest import config
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 865db39..15619f4 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -121,7 +121,7 @@
                      '/'.join((server_status, str(task_state))),
                      time.time() - start_time)
         if server_status == 'ERROR' and not ignore_error:
-            raise exceptions.BuildErrorException(server_id=server_id)
+            raise lib_exc.DeleteErrorException(resource_id=server_id)
 
         if int(time.time()) - start_time >= client.build_timeout:
             raise lib_exc.TimeoutException
@@ -218,7 +218,7 @@
                        'within the required time (%s s).' %
                        (volume_id, new_volume_type, current_volume_type,
                         client.build_timeout))
-            raise exceptions.TimeoutException(message)
+            raise lib_exc.TimeoutException(message)
 
 
 def wait_for_snapshot_status(client, snapshot_id, status):
diff --git a/tempest/config.py b/tempest/config.py
index 915b99d..bd19967 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -310,8 +310,7 @@
                     "min_microversion and max_microversion. "
                     "If both values are not specified, Tempest avoids tests "
                     "which require a microversion. Valid values are string "
-                    "with format 'X.Y' or string 'latest'",
-                    deprecated_group='compute-feature-enabled'),
+                    "with format 'X.Y' or string 'latest'"),
     cfg.StrOpt('max_microversion',
                default=None,
                help="Upper version of the test target microversion range. "
@@ -320,8 +319,7 @@
                     "min_microversion and max_microversion. "
                     "If both values are not specified, Tempest avoids tests "
                     "which require a microversion. Valid values are string "
-                    "with format 'X.Y' or string 'latest'",
-                    deprecated_group='compute-feature-enabled'),
+                    "with format 'X.Y' or string 'latest'"),
 ]
 
 compute_features_group = cfg.OptGroup(name='compute-feature-enabled',
@@ -537,23 +535,18 @@
                         'publicURL', 'adminURL', 'internalURL'],
                help="The endpoint type to use for the network service."),
     cfg.StrOpt('project_network_cidr',
-               deprecated_name='tenant_network_cidr',
                default="10.100.0.0/16",
                help="The cidr block to allocate project ipv4 subnets from"),
     cfg.IntOpt('project_network_mask_bits',
-               deprecated_name='tenant_network_mask_bits',
                default=28,
                help="The mask bits for project ipv4 subnets"),
     cfg.StrOpt('project_network_v6_cidr',
-               deprecated_name='tenant_network_v6_cidr',
                default="2003::/48",
                help="The cidr block to allocate project ipv6 subnets from"),
     cfg.IntOpt('project_network_v6_mask_bits',
-               deprecated_name='tenant_network_v6_mask_bits',
                default=64,
                help="The mask bits for project ipv6 subnets"),
     cfg.BoolOpt('project_networks_reachable',
-                deprecated_name='tenant_networks_reachable',
                 default=False,
                 help="Whether project networks can be reached directly from "
                      "the test client. This must be set to True when the "
@@ -1021,32 +1014,6 @@
 """)
 ]
 
-input_scenario_group = cfg.OptGroup(name="input-scenario",
-                                    title="Filters and values for"
-                                          " input scenarios[DEPRECATED]")
-
-
-InputScenarioGroup = [
-    cfg.StrOpt('image_regex',
-               default='^cirros-0.3.1-x86_64-uec$',
-               help="Matching images become parameters for scenario tests",
-               deprecated_for_removal=True),
-    cfg.StrOpt('flavor_regex',
-               default='^m1.nano$',
-               help="Matching flavors become parameters for scenario tests",
-               deprecated_for_removal=True),
-    cfg.StrOpt('non_ssh_image_regex',
-               default='^.*[Ww]in.*$',
-               help="SSH verification in tests is skipped"
-                    "for matching images",
-               deprecated_for_removal=True),
-    cfg.StrOpt('ssh_user_regex',
-               default="[[\"^.*[Cc]irros.*$\", \"cirros\"]]",
-               help="List of user mapped to regex "
-                    "to matching image names.",
-               deprecated_for_removal=True),
-]
-
 DefaultGroup = [
     cfg.StrOpt('resources_prefix',
                default='tempest',
@@ -1076,7 +1043,6 @@
     (scenario_group, ScenarioGroup),
     (service_available_group, ServiceAvailableGroup),
     (debug_group, DebugGroup),
-    (input_scenario_group, InputScenarioGroup),
     (None, DefaultGroup)
 ]
 
@@ -1138,7 +1104,6 @@
         self.scenario = _CONF.scenario
         self.service_available = _CONF.service_available
         self.debug = _CONF.debug
-        self.input_scenario = _CONF['input-scenario']
         logging.tempest_set_log_file('tempest.log')
 
     def __init__(self, parse_conf=True, config_path=None):
diff --git a/tempest/lib/cmd/check_uuid.py b/tempest/lib/cmd/check_uuid.py
index 2fe957b..283b10f 100755
--- a/tempest/lib/cmd/check_uuid.py
+++ b/tempest/lib/cmd/check_uuid.py
@@ -27,6 +27,7 @@
 import six.moves.urllib.parse as urlparse
 
 # TODO(oomichi): Need to remove this after switching all modules to decorators
+# on all OpenStack projects because they runs check-uuid on their own gates.
 OLD_DECORATOR_MODULE = 'test'
 
 DECORATOR_MODULE = 'decorators'
@@ -120,7 +121,7 @@
 
     @staticmethod
     def _get_idempotent_id(test_node):
-        """Return key-value dict with all metadata from @test.idempotent_id"""
+        "Return key-value dict with metadata from @decorators.idempotent_id"
         idempotent_id = None
         for decorator in test_node.decorator_list:
             if (hasattr(decorator, 'func') and
@@ -308,7 +309,8 @@
         Returns true if untagged tests exist.
         """
         def report(module_name, test_name, tests):
-            error_str = "%s:%s\nmissing @test.idempotent_id('...')\n%s\n" % (
+            error_str = ("%s:%s\nmissing @decorators.idempotent_id"
+                         "('...')\n%s\n") % (
                 tests[module_name]['source_path'],
                 tests[module_name]['tests'][test_name].lineno,
                 test_name
@@ -356,7 +358,8 @@
     else:
         errors = checker.report_untagged(untagged) or errors
     if errors:
-        sys.exit("@test.idempotent_id existence and uniqueness checks failed\n"
+        sys.exit("@decorators.idempotent_id existence and uniqueness checks "
+                 "failed\n"
                  "Run 'tox -v -euuidgen' to automatically fix tests with\n"
                  "missing @test.idempotent_id decorators.")
 
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index d0e21ff..f5bff20 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -617,6 +617,7 @@
         :raises BadRequest: If a 400 response code is received
         :raises Gone: If a 410 response code is received
         :raises Conflict: If a 409 response code is received
+        :raises PreconditionFailed: If a 412 response code is received
         :raises OverLimit: If a 413 response code is received and over_limit is
                           not in the response body
         :raises RateLimitExceeded: If a 413 response code is received and
@@ -775,6 +776,11 @@
                 resp_body = self._parse_resp(resp_body)
             raise exceptions.Conflict(resp_body, resp=resp)
 
+        if resp.status == 412:
+            if parse_resp:
+                resp_body = self._parse_resp(resp_body)
+            raise exceptions.PreconditionFailed(resp_body, resp=resp)
+
         if resp.status == 413:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
diff --git a/tempest/lib/common/utils/data_utils.py b/tempest/lib/common/utils/data_utils.py
index 75c2e51..642514b 100644
--- a/tempest/lib/common/utils/data_utils.py
+++ b/tempest/lib/common/utils/data_utils.py
@@ -14,12 +14,12 @@
 #    under the License.
 
 import itertools
-import netaddr
 import random
 import string
 import uuid
 
 from debtcollector import removals
+import netaddr
 from oslo_utils import netutils
 from oslo_utils import uuidutils
 import six.moves
diff --git a/tempest/lib/exceptions.py b/tempest/lib/exceptions.py
index 108ba70..dea3289 100644
--- a/tempest/lib/exceptions.py
+++ b/tempest/lib/exceptions.py
@@ -101,6 +101,11 @@
     message = "The requested resource is no longer available"
 
 
+class PreconditionFailed(ClientRestClientException):
+    status_code = 412
+    message = "Precondition Failed"
+
+
 class RateLimitExceeded(ClientRestClientException):
     status_code = 413
     message = "Rate limit exceeded"
@@ -259,3 +264,8 @@
 
 class VolumeBackupException(TempestException):
     message = "Volume backup %(backup_id)s failed and is in ERROR status"
+
+
+class DeleteErrorException(TempestException):
+    message = ("Resource %(resource_id)s failed to delete "
+               "and is in ERROR status")
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index 50ce32e..f16ef88 100644
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -30,6 +30,8 @@
 
 
 class ServersClient(base_compute_client.BaseComputeClient):
+    """Service client for the resource /servers"""
+
     schema_versions_info = [
         {'min': None, 'max': '2.2', 'schema': schema},
         {'min': '2.3', 'max': '2.8', 'schema': schemav23},
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 738ed61..27c45cb 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.common import custom_matchers
 from tempest.common import waiters
 from tempest import config
@@ -99,6 +101,8 @@
                     return address
 
     @decorators.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     @test.services('compute', 'volume', 'image', 'network')
     def test_minimum_basic_scenario(self):
         image = self.glance_image_create()
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index fda407c..5565cb8 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -241,9 +241,11 @@
         self.assertIn(tenant.router['id'], seen_router_ids)
 
         myport = (tenant.router['id'], tenant.subnet['id'])
-        router_ports = [(i['device_id'], i['fixed_ips'][0]['subnet_id']) for i
-                        in self._list_ports()
-                        if net_info.is_router_interface_port(i)]
+        router_ports = [
+            (i['device_id'], f['subnet_id'])
+            for i in self._list_ports(device_id=tenant.router['id'])
+            if net_info.is_router_interface_port(i)
+            for f in i['fixed_ips']]
 
         self.assertIn(myport, router_ports)
 
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 8a3b70d..ddbaf5a 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -45,8 +45,6 @@
 
     def setUp(self):
         super(TestServerBasicOps, self).setUp()
-        self.image_ref = CONF.compute.image_ref
-        self.flavor_ref = CONF.compute.flavor_ref
         self.run_ssh = CONF.validation.run_validation
         self.ssh_user = CONF.validation.image_ssh_user
 
@@ -133,8 +131,6 @@
         security_group = self._create_security_group()
         self.md = {'meta1': 'data1', 'meta2': 'data2', 'metaN': 'dataN'}
         self.instance = self.create_server(
-            image_id=self.image_ref,
-            flavor=self.flavor_ref,
             key_name=keypair['name'],
             security_groups=[{'name': security_group['name']}],
             config_drive=CONF.compute_feature_enabled.config_drive,
diff --git a/tempest/scenario/test_server_multinode.py b/tempest/scenario/test_server_multinode.py
index 9cc89a4..db91a21 100644
--- a/tempest/scenario/test_server_multinode.py
+++ b/tempest/scenario/test_server_multinode.py
@@ -77,6 +77,8 @@
             inst = self.create_server(
                 availability_zone='%(zone)s:%(host_name)s' % host)
             server = self.servers_client.show_server(inst['id'])['server']
+            # ensure server is located on the requested host
+            self.assertEqual(host['host_name'], server['OS-EXT-SRV-ATTR:host'])
             servers.append(server)
 
         # make sure we really have the number of servers we think we should
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index e950766..75cef88 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.common import compute
 from tempest.common import waiters
 from tempest import config
@@ -55,7 +57,6 @@
         security_groups = [{'name': security_group['name']}]
 
         server = self.create_server(
-            image_id=CONF.compute.image_ref,
             key_name=keypair['name'],
             security_groups=security_groups,
             volume_backed=boot_from_volume)
@@ -74,11 +75,15 @@
         self.assertEqual(timestamp, timestamp2)
 
     @decorators.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     @test.services('compute', 'network', 'image')
     def test_shelve_instance(self):
         self._create_server_then_shelve_and_unshelve()
 
     @decorators.idempotent_id('c1b6318c-b9da-490b-9c67-9339b627271f')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     @test.services('compute', 'volume', 'network', 'image')
     def test_shelve_volume_backed_instance(self):
         self._create_server_then_shelve_and_unshelve(boot_from_volume=True)
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 8197d52..6dedd1d 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest import config
 from tempest.lib import decorators
 from tempest.scenario import manager
@@ -39,6 +41,8 @@
             raise cls.skipException("Snapshotting is not available.")
 
     @decorators.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     @test.services('compute', 'network', 'image')
     def test_snapshot_pattern(self):
         # prepare for booting an instance
@@ -47,7 +51,6 @@
 
         # boot an instance and create a timestamp file in it
         server = self.create_server(
-            image_id=CONF.compute.image_ref,
             key_name=keypair['name'],
             security_groups=[{'name': security_group['name']}])
 
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index cc54a39..8661217 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -91,6 +91,8 @@
     @decorators.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     @test.services('compute', 'network', 'volume', 'image')
     def test_stamp_pattern(self):
         # prepare for booting an instance
@@ -100,7 +102,6 @@
         # boot an instance and create a timestamp file in it
         volume = self.create_volume()
         server = self.create_server(
-            image_id=CONF.compute.image_ref,
             key_name=keypair['name'],
             security_groups=[{'name': security_group['name']}])
 
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 5254082..43dcf96 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -11,6 +11,7 @@
 #    under the License.
 
 from oslo_log import log as logging
+import testtools
 
 from tempest.common.utils import data_utils
 from tempest.common import waiters
@@ -98,6 +99,8 @@
 
     @decorators.idempotent_id('557cd2c2-4eb8-4dce-98be-f86765ff311b')
     @test.attr(type='smoke')
+    @testtools.skipUnless(CONF.network.public_network_id,
+                          'The public_network_id option must be specified.')
     @test.services('compute', 'volume', 'image')
     def test_volume_boot_pattern(self):
 
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index 9932b4a..4859e75 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -128,6 +128,13 @@
             than the specified marker.
             DEFAULT: No Marker
 
+        prefix=[string value Y]
+            Given string value Y, return object names starting with that prefix
+
+        reverse=[boolean value Z]
+            Reverse the result order based on the boolean value Z
+            DEFAULT: False
+
         format=[string value, either 'json' or 'xml']
             Specify either json or xml to return the respective serialized
             response.
diff --git a/tempest/test.py b/tempest/test.py
index 039afa1..06de520 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -39,7 +39,11 @@
 
 CONF = config.CONF
 
-idempotent_id = decorators.idempotent_id
+# TODO(oomichi): This test.idempotent_id should be removed after all projects
+# switch to use decorators.idempotent_id.
+idempotent_id = debtcollector.moves.moved_function(
+    decorators.idempotent_id, 'idempotent_id', __name__,
+    version='Mitaka', removal_version='?')
 
 
 def attr(**kwargs):
diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py
index 1c9982c..2fd375d 100644
--- a/tempest/tests/common/test_preprov_creds.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -14,14 +14,15 @@
 
 import hashlib
 import os
-import testtools
+import shutil
 
 import mock
+import six
+import testtools
+
 from oslo_concurrency.fixture import lockutils as lockutils_fixtures
 from oslo_config import cfg
 from oslotest import mockpatch
-import shutil
-import six
 
 from tempest.common import preprov_creds
 from tempest import config
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index e4f4c04..5be6229 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -12,9 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import fixtures
 import time
 
+import fixtures
 from oslo_config import cfg
 from oslotest import mockpatch
 
diff --git a/tempest/tests/lib/cli/test_execute.py b/tempest/tests/lib/cli/test_execute.py
index aaeb6f4..0130454 100644
--- a/tempest/tests/lib/cli/test_execute.py
+++ b/tempest/tests/lib/cli/test_execute.py
@@ -11,9 +11,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
 import subprocess
 
+import mock
+
 from tempest.lib.cli import base as cli_base
 from tempest.lib import exceptions
 from tempest.tests import base
diff --git a/tempest/tests/lib/services/compute/test_versions_client.py b/tempest/tests/lib/services/compute/test_versions_client.py
index 06ecdc3..255a0a3 100644
--- a/tempest/tests/lib/services/compute/test_versions_client.py
+++ b/tempest/tests/lib/services/compute/test_versions_client.py
@@ -13,6 +13,7 @@
 #    under the License.
 
 import copy
+
 from oslotest import mockpatch
 
 from tempest.lib.services.compute import versions_client
diff --git a/tempest/tests/lib/services/test_clients.py b/tempest/tests/lib/services/test_clients.py
index 5db932c..a3b390e 100644
--- a/tempest/tests/lib/services/test_clients.py
+++ b/tempest/tests/lib/services/test_clients.py
@@ -12,10 +12,11 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+import types
+
 import fixtures
 import mock
 import testtools
-import types
 
 from tempest.lib import auth
 from tempest.lib import exceptions
diff --git a/tempest/tests/lib/test_auth.py b/tempest/tests/lib/test_auth.py
index 2f975d2..ac13a13 100644
--- a/tempest/tests/lib/test_auth.py
+++ b/tempest/tests/lib/test_auth.py
@@ -15,9 +15,9 @@
 
 import copy
 import datetime
-import testtools
 
 from oslotest import mockpatch
+import testtools
 
 from tempest.lib import auth
 from tempest.lib import exceptions
diff --git a/tempest/tests/lib/test_rest_client.py b/tempest/tests/lib/test_rest_client.py
index e6cf047..4a83631 100644
--- a/tempest/tests/lib/test_rest_client.py
+++ b/tempest/tests/lib/test_rest_client.py
@@ -337,6 +337,10 @@
     def test_response_410(self):
         self._test_error_checker(exceptions.Gone, self.set_data("410"))
 
+    def test_response_412(self):
+        self._test_error_checker(exceptions.PreconditionFailed,
+                                 self.set_data("412"))
+
     def test_response_413(self):
         self._test_error_checker(exceptions.OverLimit, self.set_data("413"))
 
@@ -460,7 +464,7 @@
 
     def test_response_bigger_than_400(self):
         # Any response code, that bigger than 400, and not in
-        # (401, 403, 404, 409, 413, 422, 500, 501)
+        # (401, 403, 404, 409, 412, 413, 422, 500, 501)
         self._test_error_checker(exceptions.UnexpectedResponseCode,
                                  self.set_data("402"))
 
diff --git a/tempest/tests/test_list_tests.py b/tempest/tests/test_list_tests.py
index 38d4c5c..a238879 100644
--- a/tempest/tests/test_list_tests.py
+++ b/tempest/tests/test_list_tests.py
@@ -14,9 +14,10 @@
 
 import os
 import re
-import six
 import subprocess
 
+import six
+
 from tempest.tests import base
 
 
diff --git a/test-requirements.txt b/test-requirements.txt
index 475fb16..f7d63a8 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -9,3 +9,4 @@
 mock>=2.0 # BSD
 coverage>=4.0 # Apache-2.0
 oslotest>=1.10.0 # Apache-2.0
+flake8-import-order==0.11 # LGPLv3
diff --git a/tools/check_logs.py b/tools/check_logs.py
index caad85c..f82b387 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -19,10 +19,10 @@
 import gzip
 import os
 import re
-import six
-import six.moves.urllib.request as urlreq
 import sys
 
+import six
+import six.moves.urllib.request as urlreq
 import yaml
 
 
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index f2da27a..2ba8b16 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -18,9 +18,10 @@
 import gzip
 import pprint
 import re
+import sys
+
 import six
 import six.moves.urllib.request as urlreq
-import sys
 
 
 pp = pprint.PrettyPrinter()
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
index 03e838e..acb29af 100644
--- a/tools/generate-tempest-plugins-list.py
+++ b/tools/generate-tempest-plugins-list.py
@@ -25,6 +25,7 @@
 
 import json
 import re
+
 import requests
 
 url = 'https://review.openstack.org/projects/'
diff --git a/tox.ini b/tox.ini
index 46823d8..d8d390e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -147,6 +147,7 @@
 show-source = True
 exclude = .git,.venv,.tox,dist,doc,*egg
 enable-extensions = H106,H203,H904
+import-order-style = pep8
 
 [testenv:releasenotes]
 commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html