Merge "Remove deprecated network config options"
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/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/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/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_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/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/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/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_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/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..3deb437 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
 
@@ -56,33 +56,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/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..b7b02ab 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -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 b7312fd..e9b74b4 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',
@@ -1030,32 +1028,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',
@@ -1085,7 +1057,6 @@
     (scenario_group, ScenarioGroup),
     (service_available_group, ServiceAvailableGroup),
     (debug_group, DebugGroup),
-    (input_scenario_group, InputScenarioGroup),
     (None, DefaultGroup)
 ]
 
@@ -1147,7 +1118,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..af3acbf 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"
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_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..d88a639 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -55,7 +55,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)
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 8197d52..2ce8532 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -47,7 +47,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..f00270d 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -100,7 +100,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/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