Merge "DHCP should be disabled on external subnet"
diff --git a/HACKING.rst b/HACKING.rst
index 607682b..81a7c2c 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -13,6 +13,7 @@
 - [T104] Scenario tests require a services decorator
 - [T105] Tests cannot use setUpClass/tearDownClass
 - [T106] vim configuration should not be kept in source files.
+- [T107] Check that a service tag isn't in the module path
 - [N322] Method's default argument shouldn't be mutable
 
 Test Data/Configuration
diff --git a/README.rst b/README.rst
index 5284bbf..7af0025 100644
--- a/README.rst
+++ b/README.rst
@@ -124,14 +124,14 @@
 Python 2.6
 ----------
 
-Tempest can be run with Python 2.6 however the unit tests and the gate
-currently only run with Python 2.7, so there are no guarantees about the state
-of tempest when running with Python 2.6. Additionally, to enable testr to work
-with tempest using python 2.6 the discover module from the unittest-ext
-project has to be patched to switch the unittest.TestSuite to use
-unittest2.TestSuite instead. See:
-
-https://code.google.com/p/unittest-ext/issues/detail?id=79
+Starting in the kilo release the OpenStack services dropped all support for
+python 2.6. This change has been mirrored in tempest, starting after the
+tempest-2 tag. This means that proposed changes to tempest which only fix
+python 2.6 compatibility will be rejected, and moving forward more features not
+present in python 2.6 will be used. If you're running you're OpenStack services
+on an earlier release with python 2.6 you can easily run tempest against it
+from a remote system running python 2.7. (or deploy a cloud guest in your cloud
+that has python 2.7)
 
 Branchless Tempest Considerations
 ---------------------------------
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
new file mode 100644
index 0000000..08f37cc
--- /dev/null
+++ b/doc/source/configuration.rst
@@ -0,0 +1,115 @@
+Tempest Configuration Guide
+===========================
+
+Auth/Credentials
+----------------
+
+Tempest currently has 2 different ways in configuration to provide credentials
+to use when running tempest. One is a traditional set of configuration options
+in the tempest.conf file. These options are in the identity section and let you
+specify a regular user, a global admin user, and a alternate user set of
+credentials. (which consist of a username, password, and project/tenant name)
+These options should be clearly labelled in the sample config file in the
+identity section.
+
+The other method to provide credentials is using the accounts.yaml file. This
+file is used to specify an arbitrary number of users available to run tests
+with. You can specify the location of the file in the
+auth section in the tempest.conf file. To see the specific format used in
+the file please refer to the accounts.yaml.sample file included in tempest.
+Currently users that are specified in the accounts.yaml file are assumed to
+have the same set of roles which can be used for executing all the tests you
+are running. This will be addressed in the future, but is a current limitation.
+Eventually the config options for providing credentials to tempest will be
+deprecated and removed in favor of the accounts.yaml file.
+
+Credential Provider Mechanisms
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Tempest currently also has 3 different internal methods for providing
+authentication to tests. Tenant isolation, locking test accounts, and
+non-locking test accounts. Depending on which one is in use the configuration
+of tempest is slightly different.
+
+Tenant Isolation
+""""""""""""""""
+Tenant isolation was originally create to enable running tempest in parallel.
+For each test class it creates a unique set of user credentials to use for the
+tests in the class. It can create up to 3 sets of username, password, and
+tenant/project names for a primary user, an admin user, and an alternate user.
+To enable and use tenant isolation you only need to configure 2 things:
+
+ #. A set of admin credentials with permissions to create users and
+    tenants/projects. This is specified in the identity section with the
+    admin_username, admin_tenant_name, and admin_password options
+ #. To enable tenant_isolation in the auth section with the
+    allow_tenant_isolation option.
+
+
+Locking Test Accounts
+"""""""""""""""""""""
+For a long time using tenant isolation was the only method available if you
+wanted to enable parallel execution of tempest tests. However this was
+insufficient for certain use cases because of the admin credentials requirement
+to create the credential sets on demand. To get around that the accounts.yaml
+file was introduced and with that a new internal credential provider to enable
+using the list of credentials instead of creating them on demand. With locking
+test accounts each test class will reserve a set of credentials from the
+accounts.yaml before executing any of its tests so that each class is isolated
+like in tenant isolation.
+
+Currently, this mechanism has some limitations, first only non-admin users with
+the same role set can be used at one time. The second limitation is around
+networking, locking test accounts will only work with a single flat network as
+the default for each tenant/project. If another network configuration is used
+in your cloud you might face unexpected failures.
+
+To enable and use locking test accounts you need do a few things:
+
+ #. Enable the locking test account provider with the
+    locking_credentials_provider option in the auth section
+ #. Create a accounts.yaml file which contains the set of pre-existing
+    credentials to use for testing. To make sure you don't have a credentials
+    starvation issue when running in parallel make sure you have at least 2
+    times the number of parallel workers you are using to execute tempest
+    available in the file.
+ #. Provide tempest with the location of you accounts.yaml file with the
+    test_accounts_file option in the auth section
+
+
+Non-locking test accounts
+"""""""""""""""""""""""""
+When tempest was refactored to allow for locking test accounts, the original
+non-tenant isolated case was converted to support the new accounts.yaml file.
+This mechanism is the non-locking test accounts provider. It only makes sense
+to use it if parallel execution isn't needed. If the role restrictions were too
+limiting with the locking accounts provider and tenant isolation is not wanted
+then you can use the non-locking test accounts credential provider without the
+accounts.yaml file. This is also the currently the default configuration for
+tempest, since it doesn't require elevated permissions or the extra file.
+
+To use the non-locking test accounts provider you have 2 ways to configure it.
+First you can specify the sets of credentials in the configuration file like
+detailed above with following 9 options in the identity section:
+
+ #. username
+ #. password
+ #. tenant_name
+ #. admin_username
+ #. admin_password
+ #. admin_tenant_name
+ #. alt_username
+ #. alt_password
+ #. alt_tenant_name
+
+You should use this if you need to specify credentials with different roles.
+(i.e. you want to use admin credentials) However, this isn't a requirement for
+its usage.
+
+You also can use the accounts.yaml file to specify the credentials used for
+testing. This will just allocate them serially so you only need to provide
+a pair of credentials. Do note that all the restrictions associated with
+locking test accounts applies to using the accounts.yaml file this way too.
+The procedure for doing this is very similar to with the locking accounts
+provider just don't set the locking_credentials_provider to true and you
+only should need a single pair of credentials.
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 1f06bc5..cb1c504 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -29,6 +29,15 @@
    field_guide/thirdparty
    field_guide/unit_tests
 
+---------------------------
+Tempest Configuration Guide
+---------------------------
+
+.. toctree::
+   :maxdepth: 2
+
+   configuration
+
 ---------------------
 Command Documentation
 ---------------------
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 0eeb738..d81d3bb 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -125,7 +125,7 @@
 # achieved configuring a list of test accounts (boolean value)
 # Deprecated group/name - [compute]/allow_tenant_isolation
 # Deprecated group/name - [orchestration]/allow_tenant_isolation
-#allow_tenant_isolation = false
+#allow_tenant_isolation = true
 
 # If set to True it enables the Accounts provider, which locks
 # credentials to allow for parallel execution with pre-provisioned
@@ -779,6 +779,10 @@
 # value)
 #dns_servers = 8.8.8.8,8.8.4.4
 
+# vnic_type to use when Launching instances with pre-configured ports.
+# Supported ports are: ['normal','direct','macvtap'] (string value)
+#port_vnic_type = <None>
+
 
 [network-feature-enabled]
 
diff --git a/requirements.txt b/requirements.txt
index 94c6fb0..4690329 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,18 +11,17 @@
 netaddr>=0.7.12
 python-ceilometerclient>=1.0.6
 python-glanceclient>=0.15.0
-python-keystoneclient>=1.0.0
-python-novaclient>=2.18.0
-python-neutronclient>=2.3.6,<3
+python-keystoneclient>=1.1.0
+python-neutronclient>=2.3.11,<3
 python-cinderclient>=1.1.0
-python-heatclient>=0.2.9
+python-heatclient>=0.3.0
 python-ironicclient>=0.2.1
 python-saharaclient>=0.7.6
 python-swiftclient>=2.2.0
 testrepository>=0.0.18
 oslo.config>=1.6.0  # Apache-2.0
-six>=1.7.0
+six>=1.9.0
 iso8601>=0.1.9
 fixtures>=0.3.14
 testscenarios>=0.4
-tempest-lib>=0.1.0
+tempest-lib>=0.2.0
diff --git a/tempest/api/baremetal/admin/base.py b/tempest/api/baremetal/admin/base.py
index 3b12b8e..c93dfb8 100644
--- a/tempest/api/baremetal/admin/base.py
+++ b/tempest/api/baremetal/admin/base.py
@@ -11,11 +11,11 @@
 #    under the License.
 
 import functools
+from tempest_lib import exceptions as lib_exc
 
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions as exc
 from tempest import test
 
 CONF = config.CONF
@@ -53,9 +53,8 @@
     """Base class for Baremetal API tests."""
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseBaremetalTest, cls).resource_setup()
-
+    def skip_checks(cls):
+        super(BaseBaremetalTest, cls).skip_checks()
         if not CONF.service_available.ironic:
             skip_msg = ('%s skipped as Ironic is not available' % cls.__name__)
             raise cls.skipException(skip_msg)
@@ -65,10 +64,22 @@
                         'testing.' %
                         (cls.__name__, CONF.baremetal.driver))
             raise cls.skipException(skip_msg)
-        cls.driver = CONF.baremetal.driver
 
-        mgr = clients.AdminManager()
-        cls.client = mgr.baremetal_client
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseBaremetalTest, cls).setup_credentials()
+        cls.mgr = clients.AdminManager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseBaremetalTest, cls).setup_clients()
+        cls.client = cls.mgr.baremetal_client
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaseBaremetalTest, cls).resource_setup()
+
+        cls.driver = CONF.baremetal.driver
         cls.power_timeout = CONF.baremetal.power_timeout
         cls.created_objects = {}
         for resource in RESOURCE_TYPES:
@@ -83,7 +94,7 @@
                 uuids = cls.created_objects[resource]
                 delete_method = getattr(cls.client, 'delete_%s' % resource)
                 for u in uuids:
-                    delete_method(u, ignore_errors=exc.NotFound)
+                    delete_method(u, ignore_errors=lib_exc.NotFound)
         finally:
             super(BaseBaremetalTest, cls).resource_cleanup()
 
@@ -104,21 +115,22 @@
 
     @classmethod
     @creates('node')
-    def create_node(cls, chassis_id, cpu_arch='x86', cpu_num=8, storage=1024,
-                    memory=4096):
+    def create_node(cls, chassis_id, cpu_arch='x86', cpus=8, local_gb=10,
+                    memory_mb=4096):
         """
         Wrapper utility for creating test baremetal nodes.
 
         :param cpu_arch: CPU architecture of the node. Default: x86.
-        :param cpu_num: Number of CPUs. Default: 8.
-        :param storage: Disk size. Default: 1024.
-        :param memory: Available RAM. Default: 4096.
+        :param cpus: Number of CPUs. Default: 8.
+        :param local_gb: Disk size. Default: 10.
+        :param memory_mb: Available RAM. Default: 4096.
         :return: Created node.
 
         """
         resp, body = cls.client.create_node(chassis_id, cpu_arch=cpu_arch,
-                                            cpu_num=cpu_num, storage=storage,
-                                            memory=memory, driver=cls.driver)
+                                            cpus=cpus, local_gb=local_gb,
+                                            memory_mb=memory_mb,
+                                            driver=cls.driver)
 
         return resp, body
 
diff --git a/tempest/api/baremetal/admin/test_api_discovery.py b/tempest/api/baremetal/admin/test_api_discovery.py
index 09788f2..f0b8b7f 100644
--- a/tempest/api/baremetal/admin/test_api_discovery.py
+++ b/tempest/api/baremetal/admin/test_api_discovery.py
@@ -18,6 +18,7 @@
     """Tests for API discovery features."""
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a3c27e94-f56c-42c4-8600-d6790650b9c5')
     def test_api_versions(self):
         _, descr = self.client.get_api_description()
         expected_versions = ('v1',)
@@ -27,12 +28,14 @@
             self.assertIn(v, versions)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('896283a6-488e-4f31-af78-6614286cbe0d')
     def test_default_version(self):
         _, descr = self.client.get_api_description()
         default_version = descr['default_version']
         self.assertEqual(default_version['id'], 'v1')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('abc0b34d-e684-4546-9728-ab7a9ad9f174')
     def test_version_1_resources(self):
         _, descr = self.client.get_version_description(version='v1')
         expected_resources = ('nodes', 'chassis',
diff --git a/tempest/api/baremetal/admin/test_chassis.py b/tempest/api/baremetal/admin/test_chassis.py
index 6f83412..da32f71 100644
--- a/tempest/api/baremetal/admin/test_chassis.py
+++ b/tempest/api/baremetal/admin/test_chassis.py
@@ -11,9 +11,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.baremetal.admin import base
 from tempest.common.utils import data_utils
-from tempest import exceptions as exc
 from tempest import test
 
 
@@ -33,12 +34,14 @@
                 self.assertEqual(value, actual[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7c5a2e09-699c-44be-89ed-2bc189992d42')
     def test_create_chassis(self):
         descr = data_utils.rand_name('test-chassis-')
         _, chassis = self.create_chassis(description=descr)
         self.assertEqual(chassis['description'], descr)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cabe9c6f-dc16-41a7-b6b9-0a90c212edd5')
     def test_create_chassis_unicode_description(self):
         # Use a unicode string for testing:
         # 'We ♡ OpenStack in Ukraine'
@@ -47,25 +50,29 @@
         self.assertEqual(chassis['description'], descr)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c84644df-31c4-49db-a307-8942881f41c0')
     def test_show_chassis(self):
         _, chassis = self.client.show_chassis(self.chassis['uuid'])
         self._assertExpected(self.chassis, chassis)
 
     @test.attr(type="smoke")
+    @test.idempotent_id('29c9cd3f-19b5-417b-9864-99512c3b33b3')
     def test_list_chassis(self):
         _, body = self.client.list_chassis()
         self.assertIn(self.chassis['uuid'],
                       [i['uuid'] for i in body['chassis']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5ae649ad-22d1-4fe1-bbc6-97227d199fb3')
     def test_delete_chassis(self):
         _, body = self.create_chassis()
         uuid = body['uuid']
 
         self.delete_chassis(uuid)
-        self.assertRaises(exc.NotFound, self.client.show_chassis, uuid)
+        self.assertRaises(lib_exc.NotFound, self.client.show_chassis, uuid)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cda8a41f-6be2-4cbf-840c-994b00a89b44')
     def test_update_chassis(self):
         _, body = self.create_chassis()
         uuid = body['uuid']
@@ -77,6 +84,7 @@
         self.assertEqual(chassis['description'], new_description)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('76305e22-a4e2-4ab3-855c-f4e2368b9335')
     def test_chassis_node_list(self):
         _, node = self.create_node(self.chassis['uuid'])
         _, body = self.client.list_chassis_nodes(self.chassis['uuid'])
diff --git a/tempest/api/baremetal/admin/test_drivers.py b/tempest/api/baremetal/admin/test_drivers.py
index 9d99295..de04562 100644
--- a/tempest/api/baremetal/admin/test_drivers.py
+++ b/tempest/api/baremetal/admin/test_drivers.py
@@ -27,12 +27,14 @@
         cls.driver_name = CONF.baremetal.driver
 
     @test.attr(type="smoke")
+    @test.idempotent_id('5aed2790-7592-4655-9b16-99abcc2e6ec5')
     def test_list_drivers(self):
         _, drivers = self.client.list_drivers()
         self.assertIn(self.driver_name,
                       [d['name'] for d in drivers['drivers']])
 
     @test.attr(type="smoke")
+    @test.idempotent_id('fb3287a3-c4d7-44bf-ae9d-1eef906d78ce')
     def test_show_driver(self):
         _, driver = self.client.show_driver(self.driver_name)
         self.assertEqual(self.driver_name, driver['name'])
diff --git a/tempest/api/baremetal/admin/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
index 41c12c6..f031614 100644
--- a/tempest/api/baremetal/admin/test_nodes.py
+++ b/tempest/api/baremetal/admin/test_nodes.py
@@ -11,11 +11,11 @@
 #    under the License.
 
 import six
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.baremetal.admin import base
 from tempest.common.utils import data_utils
 from tempest.common import waiters
-from tempest import exceptions as exc
 from tempest import test
 
 
@@ -47,35 +47,41 @@
         return instance_uuid
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4e939eb2-8a69-4e84-8652-6fffcbc9db8f')
     def test_create_node(self):
         params = {'cpu_arch': 'x86_64',
-                  'cpu_num': '12',
-                  'storage': '10240',
-                  'memory': '1024'}
+                  'cpus': '12',
+                  'local_gb': '10',
+                  'memory_mb': '1024'}
 
         _, body = self.create_node(self.chassis['uuid'], **params)
         self._assertExpected(params, body['properties'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9ade60a4-505e-4259-9ec4-71352cbbaf47')
     def test_delete_node(self):
         _, node = self.create_node(self.chassis['uuid'])
 
         self.delete_node(node['uuid'])
 
-        self.assertRaises(exc.NotFound, self.client.show_node, node['uuid'])
+        self.assertRaises(lib_exc.NotFound, self.client.show_node,
+                          node['uuid'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('55451300-057c-4ecf-8255-ba42a83d3a03')
     def test_show_node(self):
         _, loaded_node = self.client.show_node(self.node['uuid'])
         self._assertExpected(self.node, loaded_node)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4ca123c4-160d-4d8d-a3f7-15feda812263')
     def test_list_nodes(self):
         _, body = self.client.list_nodes()
         self.assertIn(self.node['uuid'],
                       [i['uuid'] for i in body['nodes']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('85b1f6e0-57fd-424c-aeff-c3422920556f')
     def test_list_nodes_association(self):
         _, body = self.client.list_nodes(associated=True)
         self.assertNotIn(self.node['uuid'],
@@ -90,6 +96,7 @@
         self.assertNotIn(self.node['uuid'], [n['uuid'] for n in body['nodes']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('18c4ebd8-f83a-4df7-9653-9fb33a329730')
     def test_node_port_list(self):
         _, port = self.create_port(self.node['uuid'],
                                    data_utils.rand_mac_address())
@@ -98,30 +105,33 @@
                       [p['uuid'] for p in body['ports']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('72591acb-f215-49db-8395-710d14eb86ab')
     def test_node_port_list_no_ports(self):
         _, node = self.create_node(self.chassis['uuid'])
         _, body = self.client.list_node_ports(node['uuid'])
         self.assertEmpty(body['ports'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4fed270a-677a-4d19-be87-fd38ae490320')
     def test_update_node(self):
         props = {'cpu_arch': 'x86_64',
-                 'cpu_num': '12',
-                 'storage': '10',
-                 'memory': '128'}
+                 'cpus': '12',
+                 'local_gb': '10',
+                 'memory_mb': '128'}
 
         _, node = self.create_node(self.chassis['uuid'], **props)
 
         new_p = {'cpu_arch': 'x86',
-                 'cpu_num': '1',
-                 'storage': '10000',
-                 'memory': '12300'}
+                 'cpus': '1',
+                 'local_gb': '10000',
+                 'memory_mb': '12300'}
 
         _, body = self.client.update_node(node['uuid'], properties=new_p)
         _, node = self.client.show_node(node['uuid'])
         self._assertExpected(new_p, node['properties'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cbf1f515-5f4b-4e49-945c-86bcaccfeb1d')
     def test_validate_driver_interface(self):
         _, body = self.client.validate_driver_interface(self.node['uuid'])
         core_interfaces = ['power', 'deploy']
@@ -129,10 +139,12 @@
             self.assertIn(interface, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5519371c-26a2-46e9-aa1a-f74226e9d71f')
     def test_set_node_boot_device(self):
         self.client.set_node_boot_device(self.node['uuid'], 'pxe')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9ea73775-f578-40b9-bc34-efc639c4f21f')
     def test_get_node_boot_device(self):
         body = self.client.get_node_boot_device(self.node['uuid'])
         self.assertIn('boot_device', body)
@@ -141,12 +153,14 @@
         self.assertTrue(isinstance(body['persistent'], bool))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3622bc6f-3589-4bc2-89f3-50419c66b133')
     def test_get_node_supported_boot_devices(self):
         body = self.client.get_node_supported_boot_devices(self.node['uuid'])
         self.assertIn('supported_boot_devices', body)
         self.assertTrue(isinstance(body['supported_boot_devices'], list))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f63b6288-1137-4426-8cfe-0d5b7eb87c06')
     def test_get_console(self):
         _, body = self.client.get_console(self.node['uuid'])
         con_info = ['console_enabled', 'console_info']
@@ -154,6 +168,7 @@
             self.assertIn(key, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('80504575-9b21-4670-92d1-143b948f9437')
     def test_set_console_mode(self):
         self.client.set_console_mode(self.node['uuid'], True)
 
@@ -161,6 +176,7 @@
         self.assertEqual(True, body['console_enabled'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b02a4f38-5e8b-44b2-aed2-a69a36ecfd69')
     def test_get_node_by_instance_uuid(self):
         instance_uuid = self._associate_node_with_instance()
         _, body = self.client.show_node_by_instance_uuid(instance_uuid)
diff --git a/tempest/api/baremetal/admin/test_nodestates.py b/tempest/api/baremetal/admin/test_nodestates.py
index f4f8054..bcb8b78 100644
--- a/tempest/api/baremetal/admin/test_nodestates.py
+++ b/tempest/api/baremetal/admin/test_nodestates.py
@@ -42,12 +42,14 @@
         raise exceptions.TimeoutException(message)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cd8afa5e-3f57-4e43-8185-beb83d3c9015')
     def test_list_nodestates(self):
         _, nodestates = self.client.list_nodestates(self.node['uuid'])
         for key in nodestates:
             self.assertEqual(nodestates[key], self.node[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fc5b9320-0c98-4e5a-8848-877fe5a0322c')
     def test_set_node_power_state(self):
         _, node = self.create_node(self.chassis['uuid'])
         states = ["power on", "rebooting", "power off"]
diff --git a/tempest/api/baremetal/admin/test_ports.py b/tempest/api/baremetal/admin/test_ports.py
index 89447e0..bbd2801 100644
--- a/tempest/api/baremetal/admin/test_ports.py
+++ b/tempest/api/baremetal/admin/test_ports.py
@@ -11,10 +11,10 @@
 #    under the License.
 
 from tempest_lib import decorators
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.baremetal.admin import base
 from tempest.common.utils import data_utils
-from tempest import exceptions as exc
 from tempest import test
 
 
@@ -37,6 +37,7 @@
                 self.assertEqual(value, actual[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('83975898-2e50-42ed-b5f0-e510e36a0b56')
     def test_create_port(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -48,6 +49,7 @@
         self._assertExpected(port, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d1f6b249-4cf6-4fe6-9ed6-a6e84b1bf67b')
     def test_create_port_specifying_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -61,6 +63,7 @@
 
     @decorators.skip_because(bug='1398350')
     @test.attr(type='smoke')
+    @test.idempotent_id('4a02c4b0-6573-42a4-a513-2e36ad485b62')
     def test_create_port_with_extra(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -74,6 +77,7 @@
         self._assertExpected(port, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1bf257a9-aea3-494e-89c0-63f657ab4fdd')
     def test_delete_port(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -81,19 +85,23 @@
 
         self.delete_port(port['uuid'])
 
-        self.assertRaises(exc.NotFound, self.client.show_port, port['uuid'])
+        self.assertRaises(lib_exc.NotFound, self.client.show_port,
+                          port['uuid'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9fa77ab5-ce59-4f05-baac-148904ba1597')
     def test_show_port(self):
         _, port = self.client.show_port(self.port['uuid'])
         self._assertExpected(self.port, port)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7c1114ff-fc3f-47bb-bc2f-68f61620ba8b')
     def test_show_port_by_address(self):
         _, port = self.client.show_port_by_address(self.port['address'])
         self._assertExpected(self.port, port['ports'][0])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bd773405-aea5-465d-b576-0ab1780069e5')
     def test_show_port_with_links(self):
         _, port = self.client.show_port(self.port['uuid'])
         self.assertIn('links', port.keys())
@@ -101,6 +109,7 @@
         self.assertIn(port['uuid'], port['links'][0]['href'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b5e91854-5cd7-4a8e-bb35-3e0a1314606d')
     def test_list_ports(self):
         _, body = self.client.list_ports()
         self.assertIn(self.port['uuid'],
@@ -111,12 +120,14 @@
                                     port['links'][0]['href'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('324a910e-2f80-4258-9087-062b5ae06240')
     def test_list_with_limit(self):
         _, body = self.client.list_ports(limit=3)
 
         next_marker = body['ports'][-1]['uuid']
         self.assertIn(next_marker, body['next'])
 
+    @test.idempotent_id('8a94b50f-9895-4a63-a574-7ecff86e5875')
     def test_list_ports_details(self):
         node_id = self.node['uuid']
 
@@ -141,6 +152,7 @@
             self.validate_self_link('ports', port['uuid'],
                                     port['links'][0]['href'])
 
+    @test.idempotent_id('8a03f688-7d75-4ecd-8cbc-e06b8f346738')
     def test_list_ports_details_with_address(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -154,6 +166,7 @@
         self.assertEqual(address, body['ports'][0]['address'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9c26298b-1bcb-47b7-9b9e-8bdd6e3c4aba')
     def test_update_port_replace(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -186,6 +199,7 @@
         self.assertEqual(new_extra, body['extra'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d7e7fece-6ed9-460a-9ebe-9267217e8580')
     def test_update_port_remove(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -213,6 +227,7 @@
         self.assertEqual(address, body['address'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('241288b3-e98a-400f-a4d7-d1f716146361')
     def test_update_port_add(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -235,6 +250,7 @@
 
     @decorators.skip_because(bug='1398350')
     @test.attr(type='smoke')
+    @test.idempotent_id('5309e897-0799-4649-a982-0179b04c3876')
     def test_update_port_mixed_ops(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
diff --git a/tempest/api/baremetal/admin/test_ports_negative.py b/tempest/api/baremetal/admin/test_ports_negative.py
index 8080eb6..2e79883 100644
--- a/tempest/api/baremetal/admin/test_ports_negative.py
+++ b/tempest/api/baremetal/admin/test_ports_negative.py
@@ -10,9 +10,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.baremetal.admin import base
 from tempest.common.utils import data_utils
-from tempest import exceptions as exc
 from tempest import test
 
 
@@ -26,84 +27,96 @@
         _, self.node = self.create_node(self.chassis['uuid'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('0a6ee1f7-d0d9-4069-8778-37f3aa07303a')
     def test_create_port_malformed_mac(self):
         node_id = self.node['uuid']
         address = 'malformed:mac'
 
-        self.assertRaises(exc.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_port, node_id=node_id, address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('30277ee8-0c60-4f1d-b125-0e51c2f43369')
     def test_create_port_nonexsistent_node_id(self):
         node_id = str(data_utils.rand_uuid())
         address = data_utils.rand_mac_address()
-        self.assertRaises(exc.BadRequest, self.create_port, node_id=node_id,
-                          address=address)
+        self.assertRaises(lib_exc.BadRequest, self.create_port,
+                          node_id=node_id, address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('029190f6-43e1-40a3-b64a-65173ba653a3')
     def test_show_port_malformed_uuid(self):
-        self.assertRaises(exc.BadRequest, self.client.show_port,
+        self.assertRaises(lib_exc.BadRequest, self.client.show_port,
                           'malformed:uuid')
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('0d00e13d-e2e0-45b1-bcbc-55a6d90ca793')
     def test_show_port_nonexistent_uuid(self):
-        self.assertRaises(exc.NotFound, self.client.show_port,
+        self.assertRaises(lib_exc.NotFound, self.client.show_port,
                           data_utils.rand_uuid())
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('4ad85266-31e9-4942-99ac-751897dc9e23')
     def test_show_port_by_mac_not_allowed(self):
-        self.assertRaises(exc.BadRequest, self.client.show_port,
+        self.assertRaises(lib_exc.BadRequest, self.client.show_port,
                           data_utils.rand_mac_address())
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('89a34380-3c61-4c32-955c-2cd9ce94da21')
     def test_create_port_duplicated_port_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
         uuid = data_utils.rand_uuid()
 
         self.create_port(node_id=node_id, address=address, uuid=uuid)
-        self.assertRaises(exc.Conflict, self.create_port, node_id=node_id,
+        self.assertRaises(lib_exc.Conflict, self.create_port, node_id=node_id,
                           address=address, uuid=uuid)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('65e84917-733c-40ae-ae4b-96a4adff931c')
     def test_create_port_no_mandatory_field_node_id(self):
         address = data_utils.rand_mac_address()
 
-        self.assertRaises(exc.BadRequest, self.create_port, node_id=None,
+        self.assertRaises(lib_exc.BadRequest, self.create_port, node_id=None,
                           address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('bcea3476-7033-4183-acfe-e56a30809b46')
     def test_create_port_no_mandatory_field_mac(self):
         node_id = self.node['uuid']
 
-        self.assertRaises(exc.BadRequest, self.create_port, node_id=node_id,
-                          address=None)
+        self.assertRaises(lib_exc.BadRequest, self.create_port,
+                          node_id=node_id, address=None)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('2b51cd18-fb95-458b-9780-e6257787b649')
     def test_create_port_malformed_port_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
         uuid = 'malformed:uuid'
 
-        self.assertRaises(exc.BadRequest, self.create_port, node_id=node_id,
-                          address=address, uuid=uuid)
+        self.assertRaises(lib_exc.BadRequest, self.create_port,
+                          node_id=node_id, address=address, uuid=uuid)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('583a6856-6a30-4ac4-889f-14e2adff8105')
     def test_create_port_malformed_node_id(self):
         address = data_utils.rand_mac_address()
-        self.assertRaises(exc.BadRequest, self.create_port,
+        self.assertRaises(lib_exc.BadRequest, self.create_port,
                           node_id='malformed:nodeid', address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('e27f8b2e-42c6-4a43-a3cd-accff716bc5c')
     def test_create_port_duplicated_mac(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
         self.create_port(node_id=node_id, address=address)
-        self.assertRaises(exc.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.create_port, node_id=node_id,
                           address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('8907082d-ac5e-4be3-b05f-d072ede82020')
     def test_update_port_by_mac_not_allowed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -115,11 +128,12 @@
                   'op': 'replace',
                   'value': 'new-value'}]
 
-        self.assertRaises(exc.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_port, address,
                           patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('df1ac70c-db9f-41d9-90f1-78cd6b905718')
     def test_update_port_nonexistent(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -134,10 +148,11 @@
         patch = [{'path': '/extra/key',
                   'op': 'replace',
                   'value': 'new-value'}]
-        self.assertRaises(exc.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('c701e315-aa52-41ea-817c-65c5ca8ca2a8')
     def test_update_port_malformed_port_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -145,12 +160,13 @@
         self.create_port(node_id=node_id, address=address)
 
         new_address = data_utils.rand_mac_address()
-        self.assertRaises(exc.BadRequest, self.client.update_port,
+        self.assertRaises(lib_exc.BadRequest, self.client.update_port,
                           uuid='malformed:uuid',
                           patch=[{'path': '/address', 'op': 'replace',
                                   'value': new_address}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('f8f15803-34d6-45dc-b06f-e5e04bf1b38b')
     def test_update_port_add_nonexistent_property(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -158,11 +174,12 @@
         _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
-        self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
+        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/nonexistent', ' op': 'add',
                             'value': 'value'}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('898ec904-38b1-4fcb-9584-1187d4263a2a')
     def test_update_port_replace_node_id_with_malformed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -173,10 +190,11 @@
         patch = [{'path': '/node_uuid',
                   'op': 'replace',
                   'value': 'malformed:node_uuid'}]
-        self.assertRaises(exc.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('2949f30f-5f59-43fa-a6d9-4eac578afab4')
     def test_update_port_replace_mac_with_duplicated(self):
         node_id = self.node['uuid']
         address1 = data_utils.rand_mac_address()
@@ -190,10 +208,11 @@
         patch = [{'path': '/address',
                   'op': 'replace',
                   'value': address1}]
-        self.assertRaises(exc.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('97f6e048-6e4f-4eba-a09d-fbbc78b77a77')
     def test_update_port_replace_node_id_with_nonexistent(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -204,10 +223,11 @@
         patch = [{'path': '/node_uuid',
                   'op': 'replace',
                   'value': data_utils.rand_uuid()}]
-        self.assertRaises(exc.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('375022c5-9e9e-4b11-9ca4-656729c0c9b2')
     def test_update_port_replace_mac_with_malformed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -219,10 +239,11 @@
                   'op': 'replace',
                   'value': 'malformed:mac'}]
 
-        self.assertRaises(exc.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('5722b853-03fc-4854-8308-2036a1b67d85')
     def test_update_port_replace_nonexistent_property(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -232,10 +253,11 @@
 
         patch = [{'path': '/nonexistent', ' op': 'replace', 'value': 'value'}]
 
-        self.assertRaises(exc.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('ae2696ca-930a-4a7f-918f-30ae97c60f56')
     def test_update_port_remove_mandatory_field_mac(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -243,10 +265,11 @@
         _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
-        self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
+        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/address', 'op': 'remove'}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('5392c1f0-2071-4697-9064-ec2d63019018')
     def test_update_port_remove_mandatory_field_port_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -254,10 +277,11 @@
         _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
-        self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
+        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/uuid', 'op': 'remove'}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('06b50d82-802a-47ef-b079-0a3311cf85a2')
     def test_update_port_remove_nonexistent_property(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -265,18 +289,20 @@
         _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
-        self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
+        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/nonexistent', 'op': 'remove'}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('03d42391-2145-4a6c-95bf-63fe55eb64fd')
     def test_delete_port_by_mac_not_allowed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
         self.create_port(node_id=node_id, address=address)
-        self.assertRaises(exc.BadRequest, self.client.delete_port, address)
+        self.assertRaises(lib_exc.BadRequest, self.client.delete_port, address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('0629e002-818e-4763-b25b-ae5e07b1cb23')
     def test_update_port_mixed_ops_integrity(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -304,7 +330,7 @@
                   'op': 'replace',
                   'value': 'value'}]
 
-        self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
+        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
                           patch)
 
         # patch should not be applied
diff --git a/tempest/api/compute/admin/test_agents.py b/tempest/api/compute/admin/test_agents.py
index 425ce13..2bd15ac 100644
--- a/tempest/api/compute/admin/test_agents.py
+++ b/tempest/api/compute/admin/test_agents.py
@@ -12,9 +12,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest.openstack.common import log
 from tempest import test
 
@@ -43,7 +44,7 @@
     def tearDown(self):
         try:
             self.client.delete_agent(self.agent_id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
         except Exception:
             LOG.exception('Exception raised deleting agent %s', self.agent_id)
@@ -60,6 +61,7 @@
         return kwargs
 
     @test.attr(type='gate')
+    @test.idempotent_id('1fc6bdc8-0b6d-4cc7-9f30-9b04fabe5b90')
     def test_create_agent(self):
         # Create an agent.
         params = self._param_helper(
@@ -72,6 +74,7 @@
             self.assertEqual(value, body[expected_item])
 
     @test.attr(type='gate')
+    @test.idempotent_id('dc9ffd51-1c50-4f0e-a820-ae6d2a568a9e')
     def test_update_agent(self):
         # Update an agent.
         params = self._param_helper(
@@ -82,6 +85,7 @@
             self.assertEqual(value, body[expected_item])
 
     @test.attr(type='gate')
+    @test.idempotent_id('470e0b89-386f-407b-91fd-819737d0b335')
     def test_delete_agent(self):
         # Delete an agent.
         self.client.delete_agent(self.agent_id)
@@ -91,6 +95,7 @@
         self.assertNotIn(self.agent_id, map(lambda x: x['agent_id'], agents))
 
     @test.attr(type='gate')
+    @test.idempotent_id('6a326c69-654b-438a-80a3-34bcc454e138')
     def test_list_agents(self):
         # List all agents.
         agents = self.client.list_agents()
@@ -98,6 +103,7 @@
         self.assertIn(self.agent_id, map(lambda x: x['agent_id'], agents))
 
     @test.attr(type='gate')
+    @test.idempotent_id('eabadde4-3cd7-4ec4-a4b5-5a936d2d4408')
     def test_list_agents_with_filter(self):
         # List the agent builds by the filter.
         params = self._param_helper(
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index a866ede..e3b0151 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -13,10 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -45,10 +46,11 @@
         try:
             self.client.delete_aggregate(aggregate_id)
         # if aggregate not found, it depict it was deleted in the test
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
 
     @test.attr(type='gate')
+    @test.idempotent_id('0d148aa3-d54c-4317-aa8d-42040a475e20')
     def test_aggregate_create_delete(self):
         # Create and delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -61,6 +63,7 @@
         self.client.wait_for_resource_deletion(aggregate['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('5873a6f8-671a-43ff-8838-7ce430bb6d0b')
     def test_aggregate_create_delete_with_az(self):
         # Create and delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -75,6 +78,7 @@
         self.client.wait_for_resource_deletion(aggregate['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('68089c38-04b1-4758-bdf0-cf0daec4defd')
     def test_aggregate_create_verify_entry_in_list(self):
         # Create an aggregate and ensure it is listed.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -87,6 +91,7 @@
                           aggregates))
 
     @test.attr(type='gate')
+    @test.idempotent_id('36ec92ca-7a73-43bc-b920-7531809e8540')
     def test_aggregate_create_update_metadata_get_details(self):
         # Create an aggregate and ensure its details are returned.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -109,6 +114,7 @@
         self.assertEqual(meta, body["metadata"])
 
     @test.attr(type='gate')
+    @test.idempotent_id('4d2b2004-40fa-40a1-aab2-66f4dab81beb')
     def test_aggregate_create_update_with_az(self):
         # Update an aggregate and ensure properties are updated correctly
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -138,6 +144,7 @@
                           aggregates))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c8e85064-e79b-4906-9931-c11c24294d02')
     def test_aggregate_add_remove_host(self):
         # Add an host to the given aggregate and remove.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -158,6 +165,7 @@
         self.assertNotIn(self.host, body['hosts'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('7f6a1cc5-2446-4cdb-9baa-b6ae0a919b72')
     def test_aggregate_add_host_list(self):
         # Add an host to the given aggregate and list.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -176,6 +184,7 @@
         self.assertIn(self.host, agg['hosts'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('eeef473c-7c52-494d-9f09-2ed7fc8fc036')
     def test_aggregate_add_host_get_details(self):
         # Add an host to the given aggregate and get details.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -191,6 +200,7 @@
         self.assertIn(self.host, body['hosts'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('96be03c7-570d-409c-90f8-e4db3c646996')
     def test_aggregate_add_host_create_server_with_az(self):
         # Add an host to the given aggregate and create a server.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -203,8 +213,8 @@
         self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
         server_name = data_utils.rand_name('test_server_')
         admin_servers_client = self.os_adm.servers_client
-        resp, server = self.create_test_server(name=server_name,
-                                               availability_zone=az_name,
-                                               wait_until='ACTIVE')
-        resp, body = admin_servers_client.get_server(server['id'])
+        server = self.create_test_server(name=server_name,
+                                         availability_zone=az_name,
+                                         wait_until='ACTIVE')
+        body = admin_servers_client.get_server(server['id'])
         self.assertEqual(self.host, body[self._host_key])
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index a450e5d..02e2b0b 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -13,10 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -40,80 +41,90 @@
         cls.host = hosts[0]
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('86a1cb14-da37-4a70-b056-903fd56dfe29')
     def test_aggregate_create_as_user(self):
         # Regular user is not allowed to create an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.create_aggregate,
                           name=aggregate_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3b8a1929-3793-4e92-bcb4-dfa572ee6c1d')
     def test_aggregate_create_aggregate_name_length_less_than_1(self):
         # the length of aggregate name should >= 1 and <=255
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_aggregate,
                           name='')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4c194563-543b-4e70-a719-557bbe947fac')
     def test_aggregate_create_aggregate_name_length_exceeds_255(self):
         # the length of aggregate name should >= 1 and <=255
         aggregate_name = 'a' * 256
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_aggregate,
                           name=aggregate_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c23a291-b0b1-487b-b464-132e061151b3')
     def test_aggregate_create_with_existent_aggregate_name(self):
         # creating an aggregate with existent aggregate name is forbidden
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         aggregate = self.client.create_aggregate(name=aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.create_aggregate,
                           name=aggregate_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('cd6de795-c15d-45f1-8d9e-813c6bb72a3d')
     def test_aggregate_delete_as_user(self):
         # Regular user is not allowed to delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         aggregate = self.client.create_aggregate(name=aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.delete_aggregate,
                           aggregate['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b7d475a6-5dcd-4ff4-b70a-cd9de66a6672')
     def test_aggregate_list_as_user(self):
         # Regular user is not allowed to list aggregates.
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.list_aggregates)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('557cad12-34c9-4ff4-95f0-22f0dfbaf7dc')
     def test_aggregate_get_details_as_user(self):
         # Regular user is not allowed to get aggregate details.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         aggregate = self.client.create_aggregate(name=aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.get_aggregate,
                           aggregate['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c74f4bf1-4708-4ff2-95a0-f49eaca951bd')
     def test_aggregate_delete_with_invalid_id(self):
         # Delete an aggregate with invalid id should raise exceptions.
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_aggregate, -1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3c916244-2c46-49a4-9b55-b20bb0ae512c')
     def test_aggregate_get_details_with_invalid_id(self):
         # Get aggregate details with invalid id should raise exceptions.
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_aggregate, -1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0ef07828-12b4-45ba-87cc-41425faf5711')
     def test_aggregate_add_non_exist_host(self):
         # Adding a non-exist host to an aggregate should raise exceptions.
         hosts_all = self.os_adm.hosts_client.list_hosts()
@@ -127,21 +138,23 @@
         aggregate = self.client.create_aggregate(name=aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
-        self.assertRaises(exceptions.NotFound, self.client.add_host,
+        self.assertRaises(lib_exc.NotFound, self.client.add_host,
                           aggregate['id'], non_exist_host)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7324c334-bd13-4c93-8521-5877322c3d51')
     def test_aggregate_add_host_as_user(self):
         # Regular user is not allowed to add a host to an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         aggregate = self.client.create_aggregate(name=aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.add_host,
                           aggregate['id'], self.host)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('19dd44e1-c435-4ee1-a402-88c4f90b5950')
     def test_aggregate_add_existent_host(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -151,10 +164,11 @@
         self.client.add_host(aggregate['id'], self.host)
         self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
 
-        self.assertRaises(exceptions.Conflict, self.client.add_host,
+        self.assertRaises(lib_exc.Conflict, self.client.add_host,
                           aggregate['id'], self.host)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7a53af20-137a-4e44-a4ae-e19260e626d9')
     def test_aggregate_remove_host_as_user(self):
         # Regular user is not allowed to remove a host from an aggregate.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -164,16 +178,17 @@
         self.client.add_host(aggregate['id'], self.host)
         self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.remove_host,
                           aggregate['id'], self.host)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('95d6a6fa-8da9-4426-84d0-eec0329f2e4d')
     def test_aggregate_remove_nonexistent_host(self):
         non_exist_host = data_utils.rand_name('nonexist_host_')
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         aggregate = self.client.create_aggregate(name=aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
-        self.assertRaises(exceptions.NotFound, self.client.remove_host,
+        self.assertRaises(lib_exc.NotFound, self.client.remove_host,
                           aggregate['id'], non_exist_host)
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index e88fecb..9d24b00 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -29,16 +29,15 @@
         cls.client = cls.availability_zone_admin_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('d3431479-8a09-4f76-aa2d-26dc580cb27c')
     def test_get_availability_zone_list(self):
         # List of availability zone
-        resp, availability_zone = self.client.get_availability_zone_list()
-        self.assertEqual(200, resp.status)
+        availability_zone = self.client.get_availability_zone_list()
         self.assertTrue(len(availability_zone) > 0)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ef726c58-530f-44c2-968c-c7bed22d5b8c')
     def test_get_availability_zone_list_detail(self):
         # List of availability zones and available services
-        resp, availability_zone = \
-            self.client.get_availability_zone_list_detail()
-        self.assertEqual(200, resp.status)
+        availability_zone = self.client.get_availability_zone_list_detail()
         self.assertTrue(len(availability_zone) > 0)
diff --git a/tempest/api/compute/admin/test_availability_zone_negative.py b/tempest/api/compute/admin/test_availability_zone_negative.py
index d062b0c..caecddc 100644
--- a/tempest/api/compute/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/admin/test_availability_zone_negative.py
@@ -12,8 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -29,9 +30,10 @@
         cls.non_adm_client = cls.availability_zone_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bf34dca2-fdc3-4073-9c02-7648d9eae0d7')
     def test_get_availability_zone_list_detail_with_non_admin_user(self):
         # List of availability zones and available services with
         # non-administrator user
         self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.non_adm_client.get_availability_zone_list_detail)
diff --git a/tempest/api/compute/admin/test_baremetal_nodes.py b/tempest/api/compute/admin/test_baremetal_nodes.py
new file mode 100644
index 0000000..1381f80
--- /dev/null
+++ b/tempest/api/compute/admin/test_baremetal_nodes.py
@@ -0,0 +1,44 @@
+# Copyright 2015 NEC Corporation.  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.
+
+from tempest.api.compute import base
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class BaremetalNodesAdminTestJSON(base.BaseV2ComputeAdminTest):
+    """
+    Tests Baremetal API
+    """
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaremetalNodesAdminTestJSON, cls).resource_setup()
+        if not CONF.service_available.ironic:
+            skip_msg = ('%s skipped as Ironic is not available' % cls.__name__)
+            raise cls.skipException(skip_msg)
+        cls.client = cls.os_adm.baremetal_nodes_client
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('e475aa6e-416d-4fa4-b3af-28d5e84250fb')
+    def test_list_baremetal_nodes(self):
+        # List all baremetal nodes.
+        baremetal_nodes = self.client.list_baremetal_nodes()
+        self.assertNotEmpty(baremetal_nodes, "No baremetal nodes found.")
+
+        for node in baremetal_nodes:
+            baremetal_node = self.client.get_baremetal_node(node['id'])
+            self.assertEqual(node['id'], baremetal_node['id'])
diff --git a/tempest/api/compute/admin/test_fixed_ips.py b/tempest/api/compute/admin/test_fixed_ips.py
index d1d13a0..820b9b0 100644
--- a/tempest/api/compute/admin/test_fixed_ips.py
+++ b/tempest/api/compute/admin/test_fixed_ips.py
@@ -29,8 +29,8 @@
             msg = ("%s skipped as neutron is available" % cls.__name__)
             raise cls.skipException(msg)
         cls.client = cls.os_adm.fixed_ips_client
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
-        resp, server = cls.servers_client.get_server(server['id'])
+        server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.servers_client.get_server(server['id'])
         for ip_set in server['addresses']:
             for ip in server['addresses'][ip_set]:
                 if ip['OS-EXT-IPS:type'] == 'fixed':
@@ -40,21 +40,22 @@
                 break
 
     @test.attr(type='gate')
+    @test.idempotent_id('16b7d848-2f7c-4709-85a3-2dfb4576cc52')
     @test.services('network')
     def test_list_fixed_ip_details(self):
-        resp, fixed_ip = self.client.get_fixed_ip_details(self.ip)
+        fixed_ip = self.client.get_fixed_ip_details(self.ip)
         self.assertEqual(fixed_ip['address'], self.ip)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5485077b-7e46-4cec-b402-91dc3173433b')
     @test.services('network')
     def test_set_reserve(self):
         body = {"reserve": "None"}
-        resp, body = self.client.reserve_fixed_ip(self.ip, body)
-        self.assertEqual(resp.status, 202)
+        self.client.reserve_fixed_ip(self.ip, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7476e322-b9ff-4710-bf82-49d51bac6e2e')
     @test.services('network')
     def test_set_unreserve(self):
         body = {"unreserve": "None"}
-        resp, body = self.client.reserve_fixed_ip(self.ip, body)
-        self.assertEqual(resp.status, 202)
+        self.client.reserve_fixed_ip(self.ip, body)
diff --git a/tempest/api/compute/admin/test_fixed_ips_negative.py b/tempest/api/compute/admin/test_fixed_ips_negative.py
index e7022db..df3c390 100644
--- a/tempest/api/compute/admin/test_fixed_ips_negative.py
+++ b/tempest/api/compute/admin/test_fixed_ips_negative.py
@@ -12,9 +12,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -30,8 +31,8 @@
             raise cls.skipException(msg)
         cls.client = cls.os_adm.fixed_ips_client
         cls.non_admin_client = cls.fixed_ips_client
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
-        resp, server = cls.servers_client.get_server(server['id'])
+        server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.servers_client.get_server(server['id'])
         for ip_set in server['addresses']:
             for ip in server['addresses'][ip_set]:
                 if ip['OS-EXT-IPS:type'] == 'fixed':
@@ -41,28 +42,32 @@
                 break
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9f17f47d-daad-4adc-986e-12370c93e407')
     @test.services('network')
     def test_list_fixed_ip_details_with_non_admin_user(self):
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.get_fixed_ip_details, self.ip)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ce60042c-fa60-4836-8d43-1c8e3359dc47')
     @test.services('network')
     def test_set_reserve_with_non_admin_user(self):
         body = {"reserve": "None"}
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.reserve_fixed_ip,
                           self.ip, body)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f1f7a35b-0390-48c5-9803-5f27461439db')
     @test.services('network')
     def test_set_unreserve_with_non_admin_user(self):
         body = {"unreserve": "None"}
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.reserve_fixed_ip,
                           self.ip, body)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f51cf464-7fc5-4352-bc3e-e75cfa2cb717')
     @test.services('network')
     def test_set_reserve_with_invalid_ip(self):
         # NOTE(maurosr): since this exercises the same code snippet, we do it
@@ -71,14 +76,15 @@
         # NOTE(eliqiao): in Juno, the exception is NotFound, but in master, we
         # change the error code to BadRequest, both exceptions should be
         # accepted by tempest
-        self.assertRaises((exceptions.NotFound, exceptions.BadRequest),
+        self.assertRaises((lib_exc.NotFound, lib_exc.BadRequest),
                           self.client.reserve_fixed_ip,
                           "my.invalid.ip", body)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fd26ef50-f135-4232-9d32-281aab3f9176')
     @test.services('network')
     def test_fixed_ip_with_invalid_action(self):
         body = {"invalid_action": "None"}
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.reserve_fixed_ip,
                           self.ip, body)
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 360bcf7..cd3a4f1 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -13,11 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import uuid
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -79,18 +79,21 @@
         return flavor['id']
 
     @test.attr(type='gate')
+    @test.idempotent_id('8b4330e1-12c4-4554-9390-e6639971f086')
     def test_create_flavor_with_int_id(self):
         flavor_id = data_utils.rand_int_id(start=1000)
         new_flavor_id = self._create_flavor(flavor_id)
         self.assertEqual(new_flavor_id, str(flavor_id))
 
     @test.attr(type='gate')
+    @test.idempotent_id('94c9bb4e-2c2a-4f3c-bb1f-5f0daf918e6d')
     def test_create_flavor_with_uuid_id(self):
         flavor_id = str(uuid.uuid4())
         new_flavor_id = self._create_flavor(flavor_id)
         self.assertEqual(new_flavor_id, flavor_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f83fe669-6758-448a-a85e-32d351f36fe0')
     def test_create_flavor_with_none_id(self):
         # If nova receives a request with None as flavor_id,
         # nova generates flavor_id of uuid.
@@ -99,6 +102,7 @@
         self.assertEqual(new_flavor_id, str(uuid.UUID(new_flavor_id)))
 
     @test.attr(type='gate')
+    @test.idempotent_id('8261d7b0-be58-43ec-a2e5-300573c3f6c5')
     def test_create_flavor_verify_entry_in_list_details(self):
         # Create a flavor and ensure it's details are listed
         # This operation requires the user to have 'admin' role
@@ -123,6 +127,7 @@
         self.assertTrue(flag)
 
     @test.attr(type='gate')
+    @test.idempotent_id('63dc64e6-2e79-4fdf-868f-85500d308d66')
     def test_create_list_flavor_without_extra_data(self):
         # Create a flavor and ensure it is listed
         # This operation requires the user to have 'admin' role
@@ -164,6 +169,7 @@
         self.assertTrue(flag)
 
     @test.attr(type='gate')
+    @test.idempotent_id('be6cc18c-7c5d-48c0-ac16-17eaf03c54eb')
     def test_list_non_public_flavor(self):
         # Create a flavor with os-flavor-access:is_public false.
         # The flavor should not be present in list_details as the
@@ -196,6 +202,7 @@
         self.assertFalse(flag)
 
     @test.attr(type='gate')
+    @test.idempotent_id('bcc418ef-799b-47cc-baa1-ce01368b8987')
     def test_create_server_with_non_public_flavor(self):
         # Create a flavor with os-flavor-access:is_public false
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -210,11 +217,12 @@
         self.addCleanup(self.flavor_clean_up, flavor['id'])
 
         # Verify flavor is not used by other user
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.os.servers_client.create_server,
                           'test', self.image_ref, flavor['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('b345b196-bfbd-4231-8ac1-6d7fe15ff3a3')
     def test_list_public_flavor_with_other_user(self):
         # Create a Flavor with public access.
         # Try to List/Get flavor with another user
@@ -238,6 +246,7 @@
         self.assertTrue(flag)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fb9cbde6-3a0e-41f2-a983-bdb0a823c44e')
     def test_is_public_string_variations(self):
         flavor_id_not_public = data_utils.rand_int_id(start=1000)
         flavor_name_not_public = data_utils.rand_name(self.flavor_name_prefix)
@@ -280,6 +289,7 @@
                                 flavor_name_public)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3b541a2e-2ac2-4b42-8b8d-ba6e22fcd4da')
     def test_create_flavor_using_string_ram(self):
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 8a33ce7..aaa96ac 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -44,6 +44,7 @@
         cls.disk = 10
 
     @test.attr(type='gate')
+    @test.idempotent_id('ea2c2211-29fa-4db9-97c3-906d36fad3e0')
     def test_flavor_access_list_with_private_flavor(self):
         # Test to make sure that list flavor access on a newly created
         # private flavor will return an empty access list
@@ -59,6 +60,7 @@
         self.assertEqual(len(flavor_access), 0, str(flavor_access))
 
     @test.attr(type='gate')
+    @test.idempotent_id('59e622f6-bdf6-45e3-8ba8-fedad905a6b4')
     def test_flavor_access_add_remove(self):
         # Test to add and remove flavor access to a given tenant.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index 4ba9eb2..af53985 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -13,11 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import uuid
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -43,6 +43,7 @@
         cls.disk = 10
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0621c53e-d45d-40e7-951d-43e5e257b272')
     def test_flavor_access_list_with_public_flavor(self):
         # Test to list flavor access with exceptions by querying public flavor
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -53,11 +54,12 @@
                                                new_flavor_id,
                                                is_public='True')
         self.addCleanup(self.client.delete_flavor, new_flavor['id'])
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.list_flavor_access,
                           new_flavor_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('41eaaade-6d37-4f28-9c74-f21b46ca67bd')
     def test_flavor_non_admin_add(self):
         # Test to add flavor access as a user without admin privileges.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -68,12 +70,13 @@
                                                new_flavor_id,
                                                is_public='False')
         self.addCleanup(self.client.delete_flavor, new_flavor['id'])
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.flavors_client.add_flavor_access,
                           new_flavor['id'],
                           self.tenant_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('073e79a6-c311-4525-82dc-6083d919cb3a')
     def test_flavor_non_admin_remove(self):
         # Test to remove flavor access as a user without admin privileges.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -88,12 +91,13 @@
         self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
         self.addCleanup(self.client.remove_flavor_access,
                         new_flavor['id'], self.tenant_id)
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.flavors_client.remove_flavor_access,
                           new_flavor['id'],
                           self.tenant_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f3592cc0-0306-483c-b210-9a7b5346eddc')
     def test_add_flavor_access_duplicate(self):
         # Create a new flavor.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -112,12 +116,13 @@
 
         # An exception should be raised when adding flavor access to the same
         # tenant
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.add_flavor_access,
                           new_flavor['id'],
                           self.tenant_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1f710927-3bc7-4381-9f82-0ca6e42644b7')
     def test_remove_flavor_access_not_found(self):
         # Create a new flavor.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -130,7 +135,7 @@
         self.addCleanup(self.client.delete_flavor, new_flavor['id'])
 
         # An exception should be raised when flavor access is not found
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.remove_flavor_access,
                           new_flavor['id'],
                           str(uuid.uuid4()))
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index 55c3358..5847a64 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -57,6 +57,7 @@
         super(FlavorsExtraSpecsTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('0b2f9d4b-1ca2-4b99-bb40-165d4bb94208')
     def test_flavor_set_get_update_show_unset_keys(self):
         # Test to SET, GET, UPDATE, SHOW, UNSET flavor extra
         # spec as a user with admin privileges.
@@ -87,6 +88,7 @@
         self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
 
     @test.attr(type='gate')
+    @test.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)
@@ -96,6 +98,7 @@
             self.assertEqual(body[key], specs[key])
 
     @test.attr(type='gate')
+    @test.idempotent_id('12805a7f-39a3-4042-b989-701d5cad9c90')
     def test_flavor_non_admin_get_specific_key(self):
         specs = {"key1": "value1", "key2": "value2"}
         body = self.client.set_flavor_extra_spec(self.flavor['id'], specs)
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 2663e25..979fdd3 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
@@ -14,9 +14,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -58,22 +59,24 @@
         super(FlavorsExtraSpecsNegativeTestJSON, cls).resource_cleanup()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a00a3b81-5641-45a8-ab2b-4a8ec41e1d7d')
     def test_flavor_non_admin_set_keys(self):
         # Test to SET flavor extra spec as a user without admin privileges.
         specs = {"key1": "value1", "key2": "value2"}
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.flavors_client.set_flavor_extra_spec,
                           self.flavor['id'],
                           specs)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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
         specs = {"key1": "value1", "key2": "value2"}
         body = self.client.set_flavor_extra_spec(
             self.flavor['id'], specs)
         self.assertEqual(body['key1'], 'value1')
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.flavors_client.
                           update_flavor_extra_spec,
                           self.flavor['id'],
@@ -81,43 +84,48 @@
                           key1='value1_new')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('28f12249-27c7-44c1-8810-1f382f316b11')
     def test_flavor_non_admin_unset_keys(self):
         specs = {"key1": "value1", "key2": "value2"}
         self.client.set_flavor_extra_spec(self.flavor['id'], specs)
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.flavors_client.unset_flavor_extra_spec,
                           self.flavor['id'],
                           'key1')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('440b9f3f-3c7f-4293-a106-0ceda350f8de')
     def test_flavor_unset_nonexistent_key(self):
         nonexistent_key = data_utils.rand_name('flavor_key')
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.unset_flavor_extra_spec,
                           self.flavor['id'],
                           nonexistent_key)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('329a7be3-54b2-48be-8052-bf2ce4afd898')
     def test_flavor_get_nonexistent_key(self):
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.flavors_client.get_flavor_extra_spec_with_key,
                           self.flavor['id'],
                           "nonexistent_key")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('25b822b8-9f49-44f6-80de-d99f0482e5cb')
     def test_flavor_update_mismatch_key(self):
         # the key will be updated should be match the key in the body
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_flavor_extra_spec,
                           self.flavor['id'],
                           "key2",
                           key1="value")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f5889590-bf66-41cc-b4b1-6e6370cfd93f')
     def test_flavor_update_more_key(self):
         # there should be just one item in the request body
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_flavor_extra_spec,
                           self.flavor['id'],
                           "key1",
diff --git a/tempest/api/compute/admin/test_flavors_negative.py b/tempest/api/compute/admin/test_flavors_negative.py
index 86125fb..042c270 100644
--- a/tempest/api/compute/admin/test_flavors_negative.py
+++ b/tempest/api/compute/admin/test_flavors_negative.py
@@ -15,11 +15,12 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.api_schema.request.compute.v2 import flavors
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 
@@ -52,6 +53,7 @@
         cls.rxtx = 2
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('404451c0-c1ae-4448-8d50-d74f26f93ec8')
     def test_get_flavor_details_for_deleted_flavor(self):
         # Delete a flavor and ensure it is not listed
         # Create a test flavor
@@ -83,21 +85,23 @@
         self.assertTrue(flag)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6f56e7b7-7500-4d0c-9913-880ca1efed87')
     def test_create_flavor_as_user(self):
         # only admin user can create a flavor
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = str(uuid.uuid4())
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.create_flavor,
                           flavor_name, self.ram, self.vcpus, self.disk,
                           new_flavor_id, ephemeral=self.ephemeral,
                           swap=self.swap, rxtx=self.rxtx)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a9a6dc02-8c14-4e05-a1ca-3468d4214882')
     def test_delete_flavor_as_user(self):
         # only admin user can delete a flavor
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.delete_flavor,
                           self.flavor_ref_alt)
 
@@ -105,6 +109,5 @@
 @test.SimpleNegativeAutoTest
 class FlavorCreateNegativeTestJSON(base.BaseV2ComputeAdminTest,
                                    test.NegativeAutoTest):
-    _interface = 'json'
     _service = CONF.compute.catalog_type
     _schema = flavors.flavor_create
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index c1263ea..7ca081a 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -40,7 +40,7 @@
     @classmethod
     def verify_unallocated_floating_ip_range(cls, ip_range):
         # Verify whether configure floating IP range is not already allocated.
-        _, body = cls.client.list_floating_ips_bulk()
+        body = cls.client.list_floating_ips_bulk()
         allocated_ips_list = map(lambda x: x['address'], body)
         for ip_addr in netaddr.IPNetwork(ip_range).iter_hosts():
             if str(ip_addr) in allocated_ips_list:
@@ -57,6 +57,7 @@
             pass
 
     @test.attr(type='gate')
+    @test.idempotent_id('2c8f145f-8012-4cb8-ac7e-95a587f0e4ab')
     @test.services('network')
     def test_create_list_delete_floating_ips_bulk(self):
         # Create, List  and delete the Floating IPs Bulk
@@ -65,18 +66,14 @@
         # anywhere. Using the below mentioned interface which is not ever
         # expected to be used. Clean Up has been done for created IP range
         interface = 'eth0'
-        resp, body = self.client.create_floating_ips_bulk(self.ip_range,
-                                                          pool,
-                                                          interface)
-
-        self.assertEqual(200, resp.status)
+        body = self.client.create_floating_ips_bulk(self.ip_range,
+                                                    pool,
+                                                    interface)
         self.addCleanup(self._delete_floating_ips_bulk, self.ip_range)
         self.assertEqual(self.ip_range, body['ip_range'])
-        resp, ips_list = self.client.list_floating_ips_bulk()
-        self.assertEqual(200, resp.status)
+        ips_list = self.client.list_floating_ips_bulk()
         self.assertNotEqual(0, len(ips_list))
         for ip in netaddr.IPNetwork(self.ip_range).iter_hosts():
             self.assertIn(str(ip), map(lambda x: x['address'], ips_list))
-        resp, body = self.client.delete_floating_ips_bulk(self.ip_range)
-        self.assertEqual(200, resp.status)
-        self.assertEqual(self.ip_range, body)
+        body = self.client.delete_floating_ips_bulk(self.ip_range)
+        self.assertEqual(self.ip_range, body.data)
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index b9d47bb..bef5d1f 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -29,11 +29,13 @@
         cls.client = cls.os_adm.hosts_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('9bfaf98d-e2cb-44b0-a07e-2558b2821e4f')
     def test_list_hosts(self):
         hosts = self.client.list_hosts()
         self.assertTrue(len(hosts) >= 2, str(hosts))
 
     @test.attr(type='gate')
+    @test.idempotent_id('5dc06f5b-d887-47a2-bb2a-67762ef3c6de')
     def test_list_hosts_with_zone(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
         hosts = self.client.list_hosts()
@@ -45,6 +47,7 @@
         self.assertIn(host, hosts)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9af3c171-fbf4-4150-a624-22109733c2a6')
     def test_list_hosts_with_a_blank_zone(self):
         # If send the request with a blank zone, the request will be successful
         # and it will return all the hosts list
@@ -53,6 +56,7 @@
         self.assertNotEqual(0, len(hosts))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c6ddbadb-c94e-4500-b12f-8ffc43843ff8')
     def test_list_hosts_with_nonexistent_zone(self):
         # If send the request with a nonexistent zone, the request will be
         # successful and no hosts will be retured
@@ -61,6 +65,7 @@
         self.assertEqual(0, len(hosts))
 
     @test.attr(type='gate')
+    @test.idempotent_id('38adbb12-aee2-4498-8aec-329c72423aa4')
     def test_show_host_detail(self):
         hosts = self.client.list_hosts()
 
diff --git a/tempest/api/compute/admin/test_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index fc918a3..3c070ce 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -12,9 +12,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -37,40 +38,45 @@
         return hostname
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dd032027-0210-4d9c-860e-69b1b8deed5f')
     def test_list_hosts_with_non_admin_user(self):
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_hosts)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e75b0a1a-041f-47a1-8b4a-b72a6ff36d3f')
     def test_show_host_detail_with_nonexistent_hostname(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.show_host_detail, nonexitent_hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('19ebe09c-bfd4-4b7c-81a2-e2e0710f59cc')
     def test_show_host_detail_with_non_admin_user(self):
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.show_host_detail,
                           hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e40c72b1-0239-4ed6-ba21-81a184df1f7c')
     def test_update_host_with_non_admin_user(self):
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.update_host,
                           hostname,
                           status='enable',
                           maintenance_mode='enable')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('76e396fe-5418-4dd3-a186-5b301edc0721')
     def test_update_host_with_extra_param(self):
         # only 'status' and 'maintenance_mode' are the valid params.
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_host,
                           hostname,
                           status='enable',
@@ -78,90 +84,100 @@
                           param='XXX')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fbe2bf3e-3246-4a95-a59f-94e4e298ec77')
     def test_update_host_with_invalid_status(self):
         # 'status' can only be 'enable' or 'disable'
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_host,
                           hostname,
                           status='invalid',
                           maintenance_mode='enable')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ab1e230e-5e22-41a9-8699-82b9947915d4')
     def test_update_host_with_invalid_maintenance_mode(self):
         # 'maintenance_mode' can only be 'enable' or 'disable'
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_host,
                           hostname,
                           status='enable',
                           maintenance_mode='invalid')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0cd85f75-6992-4a4a-b1bd-d11e37fd0eee')
     def test_update_host_without_param(self):
         # 'status' or 'maintenance_mode' needed for host update
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_host,
                           hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('23c92146-2100-4d68-b2d6-c7ade970c9c1')
     def test_update_nonexistent_host(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
 
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.update_host,
                           nonexitent_hostname,
                           status='enable',
                           maintenance_mode='enable')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0d981ac3-4320-4898-b674-82b61fbb60e4')
     def test_startup_nonexistent_host(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
 
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.startup_host,
                           nonexitent_hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9f4ebb7e-b2ae-4e5b-a38f-0fd1bb0ddfca')
     def test_startup_host_with_non_admin_user(self):
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.startup_host,
                           hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9e637444-29cf-4244-88c8-831ae82c31b6')
     def test_shutdown_nonexistent_host(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
 
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.shutdown_host,
                           nonexitent_hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a803529c-7e3f-4d3c-a7d6-8e1c203d27f6')
     def test_shutdown_host_with_non_admin_user(self):
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.shutdown_host,
                           hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f86bfd7b-0b13-4849-ae29-0322e83ee58b')
     def test_reboot_nonexistent_host(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
 
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.reboot_host,
                           nonexitent_hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('02d79bb9-eb57-4612-abf6-2cb38897d2f8')
     def test_reboot_host_with_non_admin_user(self):
         hostname = self._get_host_name()
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.reboot_host,
                           hostname)
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index fbfef87..c65bded 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -37,18 +37,21 @@
         self.assertTrue(len(hypers) > 0, "No hypervisors found: %s" % hypers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7f0ceacd-c64d-4e96-b8ee-d02943142cc5')
     def test_get_hypervisor_list(self):
         # List of hypervisor and available hypervisors hostname
         hypers = self._list_hypervisors()
         self.assertHypervisors(hypers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('1e7fdac2-b672-4ad1-97a4-bad0e3030118')
     def test_get_hypervisor_list_details(self):
         # Display the details of the all hypervisor
         hypers = self.client.get_hypervisor_list_details()
         self.assertHypervisors(hypers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('94ff9eae-a183-428e-9cdb-79fde71211cc')
     def test_get_hypervisor_show_details(self):
         # Display the details of the specified hypervisor
         hypers = self._list_hypervisors()
@@ -60,6 +63,7 @@
                          hypers[0]['hypervisor_hostname'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('e81bba3f-6215-4e39-a286-d52d2f906862')
     def test_get_hypervisor_show_servers(self):
         # Show instances about the specific hypervisors
         hypers = self._list_hypervisors()
@@ -70,12 +74,14 @@
         self.assertTrue(len(hypervisors) > 0)
 
     @test.attr(type='gate')
+    @test.idempotent_id('797e4f28-b6e0-454d-a548-80cc77c00816')
     def test_get_hypervisor_stats(self):
         # Verify the stats of the all hypervisor
         stats = self.client.get_hypervisor_stats()
         self.assertTrue(len(stats) > 0)
 
     @test.attr(type='gate')
+    @test.idempotent_id('91a50d7d-1c2b-4f24-b55a-a1fe20efca70')
     def test_get_hypervisor_uptime(self):
         # Verify that GET shows the specified hypervisor uptime
         hypers = self._list_hypervisors()
@@ -113,6 +119,7 @@
             "None of the hypervisors had a valid uptime: %s" % hypers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('d7e1805b-3b14-4a3b-b6fd-50ec6d9f361f')
     def test_search_hypervisor(self):
         hypers = self._list_hypervisors()
         self.assertHypervisors(hypers)
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
index a137a61..556424a 100644
--- a/tempest/api/compute/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -13,11 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import uuid
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -39,97 +39,108 @@
         return hypers
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c136086a-0f67-4b2b-bc61-8482bd68989f')
     def test_show_nonexistent_hypervisor(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.client.get_hypervisor_show_details,
             nonexistent_hypervisor_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('51e663d0-6b89-4817-a465-20aca0667d03')
     def test_show_hypervisor_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
 
         self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.non_adm_client.get_hypervisor_show_details,
             hypers[0]['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('2a0a3938-832e-4859-95bf-1c57c236b924')
     def test_show_servers_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
 
         self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.non_adm_client.get_hypervisor_servers,
             hypers[0]['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('02463d69-0ace-4d33-a4a8-93d7883a2bba')
     def test_show_servers_with_nonexistent_hypervisor(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.client.get_hypervisor_servers,
             nonexistent_hypervisor_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e2b061bb-13f9-40d8-9d6e-d5bf17595849')
     def test_get_hypervisor_stats_with_non_admin_user(self):
         self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.non_adm_client.get_hypervisor_stats)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f60aa680-9a3a-4c7d-90e1-fae3a4891303')
     def test_get_nonexistent_hypervisor_uptime(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.client.get_hypervisor_uptime,
             nonexistent_hypervisor_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6c3461f9-c04c-4e2a-bebb-71dc9cb47df2')
     def test_get_hypervisor_uptime_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
 
         self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.non_adm_client.get_hypervisor_uptime,
             hypers[0]['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('51b3d536-9b14-409c-9bce-c6f7c794994e')
     def test_get_hypervisor_list_with_non_admin_user(self):
         # List of hypervisor and available services with non admin user
         self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.non_adm_client.get_hypervisor_list)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dc02db05-e801-4c5f-bc8e-d915290ab345')
     def test_get_hypervisor_list_details_with_non_admin_user(self):
         # List of hypervisor details and available services with non admin user
         self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.non_adm_client.get_hypervisor_list_details)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('19a45cc1-1000-4055-b6d2-28e8b2ec4faa')
     def test_search_nonexistent_hypervisor(self):
         nonexistent_hypervisor_name = data_utils.rand_name('test_hypervisor')
 
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.client.search_hypervisor,
             nonexistent_hypervisor_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5b6a6c79-5dc1-4fa5-9c58-9c8085948e74')
     def test_search_hypervisor_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
 
         self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.non_adm_client.search_hypervisor,
             hypers[0]['hypervisor_hostname'])
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log.py b/tempest/api/compute/admin/test_instance_usage_audit_log.py
index f7b5e43..1a86b2d 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log.py
@@ -28,10 +28,10 @@
         cls.adm_client = cls.os_adm.instance_usages_audit_log_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('25319919-33d9-424f-9f99-2c203ee48b9d')
     def test_list_instance_usage_audit_logs(self):
         # list instance usage audit logs
-        resp, body = self.adm_client.list_instance_usage_audit_logs()
-        self.assertEqual(200, resp.status)
+        body = self.adm_client.list_instance_usage_audit_logs()
         expected_items = ['total_errors', 'total_instances', 'log',
                           'num_hosts_running', 'num_hosts_done',
                           'num_hosts', 'hosts_not_run', 'overall_status',
@@ -41,13 +41,13 @@
             self.assertIn(item, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6e40459d-7c5f-400b-9e83-449fbc8e7feb')
     def test_get_instance_usage_audit_log(self):
         # Get instance usage audit log before specified time
         now = datetime.datetime.now()
-        resp, body = self.adm_client.get_instance_usage_audit_log(
+        body = self.adm_client.get_instance_usage_audit_log(
             urllib.quote(now.strftime("%Y-%m-%d %H:%M:%S")))
 
-        self.assertEqual(200, resp.status)
         expected_items = ['total_errors', 'total_instances', 'log',
                           'num_hosts_running', 'num_hosts_done', 'num_hosts',
                           'hosts_not_run', 'overall_status', 'period_ending',
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py b/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
index c4905d9..6b5a82f 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
@@ -16,8 +16,9 @@
 import datetime
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -29,19 +30,21 @@
         cls.adm_client = cls.os_adm.instance_usages_audit_log_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a9d33178-d2c9-4131-ad3b-f4ca8d0308a2')
     def test_instance_usage_audit_logs_with_nonadmin_user(self):
         # the instance_usage_audit_logs API just can be accessed by admin user
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.instance_usages_audit_log_client.
                           list_instance_usage_audit_logs)
         now = datetime.datetime.now()
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.instance_usages_audit_log_client.
                           get_instance_usage_audit_log,
                           urllib.quote(now.strftime("%Y-%m-%d %H:%M:%S")))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9b952047-3641-41c7-ba91-a809fc5974c8')
     def test_get_instance_usage_audit_logs_with_invalid_time(self):
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.adm_client.get_instance_usage_audit_log,
                           "invalid_time")
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index 7ba05ef..67e4fe3 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -29,27 +29,26 @@
         cls.client = cls.os_adm.migrations_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('75c0b83d-72a0-4cf8-a153-631e83e7d53f')
     def test_list_migrations(self):
         # Admin can get the migrations list
-        resp, _ = self.client.list_migrations()
-        self.assertEqual(200, resp.status)
+        self.client.list_migrations()
 
+    @test.idempotent_id('1b512062-8093-438e-b47a-37d2f597cd64')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='gate')
     def test_list_migrations_in_flavor_resize_situation(self):
         # Admin can get the migrations list which contains the resized server
-        resp, server = self.create_test_server(wait_until="ACTIVE")
+        server = self.create_test_server(wait_until="ACTIVE")
         server_id = server['id']
 
-        resp, _ = self.servers_client.resize(server_id, self.flavor_ref_alt)
-        self.assertEqual(202, resp.status)
+        self.servers_client.resize(server_id, self.flavor_ref_alt)
         self.servers_client.wait_for_server_status(server_id, 'VERIFY_RESIZE')
         self.servers_client.confirm_resize(server_id)
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
 
-        resp, body = self.client.list_migrations()
-        self.assertEqual(200, resp.status)
+        body = self.client.list_migrations()
 
         instance_uuids = [x['instance_uuid'] for x in body]
         self.assertIn(server_id, instance_uuids)
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index 75f3199..fa72c01 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -15,6 +15,7 @@
 
 from tempest.api.compute import base
 from tempest import config
+from tempest import test
 
 CONF = config.CONF
 
@@ -33,8 +34,9 @@
         super(NetworksTest, cls).resource_setup()
         cls.client = cls.os_adm.networks_client
 
+    @test.idempotent_id('d206d211-8912-486f-86e2-a9d090d1f416')
     def test_get_network(self):
-        resp, networks = self.client.list_networks()
+        networks = self.client.list_networks()
         configured_network = [x for x in networks if x['label'] ==
                               CONF.compute.fixed_network_name]
         self.assertEqual(1, len(configured_network),
@@ -42,11 +44,12 @@
                              len(configured_network),
                              CONF.compute.fixed_network_name))
         configured_network = configured_network[0]
-        _, network = self.client.get_network(configured_network['id'])
+        network = self.client.get_network(configured_network['id'])
         self.assertEqual(configured_network['label'], network['label'])
 
+    @test.idempotent_id('df3d1046-6fa5-4b2c-ad0c-cfa46a351cb9')
     def test_list_all_networks(self):
-        _, networks = self.client.list_networks()
+        networks = self.client.list_networks()
         # Check the configured network is in the list
         configured_network = CONF.compute.fixed_network_name
         self.assertIn(configured_network, [x['label'] for x in networks])
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index b0fcf94..35e682e 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -51,6 +51,7 @@
                                      'cores', 'security_groups'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3b0a7c8f-cf58-46b8-a60c-715a32a8ba7d')
     def test_get_default_quotas(self):
         # Admin can get the default resource quota set for a tenant
         expected_quota_set = self.default_quota_set | set(['id'])
@@ -61,6 +62,7 @@
             self.assertIn(quota, quota_set.keys())
 
     @test.attr(type='gate')
+    @test.idempotent_id('55fbe2bf-21a9-435b-bbd2-4162b0ed799a')
     def test_update_all_quota_resources_for_tenant(self):
         # Admin can update all the resource quota limits for a tenant
         default_quota_set = self.adm_client.get_default_quota_set(
@@ -92,6 +94,7 @@
 
     # TODO(afazekas): merge these test cases
     @test.attr(type='gate')
+    @test.idempotent_id('ce9e0815-8091-4abd-8345-7fe5b85faa1d')
     def test_get_updated_quotas(self):
         # Verify that GET shows the updated quota set of tenant
         tenant_name = data_utils.rand_name('cpu_quota_tenant_')
@@ -125,6 +128,7 @@
         self.assertEqual(2048, quota_set['ram'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0')
     def test_delete_quota(self):
         # Admin can delete the resource quota set for a tenant
         tenant_name = data_utils.rand_name('ram_quota_tenant_')
@@ -169,6 +173,7 @@
     # global state, and possibly needs to be part of a set of
     # tests that get run all by themselves at the end under a
     # 'danger' flag.
+    @test.idempotent_id('7932ab0f-5136-4075-b201-c0e2338df51a')
     def test_update_default_quotas(self):
         LOG.debug("get the current 'default' quota class values")
         body = self.adm_client.get_quota_class_set('default')
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index 7cefe90..73428df 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -13,11 +13,11 @@
 #    under the License.
 
 from tempest_lib import decorators
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -38,8 +38,9 @@
         cls.demo_tenant_id = cls.client.tenant_id
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('733abfe8-166e-47bb-8363-23dbd7ff3476')
     def test_update_quota_normal_user(self):
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.client.update_quota_set,
                           self.demo_tenant_id,
                           ram=0)
@@ -47,6 +48,7 @@
     # TODO(afazekas): Add dedicated tenant to the skiped quota tests
     # it can be moved into the setUpClass as well
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('91058876-9947-4807-9f22-f6eb17140d9b')
     def test_create_server_when_cpu_quota_is_full(self):
         # Disallow server creation when tenant's vcpu quota is full
         quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
@@ -59,10 +61,11 @@
 
         self.addCleanup(self.adm_client.update_quota_set, self.demo_tenant_id,
                         cores=default_vcpu_quota)
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.create_test_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6fdd7012-584d-4327-a61c-49122e0d5864')
     def test_create_server_when_memory_quota_is_full(self):
         # Disallow server creation when tenant's memory quota is full
         quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
@@ -75,10 +78,11 @@
 
         self.addCleanup(self.adm_client.update_quota_set, self.demo_tenant_id,
                         ram=default_mem_quota)
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.create_test_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7c6be468-0274-449a-81c3-ac1c32ee0161')
     def test_create_server_when_instances_quota_is_full(self):
         # Once instances quota limit is reached, disallow server creation
         quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
@@ -90,12 +94,13 @@
                                          instances=instances_quota)
         self.addCleanup(self.adm_client.update_quota_set, self.demo_tenant_id,
                         instances=default_instances_quota)
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.create_test_server)
 
     @decorators.skip_because(bug="1186354",
                              condition=CONF.service_available.neutron)
     @test.attr(type='gate')
+    @test.idempotent_id('7c6c8f3b-2bf6-4918-b240-57b136a66aa0')
     @test.services('network')
     def test_security_groups_exceed_limit(self):
         # Negative test: Creation Security Groups over limit should FAIL
@@ -116,13 +121,14 @@
         # Check we cannot create anymore
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised when out of quota
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.sg_client.create_security_group,
                           "sg-overlimit", "sg-desc")
 
     @decorators.skip_because(bug="1186354",
                              condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6e9f436d-f1ed-4f8e-a493-7275dfaa4b4d')
     @test.services('network')
     def test_security_groups_rules_exceed_limit(self):
         # Negative test: Creation of Security Group Rules should FAIL
@@ -155,6 +161,6 @@
         # Check we cannot create SG rule anymore
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised when out of quota
-        self.assertRaises((exceptions.OverLimit, exceptions.Unauthorized),
+        self.assertRaises((lib_exc.OverLimit, lib_exc.Unauthorized),
                           self.sg_client.create_security_group_rule,
                           secgroup_id, ip_protocol, 1025, 1025)
diff --git a/tempest/api/compute/admin/test_security_group_default_rules.py b/tempest/api/compute/admin/test_security_group_default_rules.py
index 563d517..87c0008 100644
--- a/tempest/api/compute/admin/test_security_group_default_rules.py
+++ b/tempest/api/compute/admin/test_security_group_default_rules.py
@@ -12,11 +12,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import testtools
 
 from tempest.api.compute import base
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -30,10 +30,14 @@
     @testtools.skipIf(CONF.service_available.neutron,
                       "Skip as this functionality is not yet "
                       "implemented in Neutron. Related Bug#1311500")
-    def resource_setup(cls):
+    def setup_credentials(cls):
         # A network and a subnet will be created for these tests
         cls.set_network_resources(network=True, subnet=True)
-        super(SecurityGroupDefaultRulesTest, cls).resource_setup()
+        super(SecurityGroupDefaultRulesTest, cls).setup_credentials()
+
+    @classmethod
+    def setup_clients(cls):
+        super(SecurityGroupDefaultRulesTest, cls).setup_clients()
         cls.adm_client = cls.os_adm.security_group_default_rules_client
 
     def _create_security_group_default_rules(self, ip_protocol='tcp',
@@ -52,6 +56,7 @@
         return rule
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6d880615-eec3-4d29-97c5-7a074dde239d')
     def test_create_delete_security_group_default_rules(self):
         # Create and delete Security Group default rule
         ip_protocols = ['tcp', 'udp', 'icmp']
@@ -59,11 +64,12 @@
             rule = self._create_security_group_default_rules(ip_protocol)
             # Delete Security Group default rule
             self.adm_client.delete_security_group_default_rule(rule['id'])
-            self.assertRaises(exceptions.NotFound,
+            self.assertRaises(lib_exc.NotFound,
                               self.adm_client.get_security_group_default_rule,
                               rule['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4d752e0a-33a1-4c3a-b498-ff8667ca22e5')
     def test_create_security_group_default_rule_without_cidr(self):
         ip_protocol = 'udp'
         from_port = 80
@@ -78,6 +84,7 @@
         self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('29f2d218-69b0-4a95-8f3d-6bd0ef732b3a')
     def test_create_security_group_default_rule_with_blank_cidr(self):
         ip_protocol = 'icmp'
         from_port = 10
@@ -94,6 +101,7 @@
         self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6e6de55e-9146-4ae0-89f2-3569586e0b9b')
     def test_security_group_default_rules_list(self):
         ip_protocol = 'tcp'
         from_port = 22
@@ -110,6 +118,7 @@
         self.assertIn(rule, rules)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('15cbb349-86b4-4f71-a048-04b7ef3f150b')
     def test_default_security_group_default_rule_show(self):
         ip_protocol = 'tcp'
         from_port = 22
diff --git a/tempest/api/compute/admin/test_security_groups.py b/tempest/api/compute/admin/test_security_groups.py
index 82cb26e..19f5b8c 100644
--- a/tempest/api/compute/admin/test_security_groups.py
+++ b/tempest/api/compute/admin/test_security_groups.py
@@ -37,6 +37,7 @@
         else:
             self.client.delete_security_group(securitygroup_id)
 
+    @test.idempotent_id('49667619-5af9-4c63-ab5d-2cfdd1c8f7f1')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Skipped because neutron do not support all_tenants"
                       "search filter.")
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index cff9a43..adeb64b 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -35,33 +35,34 @@
         cls.flavors_client = cls.os_adm.flavors_client
 
         cls.s1_name = data_utils.rand_name('server')
-        resp, server = cls.create_test_server(name=cls.s1_name,
-                                              wait_until='ACTIVE')
+        server = cls.create_test_server(name=cls.s1_name,
+                                        wait_until='ACTIVE')
         cls.s1_id = server['id']
 
         cls.s2_name = data_utils.rand_name('server')
-        resp, server = cls.create_test_server(name=cls.s2_name,
-                                              wait_until='ACTIVE')
+        server = cls.create_test_server(name=cls.s2_name,
+                                        wait_until='ACTIVE')
         cls.s2_id = server['id']
 
     @test.attr(type='gate')
+    @test.idempotent_id('51717b38-bdc1-458b-b636-1cf82d99f62f')
     def test_list_servers_by_admin(self):
         # Listing servers by admin user returns empty list by default
-        resp, body = self.client.list_servers_with_detail()
+        body = self.client.list_servers_with_detail()
         servers = body['servers']
-        self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('06f960bb-15bb-48dc-873d-f96e89be7870')
     def test_list_servers_filter_by_error_status(self):
         # Filter the list of servers by server error status
         params = {'status': 'error'}
-        resp, server = self.client.reset_state(self.s1_id, state='error')
-        resp, body = self.non_admin_client.list_servers(params)
+        self.client.reset_state(self.s1_id, state='error')
+        body = self.non_admin_client.list_servers(params)
         # Reset server's state to 'active'
-        resp, server = self.client.reset_state(self.s1_id, state='active')
+        self.client.reset_state(self.s1_id, state='active')
         # Verify server's state
-        resp, server = self.client.get_server(self.s1_id)
+        server = self.client.get_server(self.s1_id)
         self.assertEqual(server['status'], 'ACTIVE')
         servers = body['servers']
         # Verify error server in list result
@@ -69,11 +70,12 @@
         self.assertNotIn(self.s2_id, map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('9f5579ae-19b4-4985-a091-2a5d56106580')
     def test_list_servers_by_admin_with_all_tenants(self):
         # Listing servers by admin user with all tenants parameter
         # Here should be listed all servers
         params = {'all_tenants': ''}
-        resp, body = self.client.list_servers_with_detail(params)
+        body = self.client.list_servers_with_detail(params)
         servers = body['servers']
         servers_name = map(lambda x: x['name'], servers)
 
@@ -81,74 +83,70 @@
         self.assertIn(self.s2_name, servers_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7e5d6b8f-454a-4ba1-8ae2-da857af8338b')
     def test_list_servers_by_admin_with_specified_tenant(self):
         # In nova v2, tenant_id is ignored unless all_tenants is specified
 
         # List the primary tenant but get nothing due to odd specified behavior
         tenant_id = self.non_admin_client.tenant_id
         params = {'tenant_id': tenant_id}
-        resp, body = self.client.list_servers_with_detail(params)
+        body = self.client.list_servers_with_detail(params)
         servers = body['servers']
         self.assertEqual([], servers)
 
         # List the admin tenant which has no servers
         admin_tenant_id = self.client.tenant_id
         params = {'all_tenants': '', 'tenant_id': admin_tenant_id}
-        resp, body = self.client.list_servers_with_detail(params)
+        body = self.client.list_servers_with_detail(params)
         servers = body['servers']
         self.assertEqual([], servers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('86c7a8f7-50cf-43a9-9bac-5b985317134f')
     def test_list_servers_filter_by_exist_host(self):
         # Filter the list of servers by existent host
         name = data_utils.rand_name('server')
         flavor = self.flavor_ref
         image_id = self.image_ref
-        resp, test_server = self.client.create_server(
-            name, image_id, flavor)
-        self.assertEqual('202', resp['status'])
+        test_server = self.client.create_server(name, image_id, flavor)
         self.addCleanup(self.client.delete_server, test_server['id'])
         self.client.wait_for_server_status(test_server['id'], 'ACTIVE')
-        resp, server = self.client.get_server(test_server['id'])
+        server = self.client.get_server(test_server['id'])
         self.assertEqual(server['status'], 'ACTIVE')
         hostname = server[self._host_key]
         params = {'host': hostname}
-        resp, body = self.client.list_servers(params)
-        self.assertEqual('200', resp['status'])
+        body = self.client.list_servers(params)
         servers = body['servers']
         nonexistent_params = {'host': 'nonexistent_host'}
-        resp, nonexistent_body = self.client.list_servers(
-            nonexistent_params)
-        self.assertEqual('200', resp['status'])
+        nonexistent_body = self.client.list_servers(nonexistent_params)
         nonexistent_servers = nonexistent_body['servers']
         self.assertIn(test_server['id'], map(lambda x: x['id'], servers))
         self.assertNotIn(test_server['id'],
                          map(lambda x: x['id'], nonexistent_servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ee8ae470-db70-474d-b752-690b7892cab1')
     def test_reset_state_server(self):
         # Reset server's state to 'error'
-        resp, server = self.client.reset_state(self.s1_id)
-        self.assertEqual(202, resp.status)
+        self.client.reset_state(self.s1_id)
 
         # Verify server's state
-        resp, server = self.client.get_server(self.s1_id)
+        server = self.client.get_server(self.s1_id)
         self.assertEqual(server['status'], 'ERROR')
 
         # Reset server's state to 'active'
-        resp, server = self.client.reset_state(self.s1_id, state='active')
-        self.assertEqual(202, resp.status)
+        self.client.reset_state(self.s1_id, state='active')
 
         # Verify server's state
-        resp, server = self.client.get_server(self.s1_id)
+        server = self.client.get_server(self.s1_id)
         self.assertEqual(server['status'], 'ACTIVE')
 
     @test.attr(type='gate')
     @decorators.skip_because(bug="1240043")
+    @test.idempotent_id('31ff3486-b8a0-4f56-a6c0-aab460531db3')
     def test_get_server_diagnostics_by_admin(self):
         # Retrieve server diagnostics by admin user
-        resp, diagnostic = self.client.get_server_diagnostics(self.s1_id)
-        self.assertEqual(200, resp.status)
+        diagnostic = self.client.get_server_diagnostics(self.s1_id)
         basic_attrs = ['rx_packets', 'rx_errors', 'rx_drop',
                        'tx_packets', 'tx_errors', 'tx_drop',
                        'read_req', 'write_req', 'cpu', 'memory']
@@ -156,14 +154,14 @@
             self.assertIn(key, str(diagnostic.keys()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('682cb127-e5bb-4f53-87ce-cb9003604442')
     def test_rebuild_server_in_error_state(self):
         # The server in error state should be rebuilt using the provided
         # image and changed to ACTIVE state
 
         # resetting vm state require admin privilege
-        resp, server = self.client.reset_state(self.s1_id, state='error')
-        self.assertEqual(202, resp.status)
-        resp, rebuilt_server = self.non_admin_client.rebuild(
+        self.client.reset_state(self.s1_id, state='error')
+        rebuilt_server = self.non_admin_client.rebuild(
             self.s1_id, self.image_ref_alt)
         self.addCleanup(self.non_admin_client.wait_for_server_status,
                         self.s1_id, 'ACTIVE')
@@ -179,26 +177,25 @@
                                                      'ACTIVE',
                                                      raise_on_error=False)
         # Verify the server properties after rebuilding
-        resp, server = self.non_admin_client.get_server(rebuilt_server['id'])
+        server = self.non_admin_client.get_server(rebuilt_server['id'])
         rebuilt_image_id = server['image']['id']
         self.assertEqual(self.image_ref_alt, rebuilt_image_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7a1323b4-a6a2-497a-96cb-76c07b945c71')
     def test_reset_network_inject_network_info(self):
         # Reset Network of a Server
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, server_body = self.client.reset_network(server['id'])
-        self.assertEqual(202, resp.status)
+        server = self.create_test_server(wait_until='ACTIVE')
+        self.client.reset_network(server['id'])
         # Inject the Network Info into Server
-        resp, server_body = self.client.inject_network_info(server['id'])
-        self.assertEqual(202, resp.status)
+        self.client.inject_network_info(server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('fdcd9b33-0903-4e00-a1f7-b5f6543068d6')
     def test_create_server_with_scheduling_hint(self):
         # Create a server with scheduler hints.
         hints = {
             'same_host': self.s1_id
         }
-        resp, server = self.create_test_server(sched_hints=hints,
-                                               wait_until='ACTIVE')
-        self.assertEqual('202', resp['status'])
+        self.create_test_server(sched_hints=hints,
+                                wait_until='ACTIVE')
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 0dddc76..cafbf81 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -14,13 +14,13 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
 import testtools
 
 from tempest.api.compute import base
 from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -41,8 +41,8 @@
         cls.tenant_id = cls.client.tenant_id
 
         cls.s1_name = data_utils.rand_name('server')
-        resp, server = cls.create_test_server(name=cls.s1_name,
-                                              wait_until='ACTIVE')
+        server = cls.create_test_server(name=cls.s1_name,
+                                        wait_until='ACTIVE')
         cls.s1_id = server['id']
 
     def _get_unused_flavor_id(self):
@@ -50,11 +50,12 @@
         while True:
             try:
                 self.flavors_client.get_flavor_details(flavor_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 break
             flavor_id = data_utils.rand_int_id(start=1000)
         return flavor_id
 
+    @test.idempotent_id('28dcec23-f807-49da-822c-56a92ea3c687')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
@@ -71,11 +72,12 @@
                                                        ram, vcpus, disk,
                                                        flavor_id)
         self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.client.resize,
                           self.servers[0]['id'],
                           flavor_ref['id'])
 
+    @test.idempotent_id('7368a427-2f26-4ad9-9ba9-911a0ec2b0db')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
@@ -92,42 +94,48 @@
                                                        ram, vcpus, disk,
                                                        flavor_id)
         self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.client.resize,
                           self.servers[0]['id'],
                           flavor_ref['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b0b4d8af-1256-41ef-9ee7-25f1c19dde80')
     def test_reset_state_server_invalid_state(self):
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.reset_state, self.s1_id,
                           state='invalid')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4cdcc984-fab0-4577-9a9d-6d558527ee9d')
     def test_reset_state_server_invalid_type(self):
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.reset_state, self.s1_id,
                           state=1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e741298b-8df2-46f0-81cb-8f814ff2504c')
     def test_reset_state_server_nonexistent_server(self):
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.reset_state, '999')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e84e2234-60d2-42fa-8b30-e2d3049724ac')
     def test_get_server_diagnostics_by_non_admin(self):
         # Non-admin user can not view server diagnostics according to policy
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_adm_client.get_server_diagnostics,
                           self.s1_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('46a4e1ca-87ae-4d28-987a-1b6b136a0221')
     def test_migrate_non_existent_server(self):
         # migrate a non existent server
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.migrate_server,
                           str(uuid.uuid4()))
 
+    @test.idempotent_id('b0b17f83-d14e-4fc4-8f31-bcc9f3cfa629')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
@@ -135,14 +143,12 @@
     @test.attr(type=['negative', 'gate'])
     def test_migrate_server_invalid_state(self):
         # create server.
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        self.assertEqual(202, resp.status)
+        server = self.create_test_server(wait_until='ACTIVE')
         server_id = server['id']
         # suspend the server.
-        resp, _ = self.client.suspend_server(server_id)
-        self.assertEqual(202, resp.status)
+        self.client.suspend_server(server_id)
         self.client.wait_for_server_status(server_id, 'SUSPENDED')
         # migrate an suspended server should fail
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.migrate_server,
                           server_id)
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index 5cf4a31..a6f79aa 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -30,11 +30,13 @@
         cls.client = cls.os_adm.services_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('5be41ef4-53d1-41cc-8839-5c2a48a1b283')
     def test_list_services(self):
         services = self.client.list_services()
         self.assertNotEqual(0, len(services))
 
     @test.attr(type='gate')
+    @test.idempotent_id('f345b1ec-bc6e-4c38-a527-3ca2bc00bef5')
     def test_get_service_by_service_binary_name(self):
         binary_name = 'nova-compute'
         params = {'binary': binary_name}
@@ -44,6 +46,7 @@
             self.assertEqual(binary_name, service['binary'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('affb42d5-5b4b-43c8-8b0b-6dca054abcca')
     def test_get_service_by_host_name(self):
         services = self.client.list_services()
         host_name = services[0]['host']
@@ -63,6 +66,7 @@
         self.assertEqual(sorted(s1), sorted(s2))
 
     @test.attr(type='gate')
+    @test.idempotent_id('39397f6f-37b8-4234-8671-281e44c74025')
     def test_get_service_by_service_and_host_name(self):
         services = self.client.list_services()
         host_name = services[0]['host']
diff --git a/tempest/api/compute/admin/test_services_negative.py b/tempest/api/compute/admin/test_services_negative.py
index bb19a39..b8974ca 100644
--- a/tempest/api/compute/admin/test_services_negative.py
+++ b/tempest/api/compute/admin/test_services_negative.py
@@ -12,8 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -30,11 +31,13 @@
         cls.non_admin_client = cls.services_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1126d1f8-266e-485f-a687-adc547492646')
     def test_list_services_with_non_admin_user(self):
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_services)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d0884a69-f693-4e79-a9af-232d15643bf7')
     def test_get_service_by_invalid_params(self):
         # return all services if send the request with invalid parameter
         services = self.client.list_services()
@@ -43,6 +46,7 @@
         self.assertEqual(len(services), len(services_xxx))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1e966d4a-226e-47c7-b601-0b18a27add54')
     def test_get_service_by_invalid_service_and_valid_host(self):
         services = self.client.list_services()
         host_name = services[0]['host']
@@ -51,6 +55,7 @@
         self.assertEqual(0, len(services))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('64e7e7fb-69e8-4cb6-a71d-8d5eb0c98655')
     def test_get_service_with_valid_service_and_invalid_host(self):
         services = self.client.list_services()
         binary_name = services[0]['binary']
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage.py b/tempest/api/compute/admin/test_simple_tenant_usage.py
index f6553b3..be62b1d 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage.py
@@ -30,7 +30,7 @@
         cls.tenant_id = cls.client.tenant_id
 
         # Create a server in the demo tenant
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+        cls.create_test_server(wait_until='ACTIVE')
         time.sleep(2)
 
         now = datetime.datetime.now()
@@ -43,33 +43,33 @@
         return at.strftime('%Y-%m-%dT%H:%M:%S.%f')
 
     @test.attr(type='gate')
+    @test.idempotent_id('062c8ae9-9912-4249-8b51-e38d664e926e')
     def test_list_usage_all_tenants(self):
         # Get usage for all tenants
         params = {'start': self.start,
                   'end': self.end,
                   'detailed': int(bool(True))}
-        resp, tenant_usage = self.adm_client.list_tenant_usages(params)
-        self.assertEqual(200, resp.status)
+        tenant_usage = self.adm_client.list_tenant_usages(params)
         self.assertEqual(len(tenant_usage), 8)
 
     @test.attr(type='gate')
+    @test.idempotent_id('94135049-a4c5-4934-ad39-08fa7da4f22e')
     def test_get_usage_tenant(self):
         # Get usage for a specific tenant
         params = {'start': self.start,
                   'end': self.end}
-        resp, tenant_usage = self.adm_client.get_tenant_usage(
+        tenant_usage = self.adm_client.get_tenant_usage(
             self.tenant_id, params)
 
-        self.assertEqual(200, resp.status)
         self.assertEqual(len(tenant_usage), 8)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9d00a412-b40e-4fd9-8eba-97b496316116')
     def test_get_usage_tenant_with_non_admin_user(self):
         # Get usage for a specific tenant with non admin user
         params = {'start': self.start,
                   'end': self.end}
-        resp, tenant_usage = self.client.get_tenant_usage(
+        tenant_usage = self.client.get_tenant_usage(
             self.tenant_id, params)
 
-        self.assertEqual(200, resp.status)
         self.assertEqual(len(tenant_usage), 8)
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
index 8c31d7c..8801e85 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
@@ -14,9 +14,9 @@
 #    under the License.
 
 import datetime
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -38,28 +38,31 @@
         return at.strftime('%Y-%m-%dT%H:%M:%S.%f')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8b21e135-d94b-4991-b6e9-87059609c8ed')
     def test_get_usage_tenant_with_empty_tenant_id(self):
         # Get usage for a specific tenant empty
         params = {'start': self.start,
                   'end': self.end}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.adm_client.get_tenant_usage,
                           '', params)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4079dd2a-9e8d-479f-869d-6fa985ce45b6')
     def test_get_usage_tenant_with_invalid_date(self):
         # Get usage for tenant with invalid date
         params = {'start': self.end,
                   'end': self.start}
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.adm_client.get_tenant_usage,
                           self.client.tenant_id, params)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bbe6fe2c-15d8-404c-a0a2-44fad0ad5cc7')
     def test_list_usage_all_tenants_with_non_admin_user(self):
         # Get usage for all tenants with non admin user
         params = {'start': self.start,
                   'end': self.end,
                   'detailed': int(bool(True))}
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.client.list_tenant_usages, params)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 3e80bf2..89818b1 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -13,9 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import time
 
 from tempest import clients
+from tempest.common import credentials
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -35,15 +37,60 @@
     force_tenant_isolation = False
 
     @classmethod
-    def resource_setup(cls):
-        cls.set_network_resources()
-        super(BaseComputeTest, cls).resource_setup()
+    def skip_checks(cls):
+        super(BaseComputeTest, cls).skip_checks()
+        if cls._api_version != 2:
+            msg = ("Unexpected API version is specified (%s)" %
+                   cls._api_version)
+            raise exceptions.InvalidConfiguration(message=msg)
 
+    @classmethod
+    def setup_credentials(cls):
+        cls.set_network_resources()
+        super(BaseComputeTest, cls).setup_credentials()
         # TODO(andreaf) WE should care also for the alt_manager here
         # but only once client lazy load in the manager is done
         cls.os = cls.get_client_manager()
+        # Note that we put this here and not in skip_checks because in
+        # the case of preprovisioned users we won't know if we can get
+        # two distinct users until we go and lock them
         cls.multi_user = cls.check_multi_user()
 
+    @classmethod
+    def setup_clients(cls):
+        super(BaseComputeTest, cls).setup_clients()
+        cls.servers_client = cls.os.servers_client
+        cls.flavors_client = cls.os.flavors_client
+        cls.images_client = cls.os.images_client
+        cls.extensions_client = cls.os.extensions_client
+        cls.floating_ips_client = cls.os.floating_ips_client
+        cls.keypairs_client = cls.os.keypairs_client
+        cls.security_groups_client = cls.os.security_groups_client
+        cls.quotas_client = cls.os.quotas_client
+        # NOTE(mriedem): os-quota-class-sets is v2 API only
+        cls.quota_classes_client = cls.os.quota_classes_client
+        # NOTE(mriedem): os-networks is v2 API only
+        cls.networks_client = cls.os.networks_client
+        cls.limits_client = cls.os.limits_client
+        cls.volumes_extensions_client = cls.os.volumes_extensions_client
+        cls.volumes_client = cls.os.volumes_client
+        cls.interfaces_client = cls.os.interfaces_client
+        cls.fixed_ips_client = cls.os.fixed_ips_client
+        cls.availability_zone_client = cls.os.availability_zone_client
+        cls.agents_client = cls.os.agents_client
+        cls.aggregates_client = cls.os.aggregates_client
+        cls.services_client = cls.os.services_client
+        cls.instance_usages_audit_log_client = (
+            cls.os.instance_usages_audit_log_client)
+        cls.hypervisor_client = cls.os.hypervisor_client
+        cls.certificates_client = cls.os.certificates_client
+        cls.migrations_client = cls.os.migrations_client
+        cls.security_group_default_rules_client = (
+            cls.os.security_group_default_rules_client)
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaseComputeTest, cls).resource_setup()
         cls.build_interval = CONF.compute.build_interval
         cls.build_timeout = CONF.compute.build_timeout
         cls.ssh_user = CONF.compute.ssh_user
@@ -58,39 +105,13 @@
         cls.security_groups = []
         cls.server_groups = []
 
-        if cls._api_version == 2:
-            cls.servers_client = cls.os.servers_client
-            cls.flavors_client = cls.os.flavors_client
-            cls.images_client = cls.os.images_client
-            cls.extensions_client = cls.os.extensions_client
-            cls.floating_ips_client = cls.os.floating_ips_client
-            cls.keypairs_client = cls.os.keypairs_client
-            cls.security_groups_client = cls.os.security_groups_client
-            cls.quotas_client = cls.os.quotas_client
-            # NOTE(mriedem): os-quota-class-sets is v2 API only
-            cls.quota_classes_client = cls.os.quota_classes_client
-            # NOTE(mriedem): os-networks is v2 API only
-            cls.networks_client = cls.os.networks_client
-            cls.limits_client = cls.os.limits_client
-            cls.volumes_extensions_client = cls.os.volumes_extensions_client
-            cls.volumes_client = cls.os.volumes_client
-            cls.interfaces_client = cls.os.interfaces_client
-            cls.fixed_ips_client = cls.os.fixed_ips_client
-            cls.availability_zone_client = cls.os.availability_zone_client
-            cls.agents_client = cls.os.agents_client
-            cls.aggregates_client = cls.os.aggregates_client
-            cls.services_client = cls.os.services_client
-            cls.instance_usages_audit_log_client = \
-                cls.os.instance_usages_audit_log_client
-            cls.hypervisor_client = cls.os.hypervisor_client
-            cls.certificates_client = cls.os.certificates_client
-            cls.migrations_client = cls.os.migrations_client
-            cls.security_group_default_rules_client = (
-                cls.os.security_group_default_rules_client)
-        else:
-            msg = ("Unexpected API version is specified (%s)" %
-                   cls._api_version)
-            raise exceptions.InvalidConfiguration(message=msg)
+    @classmethod
+    def resource_cleanup(cls):
+        cls.clear_images()
+        cls.clear_servers()
+        cls.clear_security_groups()
+        cls.clear_server_groups()
+        super(BaseComputeTest, cls).resource_cleanup()
 
     @classmethod
     def check_multi_user(cls):
@@ -107,7 +128,7 @@
         for server in cls.servers:
             try:
                 cls.servers_client.delete_server(server['id'])
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 # Something else already cleaned up the server, nothing to be
                 # worried about
                 pass
@@ -147,7 +168,7 @@
         for image_id in cls.images:
             try:
                 cls.images_client.delete_image(image_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 # The image may have already been deleted which is OK.
                 pass
             except Exception:
@@ -160,7 +181,7 @@
         for sg in cls.security_groups:
             try:
                 cls.security_groups_client.delete_security_group(sg['id'])
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 # The security group may have already been deleted which is OK.
                 pass
             except Exception as exc:
@@ -174,7 +195,7 @@
         for server_group_id in cls.server_groups:
             try:
                 cls.servers_client.delete_server_group(server_group_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 # The server-group may have already been deleted which is OK.
                 pass
             except Exception:
@@ -182,14 +203,6 @@
                               server_group_id)
 
     @classmethod
-    def resource_cleanup(cls):
-        cls.clear_images()
-        cls.clear_servers()
-        cls.clear_security_groups()
-        cls.clear_server_groups()
-        super(BaseComputeTest, cls).resource_cleanup()
-
-    @classmethod
     def create_test_server(cls, **kwargs):
         """Wrapper utility that returns a test server."""
         name = data_utils.rand_name(cls.__name__ + "-instance")
@@ -198,14 +211,14 @@
         flavor = kwargs.get('flavor', cls.flavor_ref)
         image_id = kwargs.get('image_id', cls.image_ref)
 
-        resp, body = cls.servers_client.create_server(
+        body = cls.servers_client.create_server(
             name, image_id, flavor, **kwargs)
 
         # handle the case of multiple servers
         servers = [body]
         if 'min_count' in kwargs or 'max_count' in kwargs:
             # Get servers created which name match with name param.
-            r, b = cls.servers_client.list_servers()
+            b = cls.servers_client.list_servers()
             servers = [s for s in b['servers'] if s['name'].startswith(name)]
 
         if 'wait_until' in kwargs:
@@ -226,7 +239,7 @@
 
         cls.servers.extend(servers)
 
-        return resp, body
+        return body
 
     @classmethod
     def create_security_group(cls, name=None, description=None):
@@ -247,9 +260,9 @@
             name = data_utils.rand_name(cls.__name__ + "-Server-Group")
         if policy is None:
             policy = ['affinity']
-        resp, body = cls.servers_client.create_server_group(name, policy)
+        body = cls.servers_client.create_server_group(name, policy)
         cls.server_groups.append(body['id'])
-        return resp, body
+        return body
 
     def wait_for(self, condition):
         """Repeatedly calls condition() until a timeout."""
@@ -274,7 +287,7 @@
             # TODO(mriedem): We should move the wait_for_resource_deletion
             # into the delete_volume method as a convenience to the caller.
             volumes_client.wait_for_resource_deletion(volume_id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             LOG.warn("Unable to delete volume '%s' since it was not found. "
                      "Maybe it was already deleted?" % volume_id)
 
@@ -316,7 +329,7 @@
                 cls.servers_client.wait_for_server_termination(server_id)
             except Exception:
                 LOG.exception('Failed to delete server %s' % server_id)
-        resp, server = cls.create_test_server(wait_until='ACTIVE', **kwargs)
+        server = cls.create_test_server(wait_until='ACTIVE', **kwargs)
         cls.password = server['adminPass']
         return server['id']
 
@@ -328,24 +341,27 @@
 
 class BaseV2ComputeTest(BaseComputeTest):
     _api_version = 2
-    _interface = "json"
 
 
 class BaseComputeAdminTest(BaseComputeTest):
     """Base test case class for Compute Admin API tests."""
-    _interface = "json"
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseComputeAdminTest, cls).resource_setup()
-        try:
-            creds = cls.isolated_creds.get_admin_creds()
-            cls.os_adm = clients.Manager(
-                credentials=creds, interface=cls._interface)
-        except NotImplementedError:
-            msg = ("Missing Compute Admin API credentials in configuration.")
+    def skip_checks(cls):
+        if not credentials.is_admin_available():
+            msg = ("Missing Identity Admin API credentials in configuration.")
             raise cls.skipException(msg)
+        super(BaseComputeAdminTest, cls).skip_checks()
 
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseComputeAdminTest, cls).setup_credentials()
+        creds = cls.isolated_creds.get_admin_creds()
+        cls.os_adm = clients.Manager(credentials=creds)
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseComputeAdminTest, cls).setup_clients()
         cls.availability_zone_admin_client = (
             cls.os_adm.availability_zone_client)
 
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index 15ccf53..2be201a 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -22,16 +22,17 @@
     _api_version = 2
 
     @test.attr(type='gate')
+    @test.idempotent_id('c070a441-b08e-447e-a733-905909535b1b')
     def test_create_root_certificate(self):
         # create certificates
-        resp, body = self.certificates_client.create_certificate()
+        body = self.certificates_client.create_certificate()
         self.assertIn('data', body)
         self.assertIn('private_key', body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3ac273d0-92d2-4632-bdfc-afbc21d4606c')
     def test_get_root_certificate(self):
         # get the root certificate
-        resp, body = self.certificates_client.get_certificate('root')
-        self.assertEqual(200, resp.status)
+        body = self.certificates_client.get_certificate('root')
         self.assertIn('data', body)
         self.assertIn('private_key', body)
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index c91ce17..b9056c7 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -29,6 +29,7 @@
         cls.client = cls.flavors_client
 
     @test.attr(type='smoke')
+    @test.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()
@@ -38,6 +39,7 @@
         self.assertIn(flavor_min_detail, flavors)
 
     @test.attr(type='smoke')
+    @test.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_with_detail()
@@ -45,12 +47,14 @@
         self.assertIn(flavor, flavors)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1f12046b-753d-40d2-abb6-d8eb8b30cb2f')
     def test_get_flavor(self):
         # The expected flavor details should be returned
         flavor = self.client.get_flavor_details(self.flavor_ref)
         self.assertEqual(self.flavor_ref, flavor['id'])
 
     @test.attr(type='gate')
+    @test.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}
@@ -58,6 +62,7 @@
         self.assertEqual(1, len(flavors))
 
     @test.attr(type='gate')
+    @test.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}
@@ -65,6 +70,7 @@
         self.assertEqual(1, len(flavors))
 
     @test.attr(type='gate')
+    @test.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.get_flavor_details(self.flavor_ref)
@@ -76,6 +82,7 @@
                          'The list of flavors did not start after the marker.')
 
     @test.attr(type='gate')
+    @test.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.get_flavor_details(self.flavor_ref)
@@ -87,6 +94,7 @@
                          'The list of flavors did not start after the marker.')
 
     @test.attr(type='gate')
+    @test.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.get_flavor_details(self.flavor_ref)
@@ -97,6 +105,7 @@
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
+    @test.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.get_flavor_details(self.flavor_ref)
@@ -107,6 +116,7 @@
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
+    @test.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.get_flavor_details(self.flavor_ref)
@@ -117,6 +127,7 @@
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
+    @test.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.get_flavor_details(self.flavor_ref)
diff --git a/tempest/api/compute/floating_ips/base.py b/tempest/api/compute/floating_ips/base.py
index 19b6a50..142eaec 100644
--- a/tempest/api/compute/floating_ips/base.py
+++ b/tempest/api/compute/floating_ips/base.py
@@ -19,8 +19,8 @@
 class BaseFloatingIPsTest(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def setup_credentials(cls):
         # Floating IP actions might need a full network configuration
         cls.set_network_resources(network=True, subnet=True,
                                   router=True, dhcp=True)
-        super(BaseFloatingIPsTest, cls).resource_setup()
+        super(BaseFloatingIPsTest, cls).setup_credentials()
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 e6f4fb0..f65223e 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -17,7 +17,6 @@
 
 from tempest.api.compute.floating_ips import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -26,16 +25,20 @@
     floating_ip = None
 
     @classmethod
+    def setup_clients(cls):
+        super(FloatingIPsTestJSON, cls).setup_clients()
+        cls.client = cls.floating_ips_client
+
+    @classmethod
     def resource_setup(cls):
         super(FloatingIPsTestJSON, cls).resource_setup()
-        cls.client = cls.floating_ips_client
         cls.floating_ip_id = None
 
         # Server creation
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
         # Floating IP creation
-        resp, body = cls.client.create_floating_ip()
+        body = cls.client.create_floating_ip()
         cls.floating_ip_id = body['id']
         cls.floating_ip = body['ip']
 
@@ -43,7 +46,7 @@
     def resource_cleanup(cls):
         # Deleting the floating IP which is created in this method
         if cls.floating_ip_id:
-            resp, body = cls.client.delete_floating_ip(cls.floating_ip_id)
+            cls.client.delete_floating_ip(cls.floating_ip_id)
         super(FloatingIPsTestJSON, cls).resource_cleanup()
 
     def _try_delete_floating_ip(self, floating_ip_id):
@@ -51,93 +54,89 @@
         try:
             self.client.delete_floating_ip(floating_ip_id)
         # if not found, it depicts it was deleted in the test
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
 
     @test.attr(type='gate')
+    @test.idempotent_id('f7bfb946-297e-41b8-9e8c-aba8e9bb5194')
     @test.services('network')
     def test_allocate_floating_ip(self):
         # Positive test:Allocation of a new floating IP to a project
         # should be successful
-        resp, body = self.client.create_floating_ip()
+        body = self.client.create_floating_ip()
         floating_ip_id_allocated = body['id']
         self.addCleanup(self.client.delete_floating_ip,
                         floating_ip_id_allocated)
-        self.assertEqual(200, resp.status)
-        resp, floating_ip_details = \
+        floating_ip_details = \
             self.client.get_floating_ip_details(floating_ip_id_allocated)
         # Checking if the details of allocated IP is in list of floating IP
-        resp, body = self.client.list_floating_ips()
+        body = self.client.list_floating_ips()
         self.assertIn(floating_ip_details, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('de45e989-b5ca-4a9b-916b-04a52e7bbb8b')
     @test.services('network')
     def test_delete_floating_ip(self):
         # Positive test:Deletion of valid floating IP from project
         # should be successful
         # Creating the floating IP that is to be deleted in this method
-        resp, floating_ip_body = self.client.create_floating_ip()
+        floating_ip_body = self.client.create_floating_ip()
         self.addCleanup(self._try_delete_floating_ip, floating_ip_body['id'])
-        # Storing the details of floating IP before deleting it
-        cli_resp = self.client.get_floating_ip_details(floating_ip_body['id'])
-        resp, floating_ip_details = cli_resp
         # Deleting the floating IP from the project
-        resp, body = self.client.delete_floating_ip(floating_ip_body['id'])
-        self.assertEqual(202, resp.status)
+        self.client.delete_floating_ip(floating_ip_body['id'])
         # Check it was really deleted.
         self.client.wait_for_resource_deletion(floating_ip_body['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('307efa27-dc6f-48a0-8cd2-162ce3ef0b52')
     @test.services('network')
     def test_associate_disassociate_floating_ip(self):
         # Positive test:Associate and disassociate the provided floating IP
         # to a specific server should be successful
 
         # Association of floating IP to fixed IP address
-        resp, body = self.client.associate_floating_ip_to_server(
+        self.client.associate_floating_ip_to_server(
             self.floating_ip,
             self.server_id)
-        self.assertEqual(202, resp.status)
 
         # Check instance_id in the floating_ip body
-        resp, body = self.client.get_floating_ip_details(self.floating_ip_id)
+        body = self.client.get_floating_ip_details(self.floating_ip_id)
         self.assertEqual(self.server_id, body['instance_id'])
 
         # Disassociation of floating IP that was associated in this method
-        resp, body = self.client.disassociate_floating_ip_from_server(
+        self.client.disassociate_floating_ip_from_server(
             self.floating_ip,
             self.server_id)
-        self.assertEqual(202, resp.status)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6edef4b2-aaf1-4abc-bbe3-993e2561e0fe')
     @test.services('network')
     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
         # Create server so as to use for Multiple association
         new_name = data_utils.rand_name('floating_server')
-        resp, body = self.create_test_server(name=new_name)
+        body = self.create_test_server(name=new_name)
         self.servers_client.wait_for_server_status(body['id'], 'ACTIVE')
         self.new_server_id = body['id']
+        self.addCleanup(self.servers_client.delete_server, self.new_server_id)
 
         # Associating floating IP for the first time
-        resp, _ = self.client.associate_floating_ip_to_server(
+        self.client.associate_floating_ip_to_server(
             self.floating_ip,
             self.server_id)
         # Associating floating IP for the second time
-        resp, body = self.client.associate_floating_ip_to_server(
+        self.client.associate_floating_ip_to_server(
             self.floating_ip,
             self.new_server_id)
 
-        self.addCleanup(self.servers_client.delete_server, self.new_server_id)
-        if (resp['status'] is not None):
-            self.addCleanup(self.client.disassociate_floating_ip_from_server,
-                            self.floating_ip,
-                            self.new_server_id)
+        self.addCleanup(self.client.disassociate_floating_ip_from_server,
+                        self.floating_ip,
+                        self.new_server_id)
 
         # Make sure no longer associated with old server
-        self.assertRaises((exceptions.NotFound,
+        self.assertRaises((lib_exc.NotFound,
                            lib_exc.UnprocessableEntity,
-                           exceptions.Conflict),
+                           lib_exc.Conflict),
                           self.client.disassociate_floating_ip_from_server,
                           self.floating_ip, self.server_id)
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index b08df97..2c08ae7 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -15,10 +15,11 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute.floating_ips import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -28,16 +29,20 @@
     server_id = None
 
     @classmethod
-    def resource_setup(cls):
-        super(FloatingIPsNegativeTestJSON, cls).resource_setup()
+    def setup_clients(cls):
+        super(FloatingIPsNegativeTestJSON, cls).setup_clients()
         cls.client = cls.floating_ips_client
 
+    @classmethod
+    def resource_setup(cls):
+        super(FloatingIPsNegativeTestJSON, cls).resource_setup()
+
         # Server creation
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
         # Generating a nonexistent floatingIP id
         cls.floating_ip_ids = []
-        resp, body = cls.client.list_floating_ips()
+        body = cls.client.list_floating_ips()
         for i in range(len(body)):
             cls.floating_ip_ids.append(body[i]['id'])
         while True:
@@ -48,48 +53,53 @@
                 break
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6e0f059b-e4dd-48fb-8207-06e3bba5b074')
     @test.services('network')
     def test_allocate_floating_ip_from_nonexistent_pool(self):
         # Negative test:Allocation of a new floating IP from a nonexistent_pool
         # to a project should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.create_floating_ip,
                           "non_exist_pool")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ae1c55a8-552b-44d4-bfb6-2a115a15d0ba')
     @test.services('network')
     def test_delete_nonexistent_floating_ip(self):
         # Negative test:Deletion of a nonexistent floating IP
         # from project should fail
 
         # Deleting the non existent floating IP
-        self.assertRaises(exceptions.NotFound, self.client.delete_floating_ip,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_floating_ip,
                           self.non_exist_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('595fa616-1a71-4670-9614-46564ac49a4c')
     @test.services('network')
     def test_associate_nonexistent_floating_ip(self):
         # Negative test:Association of a non existent floating IP
         # to specific server should fail
         # Associating non existent floating IP
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.associate_floating_ip_to_server,
                           "0.0.0.0", self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0a081a66-e568-4e6b-aa62-9587a876dca8')
     @test.services('network')
     def test_dissociate_nonexistent_floating_ip(self):
         # Negative test:Dissociation of a non existent floating IP should fail
         # Dissociating non existent floating IP
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.disassociate_floating_ip_from_server,
                           "0.0.0.0", self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('804b4fcb-bbf5-412f-925d-896672b61eb3')
     @test.services('network')
     def test_associate_ip_to_server_without_passing_floating_ip(self):
         # Negative test:Association of empty floating IP to specific server
         # should raise NotFound or BadRequest(In case of Nova V2.1) exception.
-        self.assertRaises((exceptions.NotFound, exceptions.BadRequest),
+        self.assertRaises((lib_exc.NotFound, lib_exc.BadRequest),
                           self.client.associate_floating_ip_to_server,
                           '', self.server_id)
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 7af9ca7..c18ecb7 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -20,13 +20,17 @@
 class FloatingIPDetailsTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
+    def setup_clients(cls):
+        super(FloatingIPDetailsTestJSON, cls).setup_clients()
+        cls.client = cls.floating_ips_client
+
+    @classmethod
     def resource_setup(cls):
         super(FloatingIPDetailsTestJSON, cls).resource_setup()
-        cls.client = cls.floating_ips_client
         cls.floating_ip = []
         cls.floating_ip_id = []
         for i in range(3):
-            resp, body = cls.client.create_floating_ip()
+            body = cls.client.create_floating_ip()
             cls.floating_ip.append(body)
             cls.floating_ip_id.append(body['id'])
 
@@ -37,11 +41,11 @@
         super(FloatingIPDetailsTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('16db31c3-fb85-40c9-bbe2-8cf7b67ff99f')
     @test.services('network')
     def test_list_floating_ips(self):
         # Positive test:Should return the list of floating IPs
-        resp, body = self.client.list_floating_ips()
-        self.assertEqual(200, resp.status)
+        body = self.client.list_floating_ips()
         floating_ips = body
         self.assertNotEqual(0, len(floating_ips),
                             "Expected floating IPs. Got zero.")
@@ -49,20 +53,19 @@
             self.assertIn(self.floating_ip[i], floating_ips)
 
     @test.attr(type='gate')
+    @test.idempotent_id('eef497e0-8ff7-43c8-85ef-558440574f84')
     @test.services('network')
     def test_get_floating_ip_details(self):
         # Positive test:Should be able to GET the details of floatingIP
         # Creating a floating IP for which details are to be checked
-        resp, body = self.client.create_floating_ip()
+        body = self.client.create_floating_ip()
         floating_ip_id = body['id']
         self.addCleanup(self.client.delete_floating_ip,
                         floating_ip_id)
         floating_ip_instance_id = body['instance_id']
         floating_ip_ip = body['ip']
         floating_ip_fixed_ip = body['fixed_ip']
-        resp, body = \
-            self.client.get_floating_ip_details(floating_ip_id)
-        self.assertEqual(200, resp.status)
+        body = self.client.get_floating_ip_details(floating_ip_id)
         # Comparing the details of floating IP
         self.assertEqual(floating_ip_instance_id,
                          body['instance_id'])
@@ -72,10 +75,10 @@
         self.assertEqual(floating_ip_id, body['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('df389fc8-56f5-43cc-b290-20eda39854d3')
     @test.services('network')
     def test_list_floating_ip_pools(self):
         # Positive test:Should return the list of floating IP Pools
-        resp, floating_ip_pools = self.client.list_floating_ip_pools()
-        self.assertEqual(200, resp.status)
+        floating_ip_pools = self.client.list_floating_ip_pools()
         self.assertNotEqual(0, len(floating_ip_pools),
                             "Expected floating IP Pools. Got zero.")
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
index c343018..13d0719 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
@@ -15,10 +15,11 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -27,11 +28,12 @@
 class FloatingIPDetailsNegativeTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(FloatingIPDetailsNegativeTestJSON, cls).resource_setup()
+    def setup_clients(cls):
+        super(FloatingIPDetailsNegativeTestJSON, cls).setup_clients()
         cls.client = cls.floating_ips_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7ab18834-4a4b-4f28-a2c5-440579866695')
     @test.services('network')
     def test_get_nonexistent_floating_ip_details(self):
         # Negative test:Should not be able to GET the details
@@ -41,5 +43,5 @@
             non_exist_id = str(uuid.uuid4())
         else:
             non_exist_id = data_utils.rand_int_id(start=999)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_floating_ip_details, non_exist_id)
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index c3b144d..8193a55 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -53,6 +53,7 @@
         self.client.set_image_metadata(self.image_id, meta)
 
     @test.attr(type='gate')
+    @test.idempotent_id('37ec6edd-cf30-4c53-bd45-ae74db6b0531')
     def test_list_image_metadata(self):
         # All metadata key/value pairs for an image should be returned
         resp_metadata = self.client.list_image_metadata(self.image_id)
@@ -60,6 +61,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ece7befc-d3ce-42a4-b4be-c3067a418c29')
     def test_set_image_metadata(self):
         # The metadata for the image should match the new values
         req_metadata = {'os_version': 'value2', 'architecture': 'value3'}
@@ -70,6 +72,7 @@
         self.assertEqual(req_metadata, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7b491c11-a9d5-40fe-a696-7f7e03d3fea2')
     def test_update_image_metadata(self):
         # The metadata for the image should match the updated values
         req_metadata = {'os_version': 'alt1', 'architecture': 'value3'}
@@ -83,6 +86,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4f5db52f-6685-4c75-b848-f4bb363f9aa6')
     def test_get_image_metadata_item(self):
         # The value for a specific metadata key should be returned
         meta = self.client.get_image_metadata_item(self.image_id,
@@ -90,6 +94,7 @@
         self.assertEqual('value2', meta['os_distro'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('f2de776a-4778-4d90-a5da-aae63aee64ae')
     def test_set_image_metadata_item(self):
         # The value provided for the given meta item should be set for
         # the image
@@ -101,6 +106,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a013796c-ba37-4bb5-8602-d944511def14')
     def test_delete_image_metadata_item(self):
         # The metadata value/key pair should be deleted from the image
         self.client.delete_image_metadata_item(self.image_id,
diff --git a/tempest/api/compute/images/test_image_metadata_negative.py b/tempest/api/compute/images/test_image_metadata_negative.py
index 73412ff..d181ed9 100644
--- a/tempest/api/compute/images/test_image_metadata_negative.py
+++ b/tempest/api/compute/images/test_image_metadata_negative.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -27,48 +28,54 @@
         cls.client = cls.images_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('94069db2-792f-4fa8-8bd3-2271a6e0c095')
     def test_list_nonexistent_image_metadata(self):
         # Negative test: List on nonexistent image
         # metadata should not happen
-        self.assertRaises(exceptions.NotFound, self.client.list_image_metadata,
+        self.assertRaises(lib_exc.NotFound, self.client.list_image_metadata,
                           data_utils.rand_uuid())
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a403ef9e-9f95-427c-b70a-3ce3388796f1')
     def test_update_nonexistent_image_metadata(self):
         # Negative test:An update should not happen for a non-existent image
         meta = {'os_distro': 'alt1', 'os_version': 'alt2'}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.update_image_metadata,
                           data_utils.rand_uuid(), meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('41ae052c-6ee6-405c-985e-5712393a620d')
     def test_get_nonexistent_image_metadata_item(self):
         # Negative test: Get on non-existent image should not happen
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_image_metadata_item,
                           data_utils.rand_uuid(), 'os_version')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dc64f2ce-77e8-45b0-88c8-e15041d08eaf')
     def test_set_nonexistent_image_metadata(self):
         # Negative test: Metadata should not be set to a non-existent image
         meta = {'os_distro': 'alt1', 'os_version': 'alt2'}
-        self.assertRaises(exceptions.NotFound, self.client.set_image_metadata,
+        self.assertRaises(lib_exc.NotFound, self.client.set_image_metadata,
                           data_utils.rand_uuid(), meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('2154fd03-ab54-457c-8874-e6e3eb56e9cf')
     def test_set_nonexistent_image_metadata_item(self):
         # Negative test: Metadata item should not be set to a
         # nonexistent image
         meta = {'os_distro': 'alt'}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.set_image_metadata_item,
                           data_utils.rand_uuid(), 'os_distro',
                           meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('848e157f-6bcf-4b2e-a5dd-5124025a8518')
     def test_delete_nonexistent_image_metadata_item(self):
         # Negative test: Shouldn't be able to delete metadata
         # item from non-existent image
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_image_metadata_item,
                           data_utils.rand_uuid(), 'os_distro')
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index dc27a70..396d629 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -38,9 +38,10 @@
         cls.servers_client = cls.servers_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('aa06b52b-2db5-4807-b218-9441f75d74e3')
     def test_delete_saving_image(self):
         snapshot_name = data_utils.rand_name('test-snap-')
-        resp, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
         self.addCleanup(self.servers_client.delete_server, server['id'])
         image = self.create_image_from_server(server['id'],
                                               name=snapshot_name,
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 58fc20d..ee52f37 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -12,10 +12,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -39,9 +40,10 @@
         cls.servers_client = cls.servers_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6cd5a89d-5b47-46a7-93bc-3916f0d84973')
     def test_create_image_from_deleted_server(self):
         # An image should not be created if the server instance is removed
-        resp, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
 
         # Delete server before trying to create server
         self.servers_client.delete_server(server['id'])
@@ -49,11 +51,12 @@
         # Create a new image after server is deleted
         name = data_utils.rand_name('image')
         meta = {'image_type': 'test'}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.create_image_from_server,
                           server['id'], name=name, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('82c5b0c4-9dbd-463c-872b-20c4755aae7f')
     def test_create_image_from_invalid_server(self):
         # An image should not be created with invalid server id
         # Create a new image with invalid server id
@@ -61,12 +64,13 @@
         meta = {'image_type': 'test'}
         resp = {}
         resp['status'] = None
-        self.assertRaises(exceptions.NotFound, self.create_image_from_server,
+        self.assertRaises(lib_exc.NotFound, self.create_image_from_server,
                           '!@#$%^&*()', name=name, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('aaacd1d0-55a2-4ce8-818a-b5439df8adc9')
     def test_create_image_from_stopped_server(self):
-        resp, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
         self.servers_client.stop(server['id'])
         self.servers_client.wait_for_server_status(server['id'],
                                                    'SHUTOFF')
@@ -80,54 +84,62 @@
         self.assertEqual(snapshot_name, image['name'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ec176029-73dc-4037-8d72-2e4ff60cf538')
     def test_create_image_specify_uuid_35_characters_or_less(self):
         # Return an error if Image ID passed is 35 characters or less
         snapshot_name = data_utils.rand_name('test-snap-')
         test_uuid = ('a' * 35)
-        self.assertRaises(exceptions.NotFound, self.client.create_image,
+        self.assertRaises(lib_exc.NotFound, self.client.create_image,
                           test_uuid, snapshot_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('36741560-510e-4cc2-8641-55fe4dfb2437')
     def test_create_image_specify_uuid_37_characters_or_more(self):
         # Return an error if Image ID passed is 37 characters or more
         snapshot_name = data_utils.rand_name('test-snap-')
         test_uuid = ('a' * 37)
-        self.assertRaises(exceptions.NotFound, self.client.create_image,
+        self.assertRaises(lib_exc.NotFound, self.client.create_image,
                           test_uuid, snapshot_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('381acb65-785a-4942-94ce-d8f8c84f1f0f')
     def test_delete_image_with_invalid_image_id(self):
         # An image should not be deleted with invalid image id
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           '!@$%^&*()')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('137aef61-39f7-44a1-8ddf-0adf82511701')
     def test_delete_non_existent_image(self):
         # Return an error while trying to delete a non-existent image
 
         non_existent_image_id = '11a22b9-12a9-5555-cc11-00ab112223fa'
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           non_existent_image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e6e41425-af5c-4fe6-a4b5-7b7b963ffda5')
     def test_delete_image_blank_id(self):
         # Return an error while trying to delete an image with blank Id
-        self.assertRaises(exceptions.NotFound, self.client.delete_image, '')
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('924540c3-f1f1-444c-8f58-718958b6724e')
     def test_delete_image_non_hex_string_id(self):
         # Return an error while trying to delete an image with non hex id
         image_id = '11a22b9-120q-5555-cc11-00ab112223gj'
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('68e2c175-bd26-4407-ac0f-4ea9ce2139ea')
     def test_delete_image_negative_image_id(self):
         # Return an error while trying to delete an image with negative id
-        self.assertRaises(exceptions.NotFound, self.client.delete_image, -1)
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image, -1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b340030d-82cd-4066-a314-c72fb7c59277')
     def test_delete_image_id_is_over_35_character_limit(self):
         # Return an error while trying to delete image with id over limit
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           '11a22b9-12a9-5555-cc11-00ab112223fa-3fac')
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 79cd27a..abdeb18 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -59,7 +59,7 @@
                         % cls.__name__)
             raise cls.skipException(skip_msg)
 
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
 
     def _get_default_flavor_disk_size(self, flavor_id):
@@ -67,6 +67,7 @@
         return flavor['disk']
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3731d080-d4c5-4872-b41a-64d0d0021314')
     def test_create_delete_image(self):
 
         # Create a new image
@@ -96,6 +97,7 @@
         self.client.wait_for_resource_deletion(image_id)
 
     @test.attr(type=['gate'])
+    @test.idempotent_id('3b7c6fe4-dfe7-477c-9243-b06359db51e6')
     def test_create_image_specify_multibyte_character_image_name(self):
         # prefix character is:
         # http://www.fileformat.info/info/unicode/char/1F4A9/index.htm
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 46cec9b..f6a4aec 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -14,10 +14,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest import test
 
@@ -67,28 +68,31 @@
                         % cls.__name__)
             raise cls.skipException(skip_msg)
 
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
 
         cls.image_ids = []
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('55d1d38c-dd66-4933-9c8e-7d92aeb60ddc')
     def test_create_image_specify_invalid_metadata(self):
         # Return an error when creating image with invalid metadata
         snapshot_name = data_utils.rand_name('test-snap-')
         meta = {'': ''}
-        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           self.server_id, snapshot_name, meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3d24d11f-5366-4536-bd28-cff32b748eca')
     def test_create_image_specify_metadata_over_limits(self):
         # Return an error when creating image with meta data over 256 chars
         snapshot_name = data_utils.rand_name('test-snap-')
         meta = {'a' * 260: 'b' * 260}
-        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           self.server_id, snapshot_name, meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0460efcf-ee88-4f94-acef-1bf658695456')
     def test_create_second_image_when_first_image_is_being_saved(self):
         # Disallow creating another image when first image is being saved
 
@@ -102,18 +106,20 @@
 
         # Create second snapshot
         alt_snapshot_name = data_utils.rand_name('test-snap-')
-        self.assertRaises(exceptions.Conflict, self.client.create_image,
+        self.assertRaises(lib_exc.Conflict, self.client.create_image,
                           self.server_id, alt_snapshot_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('084f0cbc-500a-4963-8a4e-312905862581')
     def test_create_image_specify_name_over_256_chars(self):
         # Return an error if snapshot name over 256 characters is passed
 
         snapshot_name = data_utils.rand_name('a' * 260)
-        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           self.server_id, snapshot_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0894954d-2db2-4195-a45b-ffec0bc0187e')
     def test_delete_image_that_is_not_yet_active(self):
         # Return an error while trying to delete an image what is creating
 
@@ -127,4 +133,4 @@
         self.client.delete_image(image_id)
         self.image_ids.remove(image_id)
 
-        self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
+        self.assertRaises(lib_exc.NotFound, self.client.get_image, image_id)
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 742c2dd..6176d85 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -69,8 +69,8 @@
             return
 
         # Create instances and snapshots via nova
-        resp, cls.server1 = cls.create_test_server()
-        resp, cls.server2 = cls.create_test_server(wait_until='ACTIVE')
+        cls.server1 = cls.create_test_server()
+        cls.server2 = cls.create_test_server(wait_until='ACTIVE')
         # NOTE(sdague) this is faster than doing the sync wait_util on both
         cls.servers_client.wait_for_server_status(cls.server1['id'],
                                                   'ACTIVE')
@@ -93,6 +93,7 @@
         cls.snapshot2_id = cls.snapshot2['id']
 
     @test.attr(type='gate')
+    @test.idempotent_id('a3f5b513-aeb3-42a9-b18e-f091ef73254d')
     def test_list_images_filter_by_status(self):
         # The list of images should contain only images with the
         # provided status
@@ -104,6 +105,7 @@
         self.assertTrue(any([i for i in images if i['id'] == self.image3_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('33163b73-79f5-4d07-a7ea-9213bcc468ff')
     def test_list_images_filter_by_name(self):
         # List of all images should contain the expected images filtered
         # by name
@@ -114,6 +116,7 @@
         self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
         self.assertFalse(any([i for i in images if i['id'] == self.image3_id]))
 
+    @test.idempotent_id('9f238683-c763-45aa-b848-232ec3ce3105')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -131,6 +134,7 @@
         self.assertFalse(any([i for i in images
                               if i['id'] == self.snapshot3_id]))
 
+    @test.idempotent_id('05a377b8-28cf-4734-a1e6-2ab5c38bf606')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -150,6 +154,7 @@
             self.assertTrue(any([i for i in images
                                  if i['id'] == self.snapshot3_id]))
 
+    @test.idempotent_id('e3356918-4d3e-4756-81d5-abc4524ba29f')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -168,15 +173,15 @@
                               if i['id'] == self.image_ref]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('3a484ca9-67ba-451e-b494-7fcf28d32d62')
     def test_list_images_limit_results(self):
         # Verify only the expected number of results are returned
         params = {'limit': '1'}
         images = self.client.list_images(params)
-        # when _interface='xml', one element for images_links in images
-        # ref: Question #224349
         self.assertEqual(1, len([x for x in images if 'id' in x]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('18bac3ae-da27-436c-92a9-b22474d13aab')
     def test_list_images_filter_by_changes_since(self):
         # Verify only updated images are returned in the detailed list
 
@@ -188,6 +193,7 @@
         self.assertTrue(found)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9b0ea018-6185-4f71-948a-a123a107988e')
     def test_list_images_with_detail_filter_by_status(self):
         # Detailed list of all images should only contain images
         # with the provided status
@@ -199,6 +205,7 @@
         self.assertTrue(any([i for i in images if i['id'] == self.image3_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('644ea267-9bd9-4f3b-af9f-dffa02396a17')
     def test_list_images_with_detail_filter_by_name(self):
         # Detailed list of all images should contain the expected
         # images filtered by name
@@ -210,6 +217,7 @@
         self.assertFalse(any([i for i in images if i['id'] == self.image3_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ba2fa9a9-b672-47cc-b354-3b4c0600e2cb')
     def test_list_images_with_detail_limit_results(self):
         # Verify only the expected number of results (with full details)
         # are returned
@@ -217,6 +225,7 @@
         images = self.client.list_images_with_detail(params)
         self.assertEqual(1, len(images))
 
+    @test.idempotent_id('8c78f822-203b-4bf6-8bba-56ebd551cf84')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -236,6 +245,7 @@
             self.assertTrue(any([i for i in images
                                  if i['id'] == self.snapshot3_id]))
 
+    @test.idempotent_id('888c0cc0-7223-43c5-9db0-b125fd0a393b')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -255,6 +265,7 @@
                               if i['id'] == self.image_ref]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('7d439e18-ac2e-4827-b049-7e18004712c4')
     def test_list_images_with_detail_filter_by_changes_since(self):
         # Verify an update image is returned
 
diff --git a/tempest/api/compute/images/test_list_image_filters_negative.py b/tempest/api/compute/images/test_list_image_filters_negative.py
index a8f2ae7..e5418ad 100644
--- a/tempest/api/compute/images/test_list_image_filters_negative.py
+++ b/tempest/api/compute/images/test_list_image_filters_negative.py
@@ -12,10 +12,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -32,8 +33,9 @@
         cls.client = cls.images_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('391b0440-432c-4d4b-b5da-c5096aa247eb')
     def test_get_nonexistent_image(self):
         # Check raises a NotFound
         nonexistent_image = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.get_image,
+        self.assertRaises(lib_exc.NotFound, self.client.get_image,
                           nonexistent_image)
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index cd01147..36451ec 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -31,12 +31,14 @@
         cls.client = cls.images_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
     def test_get_image(self):
         # Returns the correct details for a single image
         image = self.client.get_image(self.image_ref)
         self.assertEqual(self.image_ref, image['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fd51b7f4-d4a3-4331-9885-866658112a6f')
     def test_list_images(self):
         # The list of all images should contain the image
         images = self.client.list_images()
@@ -44,6 +46,7 @@
         self.assertTrue(found)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9f94cb6b-7f10-48c5-b911-a0b84d7d4cd6')
     def test_list_images_with_detail(self):
         # Detailed list of all images should contain the expected images
         images = self.client.list_images_with_detail()
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index d7884ab..972f0de 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -36,6 +36,7 @@
         return body
 
     @test.attr(type='gate')
+    @test.idempotent_id('1d1dbedb-d7a0-432a-9d09-83f543c3c19b')
     def test_keypairs_create_list_delete(self):
         # Keypairs created should be available in the response list
         # Create 3 keypairs
@@ -64,6 +65,7 @@
                          % ', '.join(m_key['name'] for m_key in missing_kps))
 
     @test.attr(type='gate')
+    @test.idempotent_id('6c1d3123-4519-4742-9194-622cb1714b7d')
     def test_keypair_create_delete(self):
         # Keypair should be created, verified and deleted
         k_name = data_utils.rand_name('keypair-')
@@ -77,6 +79,7 @@
                         "Field private_key is empty or not found.")
 
     @test.attr(type='gate')
+    @test.idempotent_id('a4233d5d-52d8-47cc-9a25-e1864527e3df')
     def test_get_keypair_detail(self):
         # Keypair should be created, Got details by name and deleted
         k_name = data_utils.rand_name('keypair-')
@@ -92,6 +95,7 @@
                         "Field public_key is empty or not found.")
 
     @test.attr(type='gate')
+    @test.idempotent_id('39c90c6a-304a-49dd-95ec-2366129def05')
     def test_keypair_create_with_pub_key(self):
         # Keypair should be created with a given public key
         k_name = data_utils.rand_name('keypair-')
diff --git a/tempest/api/compute/keypairs/test_keypairs_negative.py b/tempest/api/compute/keypairs/test_keypairs_negative.py
index 4e06d6c..e63f3c7 100644
--- a/tempest/api/compute/keypairs/test_keypairs_negative.py
+++ b/tempest/api/compute/keypairs/test_keypairs_negative.py
@@ -14,9 +14,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -32,62 +33,70 @@
         self.addCleanup(self.client.delete_keypair, keypair_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('29cca892-46ae-4d48-bc32-8fe7e731eb81')
     def test_keypair_create_with_invalid_pub_key(self):
         # Keypair should not be created with a non RSA public key
         k_name = data_utils.rand_name('keypair-')
         pub_key = "ssh-rsa JUNK nova@ubuntu"
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self._create_keypair, k_name, pub_key)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7cc32e47-4c42-489d-9623-c5e2cb5a2fa5')
     def test_keypair_delete_nonexistent_key(self):
         # Non-existent key deletion should throw a proper error
         k_name = data_utils.rand_name("keypair-non-existent-")
-        self.assertRaises(exceptions.NotFound, self.client.delete_keypair,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_keypair,
                           k_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dade320e-69ca-42a9-ba4a-345300f127e0')
     def test_create_keypair_with_empty_public_key(self):
         # Keypair should not be created with an empty public key
         k_name = data_utils.rand_name("keypair-")
         pub_key = ' '
-        self.assertRaises(exceptions.BadRequest, self._create_keypair,
+        self.assertRaises(lib_exc.BadRequest, self._create_keypair,
                           k_name, pub_key)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fc100c19-2926-4b9c-8fdc-d0589ee2f9ff')
     def test_create_keypair_when_public_key_bits_exceeds_maximum(self):
         # Keypair should not be created when public key bits are too long
         k_name = data_utils.rand_name("keypair-")
         pub_key = 'ssh-rsa ' + 'A' * 2048 + ' openstack@ubuntu'
-        self.assertRaises(exceptions.BadRequest, self._create_keypair,
+        self.assertRaises(lib_exc.BadRequest, self._create_keypair,
                           k_name, pub_key)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0359a7f1-f002-4682-8073-0c91e4011b7c')
     def test_create_keypair_with_duplicate_name(self):
         # Keypairs with duplicate names should not be created
         k_name = data_utils.rand_name('keypair-')
         self.client.create_keypair(k_name)
         # Now try the same keyname to create another key
-        self.assertRaises(exceptions.Conflict, self._create_keypair,
+        self.assertRaises(lib_exc.Conflict, self._create_keypair,
                           k_name)
         self.client.delete_keypair(k_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1398abe1-4a84-45fb-9294-89f514daff00')
     def test_create_keypair_with_empty_name_string(self):
         # Keypairs with name being an empty string should not be created
-        self.assertRaises(exceptions.BadRequest, self._create_keypair,
+        self.assertRaises(lib_exc.BadRequest, self._create_keypair,
                           '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3faa916f-779f-4103-aca7-dc3538eee1b7')
     def test_create_keypair_with_long_keynames(self):
         # Keypairs with name longer than 255 chars should not be created
         k_name = 'keypair-'.ljust(260, '0')
-        self.assertRaises(exceptions.BadRequest, self._create_keypair,
+        self.assertRaises(lib_exc.BadRequest, self._create_keypair,
                           k_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('45fbe5e0-acb5-49aa-837a-ff8d0719db91')
     def test_create_keypair_invalid_name(self):
         # Keypairs with name being an invalid name should not be created
         k_name = 'key_/.\@:'
-        self.assertRaises(exceptions.BadRequest, self._create_keypair,
+        self.assertRaises(lib_exc.BadRequest, self._create_keypair,
                           k_name)
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index 520dfa9..39ed2a1 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -20,11 +20,12 @@
 class AbsoluteLimitsTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(AbsoluteLimitsTestJSON, cls).resource_setup()
+    def setup_clients(cls):
+        super(AbsoluteLimitsTestJSON, cls).setup_clients()
         cls.client = cls.limits_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('b54c66af-6ab6-4cf0-a9e5-a0cb58d75e0b')
     def test_absLimits_get(self):
         # To check if all limits are present in the response
         absolute_limits = self.client.get_absolute_limits()
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index d537d83..507f24e 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common import tempest_fixtures as fixtures
-from tempest import exceptions
 from tempest import test
 
 
@@ -27,12 +28,13 @@
         super(AbsoluteLimitsNegativeTestJSON, self).setUp()
 
     @classmethod
-    def resource_setup(cls):
-        super(AbsoluteLimitsNegativeTestJSON, cls).resource_setup()
+    def setup_clients(cls):
+        super(AbsoluteLimitsNegativeTestJSON, cls).setup_clients()
         cls.client = cls.limits_client
         cls.server_client = cls.servers_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('215cd465-d8ae-49c9-bf33-9c911913a5c8')
     def test_max_image_meta_exceed_limit(self):
         # We should not create vm with image meta over maxImageMeta limit
         # Get max limit value
@@ -51,5 +53,5 @@
 
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised when out of quota
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.create_test_server, meta=meta_data)
diff --git a/tempest/api/compute/security_groups/base.py b/tempest/api/compute/security_groups/base.py
index 05cad9a..f70f6d3 100644
--- a/tempest/api/compute/security_groups/base.py
+++ b/tempest/api/compute/security_groups/base.py
@@ -19,7 +19,7 @@
 class BaseSecurityGroupsTest(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def setup_credentials(cls):
         # A network and a subnet will be created for these tests
         cls.set_network_resources(network=True, subnet=True)
-        super(BaseSecurityGroupsTest, cls).resource_setup()
+        super(BaseSecurityGroupsTest, cls).setup_credentials()
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 527f2dd..70394d8 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -23,9 +23,13 @@
 class SecurityGroupRulesTestJSON(base.BaseSecurityGroupsTest):
 
     @classmethod
+    def setup_clients(cls):
+        super(SecurityGroupRulesTestJSON, cls).setup_clients()
+        cls.client = cls.security_groups_client
+
+    @classmethod
     def resource_setup(cls):
         super(SecurityGroupRulesTestJSON, cls).resource_setup()
-        cls.client = cls.security_groups_client
         cls.neutron_available = CONF.service_available.neutron
         cls.ip_protocol = 'tcp'
         cls.from_port = 22
@@ -56,6 +60,7 @@
                              "Miss-matched key is %s" % key)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('850795d7-d4d3-4e55-b527-a774c0123d3a')
     @test.services('network')
     def test_security_group_rules_create(self):
         # Positive test: Creation of Security Group rule
@@ -74,6 +79,7 @@
         self._check_expected_response(rule)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7a01873e-3c38-4f30-80be-31a043cfe2fd')
     @test.services('network')
     def test_security_group_rules_create_with_optional_cidr(self):
         # Positive test: Creation of Security Group rule
@@ -97,6 +103,7 @@
         self._check_expected_response(rule)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7f5d2899-7705-4d4b-8458-4505188ffab6')
     @test.services('network')
     def test_security_group_rules_create_with_optional_group_id(self):
         # Positive test: Creation of Security Group rule
@@ -125,6 +132,7 @@
         self._check_expected_response(rule)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a6154130-5a55-4850-8be4-5e9e796dbf17')
     @test.services('network')
     def test_security_group_rules_list(self):
         # Positive test: Created Security Group rules should be
@@ -160,6 +168,7 @@
         self.assertTrue(any([i for i in rules if i['id'] == rule2_id]))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fc5c5acf-2091-43a6-a6ae-e42760e9ffaf')
     @test.services('network')
     def test_security_group_rules_delete_when_peer_group_deleted(self):
         # Positive test:rule will delete when peer group deleting
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index d97c404..f6a50ee 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -13,10 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -32,11 +33,12 @@
 class SecurityGroupRulesNegativeTestJSON(base.BaseSecurityGroupsTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(SecurityGroupRulesNegativeTestJSON, cls).resource_setup()
+    def setup_clients(cls):
+        super(SecurityGroupRulesNegativeTestJSON, cls).setup_clients()
         cls.client = cls.security_groups_client
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('1d507e98-7951-469b-82c3-23f1e6b8c254')
     @test.services('network')
     def test_create_security_group_rule_with_non_existent_id(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -46,11 +48,12 @@
         ip_protocol = 'tcp'
         from_port = 22
         to_port = 22
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.create_security_group_rule,
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('2244d7e4-adb7-4ecb-9930-2d77e123ce4f')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_id(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -60,11 +63,12 @@
         ip_protocol = 'tcp'
         from_port = 22
         to_port = 22
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group_rule,
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('8bd56d02-3ffa-4d67-9933-b6b9a01d6089')
     @test.services('network')
     def test_create_security_group_rule_duplicate(self):
         # Negative test: Create Security Group rule duplicate should fail
@@ -83,11 +87,12 @@
                                                    to_port)
         self.addCleanup(self.client.delete_security_group_rule, rule['id'])
         # Add the same rule to the group should fail
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group_rule,
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('84c81249-9f6e-439c-9bbf-cbb0d2cddbdf')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_ip_protocol(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -100,11 +105,12 @@
         from_port = 22
         to_port = 22
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group_rule,
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('12bbc875-1045-4f7a-be46-751277baedb9')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_from_port(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -116,11 +122,12 @@
         ip_protocol = 'tcp'
         from_port = data_utils.rand_int_id(start=65536)
         to_port = 22
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group_rule,
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('ff88804d-144f-45d1-bf59-dd155838a43a')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_to_port(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -132,11 +139,12 @@
         ip_protocol = 'tcp'
         from_port = 22
         to_port = data_utils.rand_int_id(start=65536)
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group_rule,
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('00296fa9-0576-496a-ae15-fbab843189e0')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_port_range(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -148,16 +156,17 @@
         ip_protocol = 'tcp'
         from_port = 22
         to_port = 21
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group_rule,
                           secgroup_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('56fddcca-dbb8-4494-a0db-96e9f869527c')
     @test.services('network')
     def test_delete_security_group_rule_with_non_existent_id(self):
         # Negative test: Deletion of Security Group rule should be FAIL
         # with non existent id
         non_existent_rule_id = not_existing_id()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_security_group_rule,
                           non_existent_rule_id)
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 909d444..5a11854 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -13,20 +13,22 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class SecurityGroupsTestJSON(base.BaseSecurityGroupsTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(SecurityGroupsTestJSON, cls).resource_setup()
+    def setup_clients(cls):
+        super(SecurityGroupsTestJSON, cls).setup_clients()
         cls.client = cls.security_groups_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('eb2b087d-633d-4d0d-a7bd-9e6ba35b32de')
     @test.services('network')
     def test_security_groups_create_list_delete(self):
         # Positive test:Should return the list of Security Groups
@@ -59,6 +61,7 @@
                                             for m_group in deleted_sgs))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ecc0da4a-2117-48af-91af-993cca39a615')
     @test.services('network')
     def test_security_group_create_get_delete(self):
         # Security Group should be created, fetched and deleted
@@ -81,6 +84,7 @@
         self.client.wait_for_resource_deletion(securitygroup['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fe4abc0d-83f5-4c50-ad11-57a1127297a2')
     @test.services('network')
     def test_server_security_groups(self):
         # Checks that security groups may be added and linked to a server
@@ -93,27 +97,25 @@
         # Create server and add the security group created
         # above to the server we just created
         server_name = data_utils.rand_name('server')
-        resp, server = self.create_test_server(name=server_name)
+        server = self.create_test_server(name=server_name)
         server_id = server['id']
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-        resp, body = self.servers_client.add_security_group(server_id,
-                                                            sg['name'])
+        self.servers_client.add_security_group(server_id, sg['name'])
 
         # Check that we are not able to delete the security
         # group since it is in use by an active server
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.delete_security_group,
                           sg['id'])
 
         # Reboot and add the other security group
-        resp, body = self.servers_client.reboot(server_id, 'HARD')
+        self.servers_client.reboot(server_id, 'HARD')
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-        resp, body = self.servers_client.add_security_group(server_id,
-                                                            sg2['name'])
+        self.servers_client.add_security_group(server_id, sg2['name'])
 
         # Check that we are not able to delete the other security
         # group since it is in use by an active server
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.delete_security_group,
                           sg2['id'])
 
@@ -126,6 +128,7 @@
         self.client.delete_security_group(sg2['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7d4e1d3c-3209-4d6d-b020-986304ebad1f')
     @test.services('network')
     def test_update_security_groups(self):
         # Update security group name and description
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 ee9f78b..0127dc7 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -14,12 +14,12 @@
 #    under the License.
 
 from tempest_lib import decorators
+from tempest_lib import exceptions as lib_exc
 import testtools
 
 from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -28,9 +28,13 @@
 class SecurityGroupsNegativeTestJSON(base.BaseSecurityGroupsTest):
 
     @classmethod
+    def setup_clients(cls):
+        super(SecurityGroupsNegativeTestJSON, cls).setup_clients()
+        cls.client = cls.security_groups_client
+
+    @classmethod
     def resource_setup(cls):
         super(SecurityGroupsNegativeTestJSON, cls).resource_setup()
-        cls.client = cls.security_groups_client
         cls.neutron_available = CONF.service_available.neutron
 
     def _generate_a_non_existent_security_group_id(self):
@@ -48,55 +52,59 @@
         return non_exist_id
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('673eaec1-9b3e-48ed-bdf1-2786c1b9661c')
     @test.services('network')
     def test_security_group_get_nonexistent_group(self):
         # Negative test:Should not be able to GET the details
         # of non-existent Security Group
         non_exist_id = self._generate_a_non_existent_security_group_id()
-        self.assertRaises(exceptions.NotFound, self.client.get_security_group,
+        self.assertRaises(lib_exc.NotFound, self.client.get_security_group,
                           non_exist_id)
 
     @decorators.skip_because(bug="1161411",
                              condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('1759c3cb-b0fc-44b7-86ce-c99236be911d')
     @test.services('network')
     def test_security_group_create_with_invalid_group_name(self):
         # Negative test: Security Group should not be created with group name
         # as an empty string/with white spaces/chars more than 255
         s_description = data_utils.rand_name('description-')
         # Create Security Group with empty string as group name
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group, "", s_description)
         # Create Security Group with white space in group name
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group, " ",
                           s_description)
         # Create Security Group with group name longer than 255 chars
         s_name = 'securitygroup-'.ljust(260, '0')
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group, s_name,
                           s_description)
 
     @decorators.skip_because(bug="1161411",
                              condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('777b6f14-aca9-4758-9e84-38783cfa58bc')
     @test.services('network')
     def test_security_group_create_with_invalid_group_description(self):
         # Negative test:Security Group should not be created with description
         # as an empty string/with white spaces/chars more than 255
         s_name = data_utils.rand_name('securitygroup-')
         # Create Security Group with empty string as description
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group, s_name, "")
         # Create Security Group with white space in description
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group, s_name, " ")
         # Create Security Group with group description longer than 255 chars
         s_description = 'description-'.ljust(260, '0')
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group, s_name,
                           s_description)
 
+    @test.idempotent_id('9fdb4abc-6b66-4b27-b89c-eb215a956168')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron allows duplicate names for security groups")
     @test.attr(type=['negative', 'smoke'])
@@ -108,11 +116,12 @@
         s_description = data_utils.rand_name('description-')
         self.create_security_group(s_name, s_description)
         # Now try the Security Group with the same 'Name'
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_security_group, s_name,
                           s_description)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('36a1629f-c6da-4a26-b8b8-55e7e5d5cd58')
     @test.services('network')
     def test_delete_the_default_security_group(self):
         # Negative test:Deletion of the "default" Security Group should Fail
@@ -123,26 +132,29 @@
                 default_security_group_id = body[i]['id']
                 break
         # Deleting the "default" Security Group
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.delete_security_group,
                           default_security_group_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('6727c00b-214c-4f9e-9a52-017ac3e98411')
     @test.services('network')
     def test_delete_nonexistent_security_group(self):
         # Negative test:Deletion of a non-existent Security Group should fail
         non_exist_id = self._generate_a_non_existent_security_group_id()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_security_group, non_exist_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('1438f330-8fa4-4aeb-8a94-37c250106d7f')
     @test.services('network')
     def test_delete_security_group_without_passing_id(self):
         # Negative test:Deletion of a Security Group with out passing ID
         # should Fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_security_group, '')
 
+    @test.idempotent_id('00579617-fe04-4e1c-9d08-ca7467d2e34b')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_id")
     @test.attr(type=['negative', 'smoke'])
@@ -153,10 +165,11 @@
         s_description = data_utils.rand_name('description-')
         # Create a non int sg_id
         sg_id_invalid = data_utils.rand_name('sg-')
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_security_group, sg_id_invalid,
                           name=s_name, description=s_description)
 
+    @test.idempotent_id('cda8d8b4-59f8-4087-821d-20cf5a03b3b1')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_name")
     @test.attr(type=['negative', 'smoke'])
@@ -168,10 +181,11 @@
         securitygroup_id = securitygroup['id']
         # Update Security Group with group name longer than 255 chars
         s_new_name = 'securitygroup-'.ljust(260, '0')
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_security_group,
                           securitygroup_id, name=s_new_name)
 
+    @test.idempotent_id('97d12b1c-a610-4194-93f1-ba859e718b45')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_description")
     @test.attr(type=['negative', 'smoke'])
@@ -183,18 +197,19 @@
         securitygroup_id = securitygroup['id']
         # Update Security Group with group description longer than 255 chars
         s_new_des = 'des-'.ljust(260, '0')
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_security_group,
                           securitygroup_id, description=s_new_des)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('27edee9c-873d-4da6-a68a-3c256efebe8f')
     @test.services('network')
     def test_update_non_existent_security_group(self):
         # Update a non-existent Security Group should Fail
         non_exist_id = self._generate_a_non_existent_security_group_id()
         s_name = data_utils.rand_name('sg-')
         s_description = data_utils.rand_name('description-')
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.update_security_group,
                           non_exist_id, name=s_name,
                           description=s_description)
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 4b14dc4..0702f3f 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -26,14 +26,22 @@
 class AttachInterfacesTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
+        super(AttachInterfacesTestJSON, cls).skip_checks()
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron is required")
         if not CONF.compute_feature_enabled.interface_attach:
             raise cls.skipException("Interface attachment is not available.")
+
+    @classmethod
+    def setup_credentials(cls):
         # This test class requires network and subnet
         cls.set_network_resources(network=True, subnet=True)
-        super(AttachInterfacesTestJSON, cls).resource_setup()
+        super(AttachInterfacesTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def setup_clients(cls):
+        super(AttachInterfacesTestJSON, cls).setup_clients()
         cls.client = cls.os.interfaces_client
 
     def _check_interface(self, iface, port_id=None, network_id=None,
@@ -49,37 +57,33 @@
             self.assertEqual(iface['mac_addr'], mac_addr)
 
     def _create_server_get_interfaces(self):
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, ifs = self.client.list_interfaces(server['id'])
-        self.assertEqual(200, resp.status)
-        resp, body = self.client.wait_for_interface_status(
+        server = self.create_test_server(wait_until='ACTIVE')
+        ifs = self.client.list_interfaces(server['id'])
+        body = self.client.wait_for_interface_status(
             server['id'], ifs[0]['port_id'], 'ACTIVE')
         ifs[0]['port_state'] = body['port_state']
         return server, ifs
 
     def _test_create_interface(self, server):
-        resp, iface = self.client.create_interface(server['id'])
-        self.assertEqual(200, resp.status)
-        resp, iface = self.client.wait_for_interface_status(
+        iface = self.client.create_interface(server['id'])
+        iface = self.client.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
         self._check_interface(iface)
         return iface
 
     def _test_create_interface_by_network_id(self, server, ifs):
         network_id = ifs[0]['net_id']
-        resp, iface = self.client.create_interface(server['id'],
-                                                   network_id=network_id)
-        self.assertEqual(200, resp.status)
-        resp, iface = self.client.wait_for_interface_status(
+        iface = self.client.create_interface(server['id'],
+                                             network_id=network_id)
+        iface = self.client.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
         self._check_interface(iface, network_id=network_id)
         return iface
 
     def _test_show_interface(self, server, ifs):
         iface = ifs[0]
-        resp, _iface = self.client.show_interface(server['id'],
-                                                  iface['port_id'])
-        self.assertEqual(200, resp.status)
+        _iface = self.client.show_interface(server['id'],
+                                            iface['port_id'])
         self._check_interface(iface, port_id=_iface['port_id'],
                               network_id=_iface['net_id'],
                               fixed_ip=_iface['fixed_ips'][0]['ip_address'],
@@ -88,14 +92,13 @@
     def _test_delete_interface(self, server, ifs):
         # NOTE(danms): delete not the first or last, but one in the middle
         iface = ifs[1]
-        resp, _ = self.client.delete_interface(server['id'], iface['port_id'])
-        self.assertEqual(202, resp.status)
-        _ifs = self.client.list_interfaces(server['id'])[1]
+        self.client.delete_interface(server['id'], iface['port_id'])
+        _ifs = self.client.list_interfaces(server['id'])
         start = int(time.time())
 
         while len(ifs) == len(_ifs):
             time.sleep(self.build_interval)
-            _ifs = self.client.list_interfaces(server['id'])[1]
+            _ifs = self.client.list_interfaces(server['id'])
             timed_out = int(time.time()) - start >= self.build_timeout
             if len(ifs) == len(_ifs) and timed_out:
                 message = ('Failed to delete interface within '
@@ -114,6 +117,7 @@
         self.assertEqual(sorted(list1), sorted(list2))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
     @test.services('network')
     def test_create_list_show_delete_interfaces(self):
         server, ifs = self._create_server_get_interfaces()
@@ -127,7 +131,7 @@
         iface = self._test_create_interface_by_network_id(server, ifs)
         ifs.append(iface)
 
-        resp, _ifs = self.client.list_interfaces(server['id'])
+        _ifs = self.client.list_interfaces(server['id'])
         self._compare_iface_list(ifs, _ifs)
 
         self._test_show_interface(server, ifs)
@@ -136,6 +140,7 @@
         self.assertEqual(len(ifs) - 1, len(_ifs))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9')
     @test.services('network')
     def test_add_remove_fixed_ip(self):
         # Add and Remove the fixed IP to server.
@@ -144,11 +149,9 @@
         self.assertTrue(interface_count > 0)
         self._check_interface(ifs[0])
         network_id = ifs[0]['net_id']
-        resp, body = self.client.add_fixed_ip(server['id'],
-                                              network_id)
-        self.assertEqual(202, resp.status)
+        self.client.add_fixed_ip(server['id'], network_id)
         # Remove the fixed IP from server.
-        server_resp, server_detail = self.os.servers_client.get_server(
+        server_detail = self.os.servers_client.get_server(
             server['id'])
         # Get the Fixed IP from server.
         fixed_ip = None
@@ -159,6 +162,4 @@
                     break
             if fixed_ip is not None:
                 break
-        resp, body = self.client.remove_fixed_ip(server['id'],
-                                                 fixed_ip)
-        self.assertEqual(202, resp.status)
+        self.client.remove_fixed_ip(server['id'], fixed_ip)
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index 5ddf053..5962042 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -29,8 +29,8 @@
         cls.client = cls.availability_zone_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('a8333aa2-205c-449f-a828-d38c2489bf25')
     def test_get_availability_zone_list_with_non_admin_user(self):
         # List of availability zone with non-administrator user
-        resp, availability_zone = self.client.get_availability_zone_list()
-        self.assertEqual(200, resp.status)
+        availability_zone = self.client.get_availability_zone_list()
         self.assertTrue(len(availability_zone) > 0)
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 85eb049..14eb536 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -43,18 +43,19 @@
                        'contents': base64.b64encode(file_contents)}]
         cls.client = cls.servers_client
         cls.network_client = cls.os.network_client
-        cli_resp = cls.create_test_server(name=cls.name,
-                                          meta=cls.meta,
-                                          accessIPv4=cls.accessIPv4,
-                                          accessIPv6=cls.accessIPv6,
-                                          personality=personality,
-                                          disk_config=cls.disk_config)
-        cls.resp, cls.server_initial = cli_resp
+        disk_config = cls.disk_config
+        cls.server_initial = cls.create_test_server(name=cls.name,
+                                                    meta=cls.meta,
+                                                    accessIPv4=cls.accessIPv4,
+                                                    accessIPv6=cls.accessIPv6,
+                                                    personality=personality,
+                                                    disk_config=disk_config)
         cls.password = cls.server_initial['adminPass']
         cls.client.wait_for_server_status(cls.server_initial['id'], 'ACTIVE')
-        resp, cls.server = cls.client.get_server(cls.server_initial['id'])
+        cls.server = cls.client.get_server(cls.server_initial['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5de47127-9977-400a-936f-abcfbec1218f')
     def test_verify_server_details(self):
         # Verify the specified server attributes are set correctly
         self.assertEqual(self.accessIPv4, self.server['accessIPv4'])
@@ -68,21 +69,24 @@
         self.assertEqual(self.meta, self.server['metadata'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9a438d88-10c6-4bcd-8b5b-5b6e25e1346f')
     def test_list_servers(self):
         # The created server should be in the list of all servers
-        resp, body = self.client.list_servers()
+        body = self.client.list_servers()
         servers = body['servers']
         found = any([i for i in servers if i['id'] == self.server['id']])
         self.assertTrue(found)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
     def test_list_servers_with_detail(self):
         # The created server should be in the detailed list of all servers
-        resp, body = self.client.list_servers_with_detail()
+        body = self.client.list_servers_with_detail()
         servers = body['servers']
         found = any([i for i in servers if i['id'] == self.server['id']])
         self.assertTrue(found)
 
+    @test.idempotent_id('cbc0f52f-05aa-492b-bdc1-84b575ca294b')
     @testtools.skipUnless(CONF.compute.run_ssh,
                           'Instance validation tests are disabled.')
     @test.attr(type='gate')
@@ -94,6 +98,7 @@
                                                   self.password)
         self.assertEqual(flavor['vcpus'], linux_client.get_number_of_vcpus())
 
+    @test.idempotent_id('ac1ad47f-984b-4441-9274-c9079b7a0666')
     @testtools.skipUnless(CONF.compute.run_ssh,
                           'Instance validation tests are disabled.')
     @test.attr(type='gate')
@@ -104,26 +109,25 @@
         self.assertTrue(linux_client.hostname_equals_servername(self.name))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ed20d3fb-9d1f-4329-b160-543fbd5d9811')
     def test_create_server_with_scheduler_hint_group(self):
         # Create a server with the scheduler hint "group".
         name = data_utils.rand_name('server_group')
         policies = ['affinity']
-        resp, body = self.client.create_server_group(name=name,
-                                                     policies=policies)
-        self.assertEqual(200, resp.status)
+        body = self.client.create_server_group(name=name,
+                                               policies=policies)
         group_id = body['id']
         self.addCleanup(self.client.delete_server_group, group_id)
 
         hints = {'group': group_id}
-        resp, server = self.create_test_server(sched_hints=hints,
-                                               wait_until='ACTIVE')
-        self.assertEqual(202, resp.status)
+        server = self.create_test_server(sched_hints=hints,
+                                         wait_until='ACTIVE')
 
         # Check a server is in the group
-        resp, server_group = self.client.get_server_group(group_id)
-        self.assertEqual(200, resp.status)
+        server_group = self.client.get_server_group(group_id)
         self.assertIn(server['id'], server_group['members'])
 
+    @test.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2')
     @testtools.skipUnless(CONF.service_available.neutron,
                           'Neutron service must be available.')
     def test_verify_multiple_nics_order(self):
@@ -156,7 +160,7 @@
         networks = [{'uuid': net1['network']['id']},
                     {'uuid': net2['network']['id']}]
 
-        _, server_multi_nics = self.create_test_server(
+        server_multi_nics = self.create_test_server(
             networks=networks, wait_until='ACTIVE')
 
         # Cleanup server; this is needed in the test case because with the LIFO
@@ -171,7 +175,7 @@
 
         self.addCleanup(cleanup_server)
 
-        _, addresses = self.client.list_addresses(server_multi_nics['id'])
+        addresses = self.client.list_addresses(server_multi_nics['id'])
 
         # We can't predict the ip addresses assigned to the server on networks.
         # Sometimes the assigned addresses are ['19.80.0.2', '19.86.0.2'], at
@@ -196,6 +200,7 @@
         cls.flavor_client = cls.os_adm.flavors_client
         cls.client = cls.servers_client
 
+    @test.idempotent_id('b3c7bcfc-bb5b-4e22-b517-c7f686b802ca')
     @testtools.skipUnless(CONF.compute.run_ssh,
                           'Instance validation tests are disabled.')
     @test.attr(type='gate')
@@ -245,22 +250,22 @@
 
         admin_pass = self.image_ssh_password
 
-        resp, server_no_eph_disk = (self.create_test_server(
-                                    wait_until='ACTIVE',
-                                    adminPass=admin_pass,
-                                    flavor=flavor_no_eph_disk_id))
-        resp, server_with_eph_disk = (self.create_test_server(
-                                      wait_until='ACTIVE',
-                                      adminPass=admin_pass,
-                                      flavor=flavor_with_eph_disk_id))
+        server_no_eph_disk = (self.create_test_server(
+                              wait_until='ACTIVE',
+                              adminPass=admin_pass,
+                              flavor=flavor_no_eph_disk_id))
+        server_with_eph_disk = (self.create_test_server(
+                                wait_until='ACTIVE',
+                                adminPass=admin_pass,
+                                flavor=flavor_with_eph_disk_id))
         # Get partition number of server without extra specs.
-        _, server_no_eph_disk = self.client.get_server(
+        server_no_eph_disk = self.client.get_server(
             server_no_eph_disk['id'])
         linux_client = remote_client.RemoteClient(server_no_eph_disk,
                                                   self.ssh_user, admin_pass)
         partition_num = len(linux_client.get_partitions().split('\n'))
 
-        _, server_with_eph_disk = self.client.get_server(
+        server_with_eph_disk = self.client.get_server(
             server_with_eph_disk['id'])
         linux_client = remote_client.RemoteClient(server_with_eph_disk,
                                                   self.ssh_user, admin_pass)
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index 9d1ea9e..8842899 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -33,63 +33,63 @@
         cls.client = cls.servers_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('9e6e0c87-3352-42f7-9faf-5d6210dbd159')
     def test_delete_server_while_in_building_state(self):
         # Delete a server while it's VM state is Building
-        resp, server = self.create_test_server(wait_until='BUILD')
-        resp, _ = self.client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        server = self.create_test_server(wait_until='BUILD')
+        self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('925fdfb4-5b13-47ea-ac8a-c36ae6fddb05')
     def test_delete_active_server(self):
         # Delete a server while it's VM state is Active
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, _ = self.client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        server = self.create_test_server(wait_until='ACTIVE')
+        self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('546d368c-bb6c-4645-979a-83ed16f3a6be')
     def test_delete_server_while_in_shutoff_state(self):
         # Delete a server while it's VM state is Shutoff
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, body = self.client.stop(server['id'])
+        server = self.create_test_server(wait_until='ACTIVE')
+        self.client.stop(server['id'])
         self.client.wait_for_server_status(server['id'], 'SHUTOFF')
-        resp, _ = self.client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('943bd6e8-4d7a-4904-be83-7a6cc2d4213b')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type='gate')
     def test_delete_server_while_in_pause_state(self):
         # Delete a server while it's VM state is Pause
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, body = self.client.pause_server(server['id'])
+        server = self.create_test_server(wait_until='ACTIVE')
+        self.client.pause_server(server['id'])
         self.client.wait_for_server_status(server['id'], 'PAUSED')
-        resp, _ = self.client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('1f82ebd3-8253-4f4e-b93f-de9b7df56d8b')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type='gate')
     def test_delete_server_while_in_suspended_state(self):
         # Delete a server while it's VM state is Suspended
-        _, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
         self.client.suspend_server(server['id'])
         self.client.wait_for_server_status(server['id'], 'SUSPENDED')
-        resp, _ = self.client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('bb0cb402-09dd-4947-b6e5-5e7e1cfa61ad')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type='gate')
     def test_delete_server_while_in_shelved_state(self):
         # Delete a server while it's VM state is Shelved
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, body = self.client.shelve_server(server['id'])
-        self.assertEqual(202, resp.status)
+        server = self.create_test_server(wait_until='ACTIVE')
+        self.client.shelve_server(server['id'])
 
         offload_time = CONF.compute.shelved_offload_time
         if offload_time >= 0:
@@ -99,41 +99,39 @@
         else:
             self.client.wait_for_server_status(server['id'],
                                                'SHELVED')
-        resp, _ = self.client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('ab0c38b4-cdd8-49d3-9b92-0cb898723c01')
     @testtools.skipIf(not CONF.compute_feature_enabled.resize,
                       'Resize not available.')
     @test.attr(type='gate')
     def test_delete_server_while_in_verify_resize_state(self):
         # Delete a server while it's VM state is VERIFY_RESIZE
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, body = self.client.resize(server['id'], self.flavor_ref_alt)
-        self.assertEqual(202, resp.status)
+        server = self.create_test_server(wait_until='ACTIVE')
+        self.client.resize(server['id'], self.flavor_ref_alt)
         self.client.wait_for_server_status(server['id'], 'VERIFY_RESIZE')
-        resp, _ = self.client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('d0f3f0d6-d9b6-4a32-8da4-23015dcab23c')
     @test.services('volume')
     @test.attr(type='gate')
     def test_delete_server_while_in_attached_volume(self):
         # Delete a server while a volume is attached to it
         volumes_client = self.volumes_extensions_client
         device = '/dev/%s' % CONF.compute.volume_device_name
-        resp, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
 
-        resp, volume = volumes_client.create_volume(1)
+        volume = volumes_client.create_volume(1)
         self.addCleanup(volumes_client.delete_volume, volume['id'])
         volumes_client.wait_for_volume_status(volume['id'], 'available')
-        resp, body = self.client.attach_volume(server['id'],
-                                               volume['id'],
-                                               device=device)
+        self.client.attach_volume(server['id'],
+                                  volume['id'],
+                                  device=device)
         volumes_client.wait_for_volume_status(volume['id'], 'in-use')
 
-        resp, _ = self.client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
         volumes_client.wait_for_volume_status(volume['id'], 'available')
 
@@ -149,23 +147,22 @@
         cls.admin_client = cls.os_adm.servers_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('99774678-e072-49d1-9d2a-49a59bc56063')
     def test_delete_server_while_in_error_state(self):
         # Delete a server while it's VM state is error
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, body = self.admin_client.reset_state(server['id'], state='error')
-        self.assertEqual(202, resp.status)
+        server = self.create_test_server(wait_until='ACTIVE')
+        self.admin_client.reset_state(server['id'], state='error')
         # Verify server's state
-        resp, server = self.non_admin_client.get_server(server['id'])
+        server = self.non_admin_client.get_server(server['id'])
         self.assertEqual(server['status'], 'ERROR')
-        resp, _ = self.non_admin_client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        self.non_admin_client.delete_server(server['id'])
         self.servers_client.wait_for_server_termination(server['id'],
                                                         ignore_error=True)
 
     @test.attr(type='gate')
+    @test.idempotent_id('73177903-6737-4f27-a60c-379e8ae8cf48')
     def test_admin_delete_servers_of_others(self):
         # Administrator can delete servers of others
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-        resp, _ = self.admin_client.delete_server(server['id'])
-        self.assertEqual('204', resp['status'])
+        server = self.create_test_server(wait_until='ACTIVE')
+        self.admin_client.delete_server(server['id'])
         self.servers_client.wait_for_server_termination(server['id'])
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index eeef0e5..a15a9b7 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -31,59 +31,61 @@
             raise cls.skipException(msg)
         super(ServerDiskConfigTestJSON, cls).resource_setup()
         cls.client = cls.os.servers_client
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
 
     def _update_server_with_disk_config(self, disk_config):
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         if disk_config != server['OS-DCF:diskConfig']:
-            resp, server = self.client.update_server(self.server_id,
-                                                     disk_config=disk_config)
-            self.assertEqual(200, resp.status)
+            server = self.client.update_server(self.server_id,
+                                               disk_config=disk_config)
             self.client.wait_for_server_status(server['id'], 'ACTIVE')
-            resp, server = self.client.get_server(server['id'])
+            server = self.client.get_server(server['id'])
             self.assertEqual(disk_config, server['OS-DCF:diskConfig'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('bef56b09-2e8c-4883-a370-4950812f430e')
     def test_rebuild_server_with_manual_disk_config(self):
         # A server should be rebuilt using the manual disk config option
         self._update_server_with_disk_config(disk_config='AUTO')
 
-        resp, server = self.client.rebuild(self.server_id,
-                                           self.image_ref_alt,
-                                           disk_config='MANUAL')
+        server = self.client.rebuild(self.server_id,
+                                     self.image_ref_alt,
+                                     disk_config='MANUAL')
 
         # Wait for the server to become active
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
 
         # Verify the specified attributes are set correctly
-        resp, server = self.client.get_server(server['id'])
+        server = self.client.get_server(server['id'])
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('9c9fae77-4feb-402f-8450-bf1c8b609713')
     def test_rebuild_server_with_auto_disk_config(self):
         # A server should be rebuilt using the auto disk config option
         self._update_server_with_disk_config(disk_config='MANUAL')
 
-        resp, server = self.client.rebuild(self.server_id,
-                                           self.image_ref_alt,
-                                           disk_config='AUTO')
+        server = self.client.rebuild(self.server_id,
+                                     self.image_ref_alt,
+                                     disk_config='AUTO')
 
         # Wait for the server to become active
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
 
         # Verify the specified attributes are set correctly
-        resp, server = self.client.get_server(server['id'])
+        server = self.client.get_server(server['id'])
         self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
 
     def _get_alternative_flavor(self):
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
 
         if server['flavor']['id'] == self.flavor_ref:
             return self.flavor_ref_alt
         else:
             return self.flavor_ref
 
+    @test.idempotent_id('414e7e93-45b5-44bc-8e03-55159c6bfc97')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='gate')
@@ -98,9 +100,10 @@
         self.client.confirm_resize(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
 
+    @test.idempotent_id('693d16f3-556c-489a-8bac-3d0ca2490bad')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='gate')
@@ -115,20 +118,20 @@
         self.client.confirm_resize(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('5ef18867-358d-4de9-b3c9-94d4ba35742f')
     def test_update_server_from_auto_to_manual(self):
         # A server should be updated from auto to manual disk config
         self._update_server_with_disk_config(disk_config='AUTO')
 
         # Update the disk_config attribute to manual
-        resp, server = self.client.update_server(self.server_id,
-                                                 disk_config='MANUAL')
-        self.assertEqual(200, resp.status)
+        server = self.client.update_server(self.server_id,
+                                           disk_config='MANUAL')
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
 
         # Verify the disk_config attribute is set correctly
-        resp, server = self.client.get_server(server['id'])
+        server = self.client.get_server(server['id'])
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index 80b2a69..b00221c 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -23,27 +23,27 @@
     def resource_setup(cls):
         super(InstanceActionsTestJSON, cls).resource_setup()
         cls.client = cls.servers_client
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
-        cls.request_id = resp['x-compute-request-id']
+        server = cls.create_test_server(wait_until='ACTIVE')
+        cls.request_id = server.response['x-compute-request-id']
         cls.server_id = server['id']
 
     @test.attr(type='gate')
+    @test.idempotent_id('77ca5cc5-9990-45e0-ab98-1de8fead201a')
     def test_list_instance_actions(self):
         # List actions of the provided server
-        resp, body = self.client.reboot(self.server_id, 'HARD')
+        self.client.reboot(self.server_id, 'HARD')
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
-        resp, body = self.client.list_instance_actions(self.server_id)
-        self.assertEqual(200, resp.status)
+        body = self.client.list_instance_actions(self.server_id)
         self.assertTrue(len(body) == 2, str(body))
         self.assertTrue(any([i for i in body if i['action'] == 'create']))
         self.assertTrue(any([i for i in body if i['action'] == 'reboot']))
 
     @test.attr(type='gate')
+    @test.idempotent_id('aacc71ca-1d70-4aa5-bbf6-0ff71470e43c')
     def test_get_instance_action(self):
         # Get the action details of the provided server
-        resp, body = self.client.get_instance_action(self.server_id,
-                                                     self.request_id)
-        self.assertEqual(200, resp.status)
+        body = self.client.get_instance_action(self.server_id,
+                                               self.request_id)
         self.assertEqual(self.server_id, body['instance_uuid'])
         self.assertEqual('create', body['action'])
diff --git a/tempest/api/compute/servers/test_instance_actions_negative.py b/tempest/api/compute/servers/test_instance_actions_negative.py
index e92f04c..a0064b2 100644
--- a/tempest/api/compute/servers/test_instance_actions_negative.py
+++ b/tempest/api/compute/servers/test_instance_actions_negative.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -25,19 +26,21 @@
     def resource_setup(cls):
         super(InstanceActionsNegativeTestJSON, cls).resource_setup()
         cls.client = cls.servers_client
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('67e1fce6-7ec2-45c6-92d4-0a8f1a632910')
     def test_list_instance_actions_non_existent_server(self):
         # List actions of the non-existent server id
         non_existent_server_id = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.list_instance_actions,
                           non_existent_server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0269f40a-6f18-456c-b336-c03623c897f1')
     def test_get_instance_action_invalid_request(self):
         # Get the action details of the provided server with invalid request
-        self.assertRaises(exceptions.NotFound, self.client.get_instance_action,
+        self.assertRaises(lib_exc.NotFound, self.client.get_instance_action,
                           self.server_id, '999')
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 375f441..bfba105 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -14,12 +14,12 @@
 #    under the License.
 
 from tempest_lib import decorators
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.compute import base
 from tempest.api import utils
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -28,11 +28,19 @@
 class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def setup_credentials(cls):
         cls.set_network_resources(network=True, subnet=True, dhcp=True)
-        super(ListServerFiltersTestJSON, cls).resource_setup()
+        super(ListServerFiltersTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def setup_clients(cls):
+        super(ListServerFiltersTestJSON, cls).setup_clients()
         cls.client = cls.servers_client
 
+    @classmethod
+    def resource_setup(cls):
+        super(ListServerFiltersTestJSON, cls).resource_setup()
+
         # Check to see if the alternate image ref actually exists...
         images_client = cls.images_client
         images = images_client.list_images()
@@ -48,29 +56,29 @@
         # not exist, fail early since the tests won't work...
         try:
             cls.images_client.get_image(cls.image_ref)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             raise RuntimeError("Image %s (image_ref) was not found!" %
                                cls.image_ref)
 
         try:
             cls.images_client.get_image(cls.image_ref_alt)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             raise RuntimeError("Image %s (image_ref_alt) was not found!" %
                                cls.image_ref_alt)
 
         cls.s1_name = data_utils.rand_name(cls.__name__ + '-instance')
-        resp, cls.s1 = cls.create_test_server(name=cls.s1_name,
-                                              wait_until='ACTIVE')
+        cls.s1 = cls.create_test_server(name=cls.s1_name,
+                                        wait_until='ACTIVE')
 
         cls.s2_name = data_utils.rand_name(cls.__name__ + '-instance')
-        resp, cls.s2 = cls.create_test_server(name=cls.s2_name,
-                                              image_id=cls.image_ref_alt,
-                                              wait_until='ACTIVE')
+        cls.s2 = cls.create_test_server(name=cls.s2_name,
+                                        image_id=cls.image_ref_alt,
+                                        wait_until='ACTIVE')
 
         cls.s3_name = data_utils.rand_name(cls.__name__ + '-instance')
-        resp, cls.s3 = cls.create_test_server(name=cls.s3_name,
-                                              flavor=cls.flavor_ref_alt,
-                                              wait_until='ACTIVE')
+        cls.s3 = cls.create_test_server(name=cls.s3_name,
+                                        flavor=cls.flavor_ref_alt,
+                                        wait_until='ACTIVE')
 
         cls.fixed_network_name = CONF.compute.fixed_network_name
         if CONF.service_available.neutron:
@@ -78,12 +86,13 @@
                 network = cls.isolated_creds.get_primary_network()
                 cls.fixed_network_name = network['name']
 
+    @test.idempotent_id('05e8a8e7-9659-459a-989d-92c2f501f4ba')
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @test.attr(type='gate')
     def test_list_servers_filter_by_image(self):
         # Filter the list of servers by image
         params = {'image': self.image_ref}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -91,10 +100,11 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('573637f5-7325-47bb-9144-3476d0416908')
     def test_list_servers_filter_by_flavor(self):
         # Filter the list of servers by flavor
         params = {'flavor': self.flavor_ref_alt}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertNotIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -102,10 +112,11 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('9b067a7b-7fee-4f6a-b29c-be43fe18fc5a')
     def test_list_servers_filter_by_server_name(self):
         # Filter the list of servers by server name
         params = {'name': self.s1_name}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -113,10 +124,11 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e')
     def test_list_servers_filter_by_server_status(self):
         # Filter the list of servers by server status
         params = {'status': 'active'}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -124,13 +136,14 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('451dbbb2-f330-4a9f-b0e1-5f5d2cb0f34c')
     def test_list_servers_filter_by_shutoff_status(self):
         # Filter the list of servers by server shutoff status
         params = {'status': 'shutoff'}
         self.client.stop(self.s1['id'])
         self.client.wait_for_server_status(self.s1['id'],
                                            'SHUTOFF')
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         self.client.start(self.s1['id'])
         self.client.wait_for_server_status(self.s1['id'],
                                            'ACTIVE')
@@ -141,28 +154,32 @@
         self.assertNotIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('614cdfc1-d557-4bac-915b-3e67b48eee76')
     def test_list_servers_filter_by_limit(self):
         # Verify only the expected number of servers are returned
         params = {'limit': 1}
-        resp, servers = self.client.list_servers(params)
+        servers = self.client.list_servers(params)
         self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('b1495414-2d93-414c-8019-849afe8d319e')
     def test_list_servers_filter_by_zero_limit(self):
         # Verify only the expected number of servers are returned
         params = {'limit': 0}
-        resp, servers = self.client.list_servers(params)
+        servers = self.client.list_servers(params)
         self.assertEqual(0, len(servers['servers']))
 
     @test.attr(type='gate')
+    @test.idempotent_id('37791bbd-90c0-4de0-831e-5f38cba9c6b3')
     def test_list_servers_filter_by_exceed_limit(self):
         # Verify only the expected number of servers are returned
         params = {'limit': 100000}
-        resp, servers = self.client.list_servers(params)
-        resp, all_servers = self.client.list_servers()
+        servers = self.client.list_servers(params)
+        all_servers = self.client.list_servers()
         self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
                          len([x for x in servers['servers'] if 'id' in x]))
 
+    @test.idempotent_id('b3304c3b-97df-46d2-8cd3-e2b6659724e7')
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @test.attr(type='gate')
     def test_list_servers_detailed_filter_by_image(self):
@@ -176,10 +193,11 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('80c574cc-0925-44ba-8602-299028357dd9')
     def test_list_servers_detailed_filter_by_flavor(self):
         # Filter the detailed list of servers by flavor
         params = {'flavor': self.flavor_ref_alt}
-        resp, body = self.client.list_servers_with_detail(params)
+        body = self.client.list_servers_with_detail(params)
         servers = body['servers']
 
         self.assertNotIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -187,10 +205,11 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('f9eb2b70-735f-416c-b260-9914ac6181e4')
     def test_list_servers_detailed_filter_by_server_name(self):
         # Filter the detailed list of servers by server name
         params = {'name': self.s1_name}
-        resp, body = self.client.list_servers_with_detail(params)
+        body = self.client.list_servers_with_detail(params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -198,10 +217,11 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('de2612ab-b7dd-4044-b0b1-d2539601911f')
     def test_list_servers_detailed_filter_by_server_status(self):
         # Filter the detailed list of servers by server status
         params = {'status': 'active'}
-        resp, body = self.client.list_servers_with_detail(params)
+        body = self.client.list_servers_with_detail(params)
         servers = body['servers']
         test_ids = [s['id'] for s in (self.s1, self.s2, self.s3)]
 
@@ -212,10 +232,11 @@
                                           if x['id'] in test_ids])
 
     @test.attr(type='gate')
+    @test.idempotent_id('e9f624ee-92af-4562-8bec-437945a18dcb')
     def test_list_servers_filtered_by_name_wildcard(self):
         # List all servers that contains '-instance' in name
         params = {'name': '-instance'}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -226,7 +247,7 @@
         part_name = self.s1_name[6:-1]
 
         params = {'name': part_name}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -234,12 +255,13 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('24a89b0c-0d55-4a28-847f-45075f19b27b')
     def test_list_servers_filtered_by_name_regex(self):
         # list of regex that should match s1, s2 and s3
         regexes = ['^.*\-instance\-[0-9]+$', '^.*\-instance\-.*$']
         for regex in regexes:
             params = {'name': regex}
-            resp, body = self.client.list_servers(params)
+            body = self.client.list_servers(params)
             servers = body['servers']
 
             self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -250,7 +272,7 @@
         part_name = self.s1_name[-10:]
 
         params = {'name': part_name}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -258,13 +280,14 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('43a1242e-7b31-48d1-88f2-3f72aa9f2077')
     def test_list_servers_filtered_by_ip(self):
         # Filter servers by ip
         # Here should be listed 1 server
-        resp, self.s1 = self.client.get_server(self.s1['id'])
+        self.s1 = self.client.get_server(self.s1['id'])
         ip = self.s1['addresses'][self.fixed_network_name][0]['addr']
         params = {'ip': ip}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -274,14 +297,15 @@
     @decorators.skip_because(bug="1182883",
                              condition=CONF.service_available.neutron)
     @test.attr(type='gate')
+    @test.idempotent_id('a905e287-c35e-42f2-b132-d02b09f3654a')
     def test_list_servers_filtered_by_ip_regex(self):
         # Filter servers by regex ip
         # List all servers filtered by part of ip address.
         # Here should be listed all servers
-        resp, self.s1 = self.client.get_server(self.s1['id'])
+        self.s1 = self.client.get_server(self.s1['id'])
         ip = self.s1['addresses'][self.fixed_network_name][0]['addr'][0:-3]
         params = {'ip': ip}
-        resp, body = self.client.list_servers(params)
+        body = self.client.list_servers(params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -289,8 +313,9 @@
         self.assertIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('67aec2d0-35fe-4503-9f92-f13272b867ed')
     def test_list_servers_detailed_limit_results(self):
         # Verify only the expected number of detailed results are returned
         params = {'limit': 1}
-        resp, servers = self.client.list_servers_with_detail(params)
+        servers = self.client.list_servers_with_detail(params)
         self.assertEqual(1, len(servers['servers']))
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index fd66d2b..7837ac1 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -14,9 +14,9 @@
 #    under the License.
 
 from six import moves
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -35,10 +35,10 @@
         cls.existing_fixtures = []
         cls.deleted_fixtures = []
         for x in moves.xrange(2):
-            resp, srv = cls.create_test_server(wait_until='ACTIVE')
+            srv = cls.create_test_server(wait_until='ACTIVE')
             cls.existing_fixtures.append(srv)
 
-        resp, srv = cls.create_test_server()
+        srv = cls.create_test_server()
         cls.client.delete_server(srv['id'])
         # We ignore errors on termination because the server may
         # be put into ERROR status on a quick spawn, then delete,
@@ -49,101 +49,103 @@
         cls.deleted_fixtures.append(srv)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f')
     def test_list_servers_with_a_deleted_server(self):
         # Verify deleted servers do not show by default in list servers
         # List servers and verify server not returned
-        resp, body = self.client.list_servers()
+        body = self.client.list_servers()
         servers = body['servers']
         deleted_ids = [s['id'] for s in self.deleted_fixtures]
         actual = [srv for srv in servers
                   if srv['id'] in deleted_ids]
-        self.assertEqual('200', resp['status'])
         self.assertEqual([], actual)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ff01387d-c7ad-47b4-ae9e-64fa214638fe')
     def test_list_servers_by_non_existing_image(self):
         # Listing servers for a non existing image returns empty list
         non_existing_image = '1234abcd-zzz0-aaa9-ppp3-0987654abcde'
-        resp, body = self.client.list_servers(dict(image=non_existing_image))
+        body = self.client.list_servers(dict(image=non_existing_image))
         servers = body['servers']
-        self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5913660b-223b-44d4-a651-a0fbfd44ca75')
     def test_list_servers_by_non_existing_flavor(self):
         # Listing servers by non existing flavor returns empty list
         non_existing_flavor = 1234
-        resp, body = self.client.list_servers(dict(flavor=non_existing_flavor))
+        body = self.client.list_servers(dict(flavor=non_existing_flavor))
         servers = body['servers']
-        self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e2c77c4a-000a-4af3-a0bd-629a328bde7c')
     def test_list_servers_by_non_existing_server_name(self):
         # Listing servers for a non existent server name returns empty list
         non_existing_name = 'junk_server_1234'
-        resp, body = self.client.list_servers(dict(name=non_existing_name))
+        body = self.client.list_servers(dict(name=non_existing_name))
         servers = body['servers']
-        self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fcdf192d-0f74-4d89-911f-1ec002b822c4')
     def test_list_servers_status_non_existing(self):
         # Return an empty list when invalid status is specified
         non_existing_status = 'BALONEY'
-        resp, body = self.client.list_servers(dict(status=non_existing_status))
+        body = self.client.list_servers(dict(status=non_existing_status))
         servers = body['servers']
-        self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('12c80a9f-2dec-480e-882b-98ba15757659')
     def test_list_servers_by_limits(self):
         # List servers by specifying limits
-        resp, body = self.client.list_servers({'limit': 1})
-        self.assertEqual('200', resp['status'])
-        # when _interface='xml', one element for servers_links in servers
+        body = self.client.list_servers({'limit': 1})
         self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d47c17fb-eebd-4287-8e95-f20a7e627b18')
     def test_list_servers_by_limits_greater_than_actual_count(self):
         # List servers by specifying a greater value for limit
-        resp, body = self.client.list_servers({'limit': 100})
-        self.assertEqual('200', resp['status'])
+        body = self.client.list_servers({'limit': 100})
         self.assertEqual(len(self.existing_fixtures), len(body['servers']))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('679bc053-5e70-4514-9800-3dfab1a380a6')
     def test_list_servers_by_limits_pass_string(self):
         # Return an error if a string value is passed for limit
-        self.assertRaises(exceptions.BadRequest, self.client.list_servers,
+        self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
                           {'limit': 'testing'})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('62610dd9-4713-4ee0-8beb-fd2c1aa7f950')
     def test_list_servers_by_limits_pass_negative_value(self):
         # Return an error if a negative value for limit is passed
-        self.assertRaises(exceptions.BadRequest, self.client.list_servers,
+        self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
                           {'limit': -1})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('87d12517-e20a-4c9c-97b6-dd1628d6d6c9')
     def test_list_servers_by_changes_since_invalid_date(self):
         # Return an error when invalid date format is passed
-        self.assertRaises(exceptions.BadRequest, self.client.list_servers,
+        self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
                           {'changes-since': '2011/01/01'})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('74745ad8-b346-45b5-b9b8-509d7447fc1f')
     def test_list_servers_by_changes_since_future_date(self):
         # Return an empty list when a date in the future is passed
         changes_since = {'changes-since': '2051-01-01T12:34:00Z'}
-        resp, body = self.client.list_servers(changes_since)
-        self.assertEqual('200', resp['status'])
+        body = self.client.list_servers(changes_since)
         self.assertEqual(0, len(body['servers']))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('93055106-2d34-46fe-af68-d9ddbf7ee570')
     def test_list_servers_detail_server_is_deleted(self):
         # Server details are not listed for a deleted server
         deleted_ids = [s['id'] for s in self.deleted_fixtures]
-        resp, body = self.client.list_servers_with_detail()
+        body = self.client.list_servers_with_detail()
         servers = body['servers']
         actual = [srv for srv in servers
                   if srv['id'] in deleted_ids]
-        self.assertEqual('200', resp['status'])
         self.assertEqual([], actual)
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index 6fd2a75..69c056e 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -30,26 +30,26 @@
         created servers into the servers list to be cleaned up after all.
         """
         kwargs['name'] = kwargs.get('name', self._generate_name())
-        resp, body = self.create_test_server(**kwargs)
+        body = self.create_test_server(**kwargs)
 
-        return resp, body
+        return body
 
     @test.attr(type='gate')
+    @test.idempotent_id('61e03386-89c3-449c-9bb1-a06f423fd9d1')
     def test_multiple_create(self):
-        resp, body = self._create_multiple_servers(wait_until='ACTIVE',
-                                                   min_count=1,
-                                                   max_count=2)
+        body = self._create_multiple_servers(wait_until='ACTIVE',
+                                             min_count=1,
+                                             max_count=2)
         # NOTE(maurosr): do status response check and also make sure that
         # reservation_id is not in the response body when the request send
         # contains return_reservation_id=False
-        self.assertEqual('202', resp['status'])
         self.assertNotIn('reservation_id', body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('864777fb-2f1e-44e3-b5b9-3eb6fa84f2f7')
     def test_multiple_create_with_reservation_return(self):
-        resp, body = self._create_multiple_servers(wait_until='ACTIVE',
-                                                   min_count=1,
-                                                   max_count=2,
-                                                   return_reservation_id=True)
-        self.assertEqual(resp['status'], '202')
+        body = self._create_multiple_servers(wait_until='ACTIVE',
+                                             min_count=1,
+                                             max_count=2,
+                                             return_reservation_id=True)
         self.assertIn('reservation_id', body)
diff --git a/tempest/api/compute/servers/test_multiple_create_negative.py b/tempest/api/compute/servers/test_multiple_create_negative.py
index 55db605..caf1ae5 100644
--- a/tempest/api/compute/servers/test_multiple_create_negative.py
+++ b/tempest/api/compute/servers/test_multiple_create_negative.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -31,38 +32,43 @@
         created servers into the servers list to be cleaned up after all.
         """
         kwargs['name'] = kwargs.get('name', self._generate_name())
-        resp, body = self.create_test_server(**kwargs)
+        body = self.create_test_server(**kwargs)
 
-        return resp, body
+        return body
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('daf29d8d-e928-4a01-9a8c-b129603f3fc0')
     def test_min_count_less_than_one(self):
         invalid_min_count = 0
-        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+        self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           min_count=invalid_min_count)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('999aa722-d624-4423-b813-0d1ac9884d7a')
     def test_min_count_non_integer(self):
         invalid_min_count = 2.5
-        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+        self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           min_count=invalid_min_count)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a6f9c2ab-e060-4b82-b23c-4532cb9390ff')
     def test_max_count_less_than_one(self):
         invalid_max_count = 0
-        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+        self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           max_count=invalid_max_count)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c5698d1-d7af-4c80-b971-9d403135eea2')
     def test_max_count_non_integer(self):
         invalid_max_count = 2.5
-        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+        self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           max_count=invalid_max_count)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('476da616-f1ef-4271-a9b1-b9fc87727cdf')
     def test_max_count_less_than_min_count(self):
         min_count = 3
         max_count = 2
-        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+        self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           min_count=min_count,
                           max_count=max_count)
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 9edaede..ce3772f 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -18,13 +18,13 @@
 import urlparse
 
 from tempest_lib import decorators
+from tempest_lib import exceptions as lib_exc
 import testtools
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux import remote_client
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -47,7 +47,7 @@
             self.__class__.server_id = self.rebuild_server(self.server_id)
 
     def tearDown(self):
-        _, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         self.assertEqual(self.image_ref, server['image']['id'])
         self.server_check_teardown()
         super(ServerActionsTestJSON, self).tearDown()
@@ -59,19 +59,19 @@
         cls.client = cls.servers_client
         cls.server_id = cls.rebuild_server(None)
 
+    @test.idempotent_id('6158df09-4b82-4ab3-af6d-29cf36af858d')
     @testtools.skipUnless(CONF.compute_feature_enabled.change_password,
                           'Change password not available.')
     @test.attr(type='gate')
     def test_change_server_password(self):
         # The server's password should be set to the provided password
         new_password = 'Newpass1234'
-        resp, body = self.client.change_password(self.server_id, new_password)
-        self.assertEqual(202, resp.status)
+        self.client.change_password(self.server_id, new_password)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
         if self.run_ssh:
             # Verify that the user can authenticate with the new password
-            resp, server = self.client.get_server(self.server_id)
+            server = self.client.get_server(self.server_id)
             linux_client = remote_client.RemoteClient(server, self.ssh_user,
                                                       new_password)
             linux_client.validate_authentication()
@@ -79,13 +79,12 @@
     def _test_reboot_server(self, reboot_type):
         if self.run_ssh:
             # Get the time the server was last rebooted,
-            resp, server = self.client.get_server(self.server_id)
+            server = self.client.get_server(self.server_id)
             linux_client = remote_client.RemoteClient(server, self.ssh_user,
                                                       self.password)
             boot_time = linux_client.get_boot_time()
 
-        resp, body = self.client.reboot(self.server_id, reboot_type)
-        self.assertEqual(202, resp.status)
+        self.client.reboot(self.server_id, reboot_type)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
         if self.run_ssh:
@@ -97,17 +96,20 @@
                             '%s > %s' % (new_boot_time, boot_time))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32')
     def test_reboot_server_hard(self):
         # The server should be power cycled
         self._test_reboot_server('HARD')
 
     @decorators.skip_because(bug="1014647")
     @test.attr(type='smoke')
+    @test.idempotent_id('4640e3ef-a5df-482e-95a1-ceeeb0faa84d')
     def test_reboot_server_soft(self):
         # The server should be signaled to reboot gracefully
         self._test_reboot_server('SOFT')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aaa6cdf3-55a7-461a-add9-1c8596b9a07c')
     def test_rebuild_server(self):
         # The server should be rebuilt using the provided image and data
         meta = {'rebuild': 'server'}
@@ -116,12 +118,12 @@
         personality = [{'path': 'rebuild.txt',
                        'contents': base64.b64encode(file_contents)}]
         password = 'rebuildPassw0rd'
-        resp, rebuilt_server = self.client.rebuild(self.server_id,
-                                                   self.image_ref_alt,
-                                                   name=new_name,
-                                                   metadata=meta,
-                                                   personality=personality,
-                                                   adminPass=password)
+        rebuilt_server = self.client.rebuild(self.server_id,
+                                             self.image_ref_alt,
+                                             name=new_name,
+                                             metadata=meta,
+                                             personality=personality,
+                                             adminPass=password)
 
         # Verify the properties in the initial response are correct
         self.assertEqual(self.server_id, rebuilt_server['id'])
@@ -131,7 +133,7 @@
 
         # Verify the server properties after the rebuild completes
         self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
-        resp, server = self.client.get_server(rebuilt_server['id'])
+        server = self.client.get_server(rebuilt_server['id'])
         rebuilt_image_id = server['image']['id']
         self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
         self.assertEqual(new_name, server['name'])
@@ -145,17 +147,17 @@
             self.client.rebuild(self.server_id, self.image_ref)
 
     @test.attr(type='gate')
+    @test.idempotent_id('30449a88-5aff-4f9b-9866-6ee9b17f906d')
     def test_rebuild_server_in_stop_state(self):
         # The server in stop state  should be rebuilt using the provided
         # image and remain in SHUTOFF state
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         old_image = server['image']['id']
         new_image = self.image_ref_alt \
             if old_image == self.image_ref else self.image_ref
-        resp, server = self.client.stop(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.stop(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'SHUTOFF')
-        resp, rebuilt_server = self.client.rebuild(self.server_id, new_image)
+        rebuilt_server = self.client.rebuild(self.server_id, new_image)
 
         # Verify the properties in the initial response are correct
         self.assertEqual(self.server_id, rebuilt_server['id'])
@@ -165,7 +167,7 @@
 
         # Verify the server properties after the rebuild completes
         self.client.wait_for_server_status(rebuilt_server['id'], 'SHUTOFF')
-        resp, server = self.client.get_server(rebuilt_server['id'])
+        server = self.client.get_server(rebuilt_server['id'])
         rebuilt_image_id = server['image']['id']
         self.assertEqual(new_image, rebuilt_image_id)
 
@@ -177,7 +179,7 @@
 
     def _detect_server_image_flavor(self, server_id):
         # Detects the current server image flavor ref.
-        resp, server = self.client.get_server(server_id)
+        server = self.client.get_server(server_id)
         current_flavor = server['flavor']['id']
         new_flavor_ref = self.flavor_ref_alt \
             if current_flavor == self.flavor_ref else self.flavor_ref
@@ -191,38 +193,39 @@
             self._detect_server_image_flavor(self.server_id)
 
         if stop:
-            resp = self.servers_client.stop(self.server_id)[0]
-            self.assertEqual(202, resp.status)
+            self.servers_client.stop(self.server_id)
             self.servers_client.wait_for_server_status(self.server_id,
                                                        'SHUTOFF')
 
-        resp, server = self.client.resize(self.server_id, new_flavor_ref)
-        self.assertEqual(202, resp.status)
+        self.client.resize(self.server_id, new_flavor_ref)
         self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
 
         self.client.confirm_resize(self.server_id)
         expected_status = 'SHUTOFF' if stop else 'ACTIVE'
         self.client.wait_for_server_status(self.server_id, expected_status)
 
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         self.assertEqual(new_flavor_ref, server['flavor']['id'])
 
         if stop:
             # NOTE(mriedem): tearDown requires the server to be started.
             self.client.start(self.server_id)
 
+    @test.idempotent_id('1499262a-9328-4eda-9068-db1ac57498d2')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='smoke')
     def test_resize_server_confirm(self):
         self._test_resize_server_confirm(stop=False)
 
+    @test.idempotent_id('138b131d-66df-48c9-a171-64f45eb92962')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='smoke')
     def test_resize_server_confirm_from_stopped(self):
         self._test_resize_server_confirm(stop=True)
 
+    @test.idempotent_id('c03aab19-adb1-44f5-917d-c419577e9e68')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='gate')
@@ -233,16 +236,16 @@
         previous_flavor_ref, new_flavor_ref = \
             self._detect_server_image_flavor(self.server_id)
 
-        resp, server = self.client.resize(self.server_id, new_flavor_ref)
-        self.assertEqual(202, resp.status)
+        self.client.resize(self.server_id, new_flavor_ref)
         self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
 
         self.client.revert_resize(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         self.assertEqual(previous_flavor_ref, server['flavor']['id'])
 
+    @test.idempotent_id('b963d4f1-94b3-4c40-9e97-7b583f46e470')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting not available, backup not possible.')
     @test.attr(type='gate')
@@ -251,10 +254,10 @@
         # Positive test:create backup successfully and rotate backups correctly
         # create the first and the second backup
         backup1 = data_utils.rand_name('backup-1')
-        resp, _ = self.servers_client.create_backup(self.server_id,
-                                                    'daily',
-                                                    2,
-                                                    backup1)
+        resp = self.servers_client.create_backup(self.server_id,
+                                                 'daily',
+                                                 2,
+                                                 backup1).response
         oldest_backup_exist = True
 
         # the oldest one should be deleted automatically in this test
@@ -262,7 +265,7 @@
             if oldest_backup_exist:
                 try:
                     self.os.image_client.delete_image(oldest_backup)
-                except exceptions.NotFound:
+                except lib_exc.NotFound:
                     pass
                 else:
                     LOG.warning("Deletion of oldest backup %s should not have "
@@ -271,18 +274,16 @@
 
         image1_id = data_utils.parse_image_id(resp['location'])
         self.addCleanup(_clean_oldest_backup, image1_id)
-        self.assertEqual(202, resp.status)
         self.os.image_client.wait_for_image_status(image1_id, 'active')
 
         backup2 = data_utils.rand_name('backup-2')
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-        resp, _ = self.servers_client.create_backup(self.server_id,
-                                                    'daily',
-                                                    2,
-                                                    backup2)
+        resp = self.servers_client.create_backup(self.server_id,
+                                                 'daily',
+                                                 2,
+                                                 backup2).response
         image2_id = data_utils.parse_image_id(resp['location'])
         self.addCleanup(self.os.image_client.delete_image, image2_id)
-        self.assertEqual(202, resp.status)
         self.os.image_client.wait_for_image_status(image2_id, 'active')
 
         # verify they have been created
@@ -304,13 +305,12 @@
         # the first one will be deleted
         backup3 = data_utils.rand_name('backup-3')
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-        resp, _ = self.servers_client.create_backup(self.server_id,
-                                                    'daily',
-                                                    2,
-                                                    backup3)
+        resp = self.servers_client.create_backup(self.server_id,
+                                                 'daily',
+                                                 2,
+                                                 backup3).response
         image3_id = data_utils.parse_image_id(resp['location'])
         self.addCleanup(self.os.image_client.delete_image, image3_id)
-        self.assertEqual(202, resp.status)
         # the first back up should be deleted
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
         self.os.image_client.wait_for_resource_deletion(image1_id)
@@ -329,13 +329,13 @@
                          (image_list[0]['name'], image_list[1]['name']))
 
     def _get_output(self):
-        resp, output = self.servers_client.get_console_output(
-            self.server_id, 10)
-        self.assertEqual(200, resp.status)
+        output = self.servers_client.get_console_output(
+            self.server_id, 10).data
         self.assertTrue(output, "Console output was empty.")
         lines = len(output.split('\n'))
         self.assertEqual(lines, 10)
 
+    @test.idempotent_id('4b8867e6-fffa-4d54-b1d1-6fdda57be2f3')
     @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
                           'Console output not supported.')
     @test.attr(type='gate')
@@ -348,21 +348,21 @@
         # log file is truncated and we cannot get any console log through
         # "console-log" API.
         # The detail is https://bugs.launchpad.net/nova/+bug/1251920
-        resp, body = self.servers_client.reboot(self.server_id, 'HARD')
-        self.assertEqual(202, resp.status)
+        self.servers_client.reboot(self.server_id, 'HARD')
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
         self.wait_for(self._get_output)
 
+    @test.idempotent_id('89104062-69d8-4b19-a71b-f47b7af093d7')
     @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
                           'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output_with_unlimited_size(self):
-        _, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
 
         def _check_full_length_console_log():
-            _, output = self.servers_client.get_console_output(server['id'],
-                                                               None)
+            output = self.servers_client.get_console_output(server['id'],
+                                                            None).data
             self.assertTrue(output, "Console output was empty.")
             lines = len(output.split('\n'))
 
@@ -373,6 +373,7 @@
 
         self.wait_for(_check_full_length_console_log)
 
+    @test.idempotent_id('5b65d4e7-4ecd-437c-83c0-d6b79d927568')
     @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
                           'Console output not supported.')
     @test.attr(type='gate')
@@ -383,43 +384,40 @@
         # NOTE: SHUTOFF is irregular status. To avoid test instability,
         #       one server is created only for this test without using
         #       the server that was created in setupClass.
-        resp, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
         temp_server_id = server['id']
 
-        resp, server = self.servers_client.stop(temp_server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.stop(temp_server_id)
         self.servers_client.wait_for_server_status(temp_server_id, 'SHUTOFF')
 
         self.wait_for(self._get_output)
 
+    @test.idempotent_id('bd61a9fd-062f-4670-972b-2d6c3e3b9e73')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type='gate')
     def test_pause_unpause_server(self):
-        resp, server = self.client.pause_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.pause_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'PAUSED')
-        resp, server = self.client.unpause_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.unpause_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @test.idempotent_id('0d8ee21e-b749-462d-83da-b85b41c86c7f')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type='gate')
     def test_suspend_resume_server(self):
-        resp, server = self.client.suspend_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.suspend_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
-        resp, server = self.client.resume_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.resume_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @test.idempotent_id('77eba8e0-036e-4635-944b-f7a8f3b78dc9')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type='gate')
     def test_shelve_unshelve_server(self):
-        resp, server = self.client.shelve_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.shelve_server(self.server_id)
 
         offload_time = CONF.compute.shelved_offload_time
         if offload_time >= 0:
@@ -430,49 +428,42 @@
             self.client.wait_for_server_status(self.server_id,
                                                'SHELVED')
 
-            resp, server = self.client.shelve_offload_server(self.server_id)
-            self.assertEqual(202, resp.status)
+            self.client.shelve_offload_server(self.server_id)
             self.client.wait_for_server_status(self.server_id,
                                                'SHELVED_OFFLOADED')
 
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         image_name = server['name'] + '-shelved'
         params = {'name': image_name}
         images = self.images_client.list_images(params)
         self.assertEqual(1, len(images))
         self.assertEqual(image_name, images[0]['name'])
 
-        resp, server = self.client.unshelve_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.unshelve_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
     def test_stop_start_server(self):
-        resp, server = self.servers_client.stop(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.stop(self.server_id)
         self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
-        resp, server = self.servers_client.start(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.start(self.server_id)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('80a8094c-211e-440a-ab88-9e59d556c7ee')
     def test_lock_unlock_server(self):
         # Lock the server,try server stop(exceptions throw),unlock it and retry
-        resp, server = self.servers_client.lock_server(self.server_id)
-        self.assertEqual(202, resp.status)
-        resp, server = self.servers_client.get_server(self.server_id)
-        self.assertEqual(200, resp.status)
+        self.servers_client.lock_server(self.server_id)
+        server = self.servers_client.get_server(self.server_id)
         self.assertEqual(server['status'], 'ACTIVE')
         # Locked server is not allowed to be stopped by non-admin user
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.servers_client.stop, self.server_id)
-        resp, server = self.servers_client.unlock_server(self.server_id)
-        self.assertEqual(202, resp.status)
-        resp, server = self.servers_client.stop(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.unlock_server(self.server_id)
+        self.servers_client.stop(self.server_id)
         self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
-        resp, server = self.servers_client.start(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.start(self.server_id)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     def _validate_url(self, url):
@@ -482,6 +473,7 @@
         self.assertNotEqual('None', parsed_url.hostname)
         self.assertIn(parsed_url.scheme, valid_scheme)
 
+    @test.idempotent_id('c6bc11bf-592e-4015-9319-1c98dc64daf5')
     @testtools.skipUnless(CONF.compute_feature_enabled.vnc_console,
                           'VNC Console feature is disabled.')
     @test.attr(type='gate')
@@ -489,11 +481,8 @@
         # Get the VNC console of type 'novnc' and 'xvpvnc'
         console_types = ['novnc', 'xvpvnc']
         for console_type in console_types:
-            resp, body = self.servers_client.get_vnc_console(self.server_id,
-                                                             console_type)
-            self.assertEqual(
-                200, resp.status,
-                "Failed to get Console Type: %s" % (console_types))
+            body = self.servers_client.get_vnc_console(self.server_id,
+                                                       console_type)
             self.assertEqual(console_type, body['type'])
             self.assertNotEqual('', body['url'])
             self._validate_url(body['url'])
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 3d1d964..d0dfc87 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -20,22 +20,30 @@
 class ServerAddressesTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def setup_credentials(cls):
         # This test module might use a network and a subnet
         cls.set_network_resources(network=True, subnet=True)
-        super(ServerAddressesTestJSON, cls).resource_setup()
+        super(ServerAddressesTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def setup_clients(cls):
+        super(ServerAddressesTestJSON, cls).setup_clients()
         cls.client = cls.servers_client
 
-        resp, cls.server = cls.create_test_server(wait_until='ACTIVE')
+    @classmethod
+    def resource_setup(cls):
+        super(ServerAddressesTestJSON, cls).resource_setup()
+
+        cls.server = cls.create_test_server(wait_until='ACTIVE')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6eb718c0-02d9-4d5e-acd1-4e0c269cef39')
     @test.services('network')
     def test_list_server_addresses(self):
         # All public and private addresses for
         # a server should be returned
 
-        resp, addresses = self.client.list_addresses(self.server['id'])
-        self.assertEqual('200', resp['status'])
+        addresses = self.client.list_addresses(self.server['id'])
 
         # We do not know the exact network configuration, but an instance
         # should at least have a single public or private address
@@ -47,20 +55,20 @@
                 self.assertTrue(address['version'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('87bbc374-5538-4f64-b673-2b0e4443cc30')
     @test.services('network')
     def test_list_server_addresses_by_network(self):
         # Providing a network type should filter
         # the addresses return by that type
 
-        resp, addresses = self.client.list_addresses(self.server['id'])
+        addresses = self.client.list_addresses(self.server['id'])
 
         # Once again we don't know the environment's exact network config,
         # but the response for each individual network should be the same
         # as the partial result of the full address list
         id = self.server['id']
         for addr_type in addresses:
-            resp, addr = self.client.list_addresses_by_network(id, addr_type)
-            self.assertEqual('200', resp['status'])
+            addr = self.client.list_addresses_by_network(id, addr_type)
 
             addr = addr[addr_type]
             for address in addresses[addr_type]:
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index 3087e59..dac5637 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -13,32 +13,42 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest import test
 
 
 class ServerAddressesNegativeTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def setup_credentials(cls):
         cls.set_network_resources(network=True, subnet=True)
-        super(ServerAddressesNegativeTestJSON, cls).resource_setup()
+        super(ServerAddressesNegativeTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def setup_clients(cls):
+        super(ServerAddressesNegativeTestJSON, cls).setup_clients()
         cls.client = cls.servers_client
 
-        resp, cls.server = cls.create_test_server(wait_until='ACTIVE')
+    @classmethod
+    def resource_setup(cls):
+        super(ServerAddressesNegativeTestJSON, cls).resource_setup()
+        cls.server = cls.create_test_server(wait_until='ACTIVE')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('02c3f645-2d2e-4417-8525-68c0407d001b')
     @test.services('network')
     def test_list_server_addresses_invalid_server_id(self):
         # List addresses request should fail if server id not in system
-        self.assertRaises(exceptions.NotFound, self.client.list_addresses,
+        self.assertRaises(lib_exc.NotFound, self.client.list_addresses,
                           '999')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a2ab5144-78c0-4942-a0ed-cc8edccfd9ba')
     @test.services('network')
     def test_list_server_addresses_by_network_neg(self):
         # List addresses by network should fail if network name not valid
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.list_addresses_by_network,
                           self.server['id'], 'invalid')
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index fe5dca0..ac04feb 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -37,26 +37,23 @@
         server_group_name = data_utils.rand_name('server-group')
         cls.policy = ['affinity']
 
-        _, cls.created_server_group = cls.create_test_server_group(
+        cls.created_server_group = cls.create_test_server_group(
             server_group_name,
             cls.policy)
 
     def _create_server_group(self, name, policy):
         # create the test server-group with given policy
         server_group = {'name': name, 'policies': policy}
-        resp, body = self.create_test_server_group(name, policy)
-        self.assertEqual(200, resp.status)
+        body = self.create_test_server_group(name, policy)
         for key in ['name', 'policies']:
             self.assertEqual(server_group[key], body[key])
         return body
 
     def _delete_server_group(self, server_group):
         # delete the test server-group
-        resp, _ = self.client.delete_server_group(server_group['id'])
-        self.assertEqual(204, resp.status)
+        self.client.delete_server_group(server_group['id'])
         # validation of server-group deletion
-        resp, server_group_list = self.client.list_server_groups()
-        self.assertEqual(200, resp.status)
+        server_group_list = self.client.list_server_groups()
         self.assertNotIn(server_group, server_group_list)
 
     def _create_delete_server_group(self, policy):
@@ -66,11 +63,13 @@
         self._delete_server_group(server_group)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5dc57eda-35b7-4af7-9e5f-3c2be3d2d68b')
     def test_create_delete_server_group_with_affinity_policy(self):
         # Create and Delete the server-group with affinity policy
         self._create_delete_server_group(self.policy)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3645a102-372f-4140-afad-13698d850d23')
     def test_create_delete_server_group_with_anti_affinity_policy(self):
         # Create and Delete the server-group with anti-affinity policy
         policy = ['anti-affinity']
@@ -78,12 +77,14 @@
 
     @decorators.skip_because(bug="1324348")
     @test.attr(type='gate')
+    @test.idempotent_id('6d9bae05-eb32-425d-a673-e14e1b1c6306')
     def test_create_delete_server_group_with_multiple_policies(self):
         # Create and Delete the server-group with multiple policies
         policies = ['affinity', 'affinity']
         self._create_delete_server_group(policies)
 
     @test.attr(type='gate')
+    @test.idempotent_id('154dc5a4-a2fe-44b5-b99e-f15806a4a113')
     def test_create_delete_multiple_server_groups_with_same_name_policy(self):
         # Create and Delete the server-groups with same name and same policy
         server_groups = []
@@ -99,16 +100,16 @@
             self._delete_server_group(server_groups[i])
 
     @test.attr(type='gate')
+    @test.idempotent_id('b3545034-dd78-48f0-bdc2-a4adfa6d0ead')
     def test_get_server_group(self):
         # Get the server-group
-        resp, body = self.client.get_server_group(
+        body = self.client.get_server_group(
             self.created_server_group['id'])
-        self.assertEqual(200, resp.status)
         self.assertEqual(self.created_server_group, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('d4874179-27b4-4d7d-80e4-6c560cdfe321')
     def test_list_server_groups(self):
         # List the server-group
-        resp, body = self.client.list_server_groups()
-        self.assertEqual(200, resp.status)
+        body = self.client.list_server_groups()
         self.assertIn(self.created_server_group, body)
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index 6fd6a6d..4a14228 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -24,92 +24,88 @@
         super(ServerMetadataTestJSON, cls).resource_setup()
         cls.client = cls.servers_client
         cls.quotas = cls.quotas_client
-        resp, server = cls.create_test_server(meta={}, wait_until='ACTIVE')
+        server = cls.create_test_server(meta={}, wait_until='ACTIVE')
         cls.server_id = server['id']
 
     def setUp(self):
         super(ServerMetadataTestJSON, self).setUp()
         meta = {'key1': 'value1', 'key2': 'value2'}
-        resp, _ = self.client.set_server_metadata(self.server_id, meta)
-        self.assertEqual(resp.status, 200)
+        self.client.set_server_metadata(self.server_id, meta)
 
     @test.attr(type='gate')
+    @test.idempotent_id('479da087-92b3-4dcf-aeb3-fd293b2d14ce')
     def test_list_server_metadata(self):
         # All metadata key/value pairs for a server should be returned
-        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        resp_metadata = self.client.list_server_metadata(self.server_id)
 
         # Verify the expected metadata items are in the list
-        self.assertEqual(200, resp.status)
         expected = {'key1': 'value1', 'key2': 'value2'}
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('211021f6-21de-4657-a68f-908878cfe251')
     def test_set_server_metadata(self):
         # The server's metadata should be replaced with the provided values
         # Create a new set of metadata for the server
         req_metadata = {'meta2': 'data2', 'meta3': 'data3'}
-        resp, metadata = self.client.set_server_metadata(self.server_id,
-                                                         req_metadata)
-        self.assertEqual(200, resp.status)
+        self.client.set_server_metadata(self.server_id, req_metadata)
 
         # Verify the expected values are correct, and that the
         # previous values have been removed
-        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        resp_metadata = self.client.list_server_metadata(self.server_id)
         self.assertEqual(resp_metadata, req_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('344d981e-0c33-4997-8a5d-6c1d803e4134')
     def test_update_server_metadata(self):
         # The server's metadata values should be updated to the
         # provided values
         meta = {'key1': 'alt1', 'key3': 'value3'}
-        resp, metadata = self.client.update_server_metadata(self.server_id,
-                                                            meta)
-        self.assertEqual(200, resp.status)
+        self.client.update_server_metadata(self.server_id, meta)
 
         # Verify the values have been updated to the proper values
-        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        resp_metadata = self.client.list_server_metadata(self.server_id)
         expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('0f58d402-e34a-481d-8af8-b392b17426d9')
     def test_update_metadata_empty_body(self):
         # The original metadata should not be lost if empty metadata body is
         # passed
         meta = {}
-        _, metadata = self.client.update_server_metadata(self.server_id, meta)
-        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        self.client.update_server_metadata(self.server_id, meta)
+        resp_metadata = self.client.list_server_metadata(self.server_id)
         expected = {'key1': 'value1', 'key2': 'value2'}
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3043c57d-7e0e-49a6-9a96-ad569c265e6a')
     def test_get_server_metadata_item(self):
         # The value for a specific metadata key should be returned
-        resp, meta = self.client.get_server_metadata_item(self.server_id,
-                                                          'key2')
+        meta = self.client.get_server_metadata_item(self.server_id, 'key2')
         self.assertEqual('value2', meta['key2'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('58c02d4f-5c67-40be-8744-d3fa5982eb1c')
     def test_set_server_metadata_item(self):
         # The item's value should be updated to the provided value
         # Update the metadata value
         meta = {'nova': 'alt'}
-        resp, body = self.client.set_server_metadata_item(self.server_id,
-                                                          'nova', meta)
-        self.assertEqual(200, resp.status)
+        self.client.set_server_metadata_item(self.server_id, 'nova', meta)
 
         # Verify the meta item's value has been updated
-        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        resp_metadata = self.client.list_server_metadata(self.server_id)
         expected = {'key1': 'value1', 'key2': 'value2', 'nova': 'alt'}
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('127642d6-4c7b-4486-b7cd-07265a378658')
     def test_delete_server_metadata_item(self):
         # The metadata value/key pair should be deleted from the server
-        resp, meta = self.client.delete_server_metadata_item(self.server_id,
-                                                             'key1')
-        self.assertEqual(204, resp.status)
+        self.client.delete_server_metadata_item(self.server_id, 'key1')
 
         # Verify the metadata item has been removed
-        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        resp_metadata = self.client.list_server_metadata(self.server_id)
         expected = {'key2': 'value2'}
         self.assertEqual(expected, resp_metadata)
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index e193677..0eb3800 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -27,11 +28,12 @@
         cls.client = cls.servers_client
         cls.quotas = cls.quotas_client
         cls.tenant_id = cls.client.tenant_id
-        resp, server = cls.create_test_server(meta={}, wait_until='ACTIVE')
+        server = cls.create_test_server(meta={}, wait_until='ACTIVE')
 
         cls.server_id = server['id']
 
     @test.attr(type=['gate', 'negative'])
+    @test.idempotent_id('fe114a8f-3a57-4eff-9ee2-4e14628df049')
     def test_server_create_metadata_key_too_long(self):
         # Attempt to start a server with a meta-data key that is > 255
         # characters
@@ -40,84 +42,93 @@
         for sz in [256, 257, 511, 1023]:
             key = "k" * sz
             meta = {key: 'data1'}
-            self.assertRaises((exceptions.BadRequest, exceptions.OverLimit),
+            self.assertRaises((lib_exc.BadRequest, lib_exc.OverLimit),
                               self.create_test_server,
                               meta=meta)
 
         # no teardown - all creates should fail
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('92431555-4d8b-467c-b95b-b17daa5e57ff')
     def test_create_server_metadata_blank_key(self):
         # Blank key should trigger an error.
         meta = {'': 'data1'}
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4d9cd7a3-2010-4b41-b8fe-3bbf0b169466')
     def test_server_metadata_non_existent_server(self):
         # GET on a non-existent server should not succeed
         non_existent_server_id = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_server_metadata_item,
                           non_existent_server_id,
                           'test2')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f408e78e-3066-4097-9299-3b0182da812e')
     def test_list_server_metadata_non_existent_server(self):
         # List metadata on a non-existent server should not succeed
         non_existent_server_id = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.list_server_metadata,
                           non_existent_server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0025fbd6-a4ba-4cde-b8c2-96805dcfdabc')
     def test_wrong_key_passed_in_body(self):
         # Raise BadRequest if key in uri does not match
         # the key passed in body.
         meta = {'testkey': 'testvalue'}
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.set_server_metadata_item,
                           self.server_id, 'key', meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0df38c2a-3d4e-4db5-98d8-d4d9fa843a12')
     def test_set_metadata_non_existent_server(self):
         # Set metadata on a non-existent server should not succeed
         non_existent_server_id = data_utils.rand_uuid()
         meta = {'meta1': 'data1'}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.set_server_metadata,
                           non_existent_server_id,
                           meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('904b13dc-0ef2-4e4c-91cd-3b4a0f2f49d8')
     def test_update_metadata_non_existent_server(self):
         # An update should not happen for a non-existent server
         non_existent_server_id = data_utils.rand_uuid()
         meta = {'key1': 'value1', 'key2': 'value2'}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.update_server_metadata,
                           non_existent_server_id,
                           meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a452f38c-05c2-4b47-bd44-a4f0bf5a5e48')
     def test_update_metadata_with_blank_key(self):
         # Blank key should trigger an error
         meta = {'': 'data1'}
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_server_metadata,
                           self.server_id, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6bbd88e1-f8b3-424d-ba10-ae21c45ada8d')
     def test_delete_metadata_non_existent_server(self):
         # Should not be able to delete metadata item from a non-existent server
         non_existent_server_id = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_server_metadata_item,
                           non_existent_server_id,
                           'd')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d8c0a210-a5c3-4664-be04-69d96746b547')
     def test_metadata_items_limit(self):
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised while exceeding metadata items limit for
@@ -130,31 +141,33 @@
         req_metadata = {}
         for num in range(1, quota_metadata + 2):
             req_metadata['key' + str(num)] = 'val' + str(num)
-        self.assertRaises((exceptions.OverLimit, exceptions.Unauthorized),
+        self.assertRaises((lib_exc.OverLimit, lib_exc.Unauthorized),
                           self.client.set_server_metadata,
                           self.server_id, req_metadata)
 
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised while exceeding metadata items limit for
         # tenant.
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.client.update_server_metadata,
                           self.server_id, req_metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('96100343-7fa9-40d8-80fa-d29ef588ce1c')
     def test_set_server_metadata_blank_key(self):
         # Raise a bad request error for blank key.
         # set_server_metadata will replace all metadata with new value
         meta = {'': 'data1'}
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.set_server_metadata,
                           self.server_id, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('64a91aee-9723-4863-be44-4c9d9f1e7d0e')
     def test_set_server_metadata_missing_metadata(self):
         # Raise a bad request error for a missing metadata field
         # set_server_metadata will replace all metadata with new value
         meta = {'meta1': 'data1'}
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.set_server_metadata,
                           self.server_id, meta=meta, no_metadata_field=True)
diff --git a/tempest/api/compute/servers/test_server_password.py b/tempest/api/compute/servers/test_server_password.py
index 994caa4..57fa408 100644
--- a/tempest/api/compute/servers/test_server_password.py
+++ b/tempest/api/compute/servers/test_server_password.py
@@ -24,14 +24,14 @@
     def resource_setup(cls):
         super(ServerPasswordTestJSON, cls).resource_setup()
         cls.client = cls.servers_client
-        resp, cls.server = cls.create_test_server(wait_until="ACTIVE")
+        cls.server = cls.create_test_server(wait_until="ACTIVE")
 
     @test.attr(type='gate')
+    @test.idempotent_id('f83b582f-62a8-4f22-85b0-0dee50ff783a')
     def test_get_server_password(self):
-        resp, body = self.client.get_password(self.server['id'])
-        self.assertEqual(200, resp.status)
+        self.client.get_password(self.server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('f8229e8b-b625-4493-800a-bde86ac611ea')
     def test_delete_server_password(self):
-        resp, body = self.client.delete_password(self.server['id'])
-        self.assertEqual(204, resp.status)
+        self.client.delete_password(self.server['id'])
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index c6d48bc..4a28dfb 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -14,9 +14,9 @@
 #    under the License.
 
 import base64
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -29,6 +29,7 @@
         cls.user_client = cls.limits_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('176cd8c9-b9e8-48ee-a480-180beab292bf')
     def test_personality_files_exceed_limit(self):
         # Server creation should fail if greater than the maximum allowed
         # number of files are injected into the server.
@@ -44,10 +45,11 @@
                                 'contents': base64.b64encode(file_contents)})
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised when out of quota
-        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+        self.assertRaises((lib_exc.Unauthorized, lib_exc.OverLimit),
                           self.create_test_server, personality=personality)
 
     @test.attr(type='gate')
+    @test.idempotent_id('52f12ee8-5180-40cc-b417-31572ea3d555')
     def test_can_create_server_with_max_number_personality_files(self):
         # Server should be created successfully if maximum allowed number of
         # files is injected into the server during creation.
@@ -63,5 +65,4 @@
                 'path': path,
                 'contents': base64.b64encode(file_contents),
             })
-        resp, server = self.create_test_server(personality=person)
-        self.assertEqual('202', resp['status'])
+        self.create_test_server(personality=person)
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index b04fe69..a1a99a1 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -24,16 +24,23 @@
 class ServerRescueTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
+        super(ServerRescueTestJSON, cls).skip_checks()
         if not CONF.compute_feature_enabled.rescue:
             msg = "Server rescue not available."
             raise cls.skipException(msg)
 
+    @classmethod
+    def setup_credentials(cls):
         cls.set_network_resources(network=True, subnet=True, router=True)
+        super(ServerRescueTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def resource_setup(cls):
         super(ServerRescueTestJSON, cls).resource_setup()
 
         # Floating IP creation
-        resp, body = cls.floating_ips_client.create_floating_ip()
+        body = cls.floating_ips_client.create_floating_ip()
         cls.floating_ip_id = str(body['id']).strip()
         cls.floating_ip = str(body['ip']).strip()
 
@@ -46,7 +53,7 @@
         cls.sg_id = cls.sg['id']
 
         # Server for positive tests
-        resp, server = cls.create_test_server(wait_until='BUILD')
+        server = cls.create_test_server(wait_until='BUILD')
         cls.server_id = server['id']
         cls.password = server['adminPass']
         cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
@@ -66,21 +73,20 @@
         super(ServerRescueTestJSON, self).tearDown()
 
     def _unrescue(self, server_id):
-        resp, body = self.servers_client.unrescue_server(server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.unrescue_server(server_id)
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fd032140-714c-42e4-a8fd-adcd8df06be6')
     def test_rescue_unrescue_instance(self):
-        resp, body = self.servers_client.rescue_server(
+        self.servers_client.rescue_server(
             self.server_id, adminPass=self.password)
-        self.assertEqual(200, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
-        resp, body = self.servers_client.unrescue_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.unrescue_server(self.server_id)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
     def test_rescued_vm_associate_dissociate_floating_ip(self):
         # Rescue the server
         self.servers_client.rescue_server(
@@ -90,17 +96,15 @@
 
         # Association of floating IP to a rescued vm
         client = self.floating_ips_client
-        resp, body = client.associate_floating_ip_to_server(self.floating_ip,
-                                                            self.server_id)
-        self.assertEqual(202, resp.status)
+        client.associate_floating_ip_to_server(self.floating_ip,
+                                               self.server_id)
 
         # Disassociation of floating IP that was associated in this method
-        resp, body = \
-            client.disassociate_floating_ip_from_server(self.floating_ip,
-                                                        self.server_id)
-        self.assertEqual(202, resp.status)
+        client.disassociate_floating_ip_from_server(self.floating_ip,
+                                                    self.server_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('affca41f-7195-492d-8065-e09eee245404')
     def test_rescued_vm_add_remove_security_group(self):
         # Rescue the server
         self.servers_client.rescue_server(
@@ -109,11 +113,8 @@
         self.addCleanup(self._unrescue, self.server_id)
 
         # Add Security group
-        resp, body = self.servers_client.add_security_group(self.server_id,
-                                                            self.sg_name)
-        self.assertEqual(202, resp.status)
+        self.servers_client.add_security_group(self.server_id, self.sg_name)
 
         # Delete Security group
-        resp, body = self.servers_client.remove_security_group(self.server_id,
-                                                               self.sg_name)
-        self.assertEqual(202, resp.status)
+        self.servers_client.remove_security_group(self.server_id,
+                                                  self.sg_name)
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index f1e2f7f..6e23334 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -12,12 +12,13 @@
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
+
+from tempest_lib import exceptions as lib_exc
 import testtools
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -26,18 +27,25 @@
 class ServerRescueNegativeTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
+        super(ServerRescueNegativeTestJSON, cls).skip_checks()
         if not CONF.compute_feature_enabled.rescue:
             msg = "Server rescue not available."
             raise cls.skipException(msg)
 
+    @classmethod
+    def setup_credentials(cls):
         cls.set_network_resources(network=True, subnet=True, router=True)
+        super(ServerRescueNegativeTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def resource_setup(cls):
         super(ServerRescueNegativeTestJSON, cls).resource_setup()
         cls.device = CONF.compute.volume_device_name
 
         # Server for negative tests
-        resp, server = cls.create_test_server(wait_until='BUILD')
-        resp, resc_server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='BUILD')
+        resc_server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
         cls.password = server['adminPass']
         cls.rescue_id = resc_server['id']
@@ -49,7 +57,7 @@
         cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
 
     def _create_volume(self):
-        resp, volume = self.volumes_extensions_client.create_volume(
+        volume = self.volumes_extensions_client.create_volume(
             1, display_name=data_utils.rand_name(
                 self.__class__.__name__ + '_volume'))
         self.addCleanup(self.delete_volume, volume['id'])
@@ -63,48 +71,50 @@
                                                               'available')
 
     def _unrescue(self, server_id):
-        resp, body = self.servers_client.unrescue_server(server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.unrescue_server(server_id)
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
 
     def _unpause(self, server_id):
-        resp, body = self.servers_client.unpause_server(server_id)
-        self.assertEqual(202, resp.status)
+        self.servers_client.unpause_server(server_id)
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
 
+    @test.idempotent_id('cc3a883f-43c0-4fb6-a9bb-5579d64984ed')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_rescue_paused_instance(self):
         # Rescue a paused server
-        resp, body = self.servers_client.pause_server(self.server_id)
+        self.servers_client.pause_server(self.server_id)
         self.addCleanup(self._unpause, self.server_id)
-        self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'PAUSED')
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.servers_client.rescue_server,
                           self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('db22b618-f157-4566-a317-1b6d467a8094')
     def test_rescued_vm_reboot(self):
-        self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
+        self.assertRaises(lib_exc.Conflict, self.servers_client.reboot,
                           self.rescue_id, 'HARD')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6dfc0a55-3a77-4564-a144-1587b7971dde')
     def test_rescue_non_existent_server(self):
         # Rescue a non-existing server
         non_existent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.servers_client.rescue_server,
                           non_existent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('70cdb8a1-89f8-437d-9448-8844fd82bf46')
     def test_rescued_vm_rebuild(self):
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.servers_client.rebuild,
                           self.rescue_id,
                           self.image_ref_alt)
 
+    @test.idempotent_id('d0ccac79-0091-4cf4-a1ce-26162d0cc55f')
     @test.services('volume')
     @test.attr(type=['negative', 'gate'])
     def test_rescued_vm_attach_volume(self):
@@ -117,12 +127,13 @@
         self.addCleanup(self._unrescue, self.server_id)
 
         # Attach the volume to the server
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.servers_client.attach_volume,
                           self.server_id,
                           volume['id'],
                           device='/dev/%s' % self.device)
 
+    @test.idempotent_id('f56e465b-fe10-48bf-b75d-646cda3a8bc9')
     @test.services('volume')
     @test.attr(type=['negative', 'gate'])
     def test_rescued_vm_detach_volume(self):
@@ -144,7 +155,7 @@
         self.addCleanup(self._unrescue, self.server_id)
 
         # Detach the volume from the server expecting failure
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.servers_client.detach_volume,
                           self.server_id,
                           volume['id'])
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index d31b320..624d9c2 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -30,97 +30,101 @@
         super(ServersTestJSON, self).tearDown()
 
     @test.attr(type='gate')
+    @test.idempotent_id('b92d5ec7-b1dd-44a2-87e4-45e888c46ef0')
     def test_create_server_with_admin_password(self):
         # If an admin password is provided on server creation, the server's
         # root password should be set to that password.
-        resp, server = self.create_test_server(adminPass='testpassword')
+        server = self.create_test_server(adminPass='testpassword')
 
         # Verify the password is set correctly in the response
         self.assertEqual('testpassword', server['adminPass'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('8fea6be7-065e-47cf-89b8-496e6f96c699')
     def test_create_with_existing_server_name(self):
         # Creating a server with a name that already exists is allowed
 
         # TODO(sdague): clear out try, we do cleanup one layer up
         server_name = data_utils.rand_name('server')
-        resp, server = self.create_test_server(name=server_name,
-                                               wait_until='ACTIVE')
+        server = self.create_test_server(name=server_name,
+                                         wait_until='ACTIVE')
         id1 = server['id']
-        resp, server = self.create_test_server(name=server_name,
-                                               wait_until='ACTIVE')
+        server = self.create_test_server(name=server_name,
+                                         wait_until='ACTIVE')
         id2 = server['id']
         self.assertNotEqual(id1, id2, "Did not create a new server")
-        resp, server = self.client.get_server(id1)
+        server = self.client.get_server(id1)
         name1 = server['name']
-        resp, server = self.client.get_server(id2)
+        server = self.client.get_server(id2)
         name2 = server['name']
         self.assertEqual(name1, name2)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f9e15296-d7f9-4e62-b53f-a04e89160833')
     def test_create_specify_keypair(self):
         # Specify a keypair while creating a server
 
         key_name = data_utils.rand_name('key')
         self.keypairs_client.create_keypair(key_name)
         self.keypairs_client.list_keypairs()
-        resp, server = self.create_test_server(key_name=key_name)
-        self.assertEqual('202', resp['status'])
+        server = self.create_test_server(key_name=key_name)
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
-        resp, server = self.client.get_server(server['id'])
+        server = self.client.get_server(server['id'])
         self.assertEqual(key_name, server['key_name'])
 
     def _update_server_name(self, server_id, status):
         # The server name should be changed to the the provided value
         new_name = data_utils.rand_name('server')
         # Update the server with a new name
-        resp, server = self.client.update_server(server_id,
-                                                 name=new_name)
+        self.client.update_server(server_id,
+                                  name=new_name)
         self.client.wait_for_server_status(server_id, status)
 
         # Verify the name of the server has changed
-        resp, server = self.client.get_server(server_id)
+        server = self.client.get_server(server_id)
         self.assertEqual(new_name, server['name'])
         return server
 
     @test.attr(type='gate')
+    @test.idempotent_id('5e6ccff8-349d-4852-a8b3-055df7988dd2')
     def test_update_server_name(self):
         # The server name should be changed to the the provided value
-        resp, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
 
         self._update_server_name(server['id'], 'ACTIVE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('6ac19cb1-27a3-40ec-b350-810bdc04c08e')
     def test_update_server_name_in_stop_state(self):
         # The server name should be changed to the the provided value
-        resp, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
         self.client.stop(server['id'])
         self.client.wait_for_server_status(server['id'], 'SHUTOFF')
         updated_server = self._update_server_name(server['id'], 'SHUTOFF')
         self.assertNotIn('progress', updated_server)
 
     @test.attr(type='gate')
+    @test.idempotent_id('89b90870-bc13-4b73-96af-f9d4f2b70077')
     def test_update_access_server_address(self):
         # The server's access addresses should reflect the provided values
-        resp, server = self.create_test_server(wait_until='ACTIVE')
+        server = self.create_test_server(wait_until='ACTIVE')
 
         # Update the IPv4 and IPv6 access addresses
-        resp, body = self.client.update_server(server['id'],
-                                               accessIPv4='1.1.1.1',
-                                               accessIPv6='::babe:202:202')
-        self.assertEqual(200, resp.status)
+        self.client.update_server(server['id'],
+                                  accessIPv4='1.1.1.1',
+                                  accessIPv6='::babe:202:202')
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
 
         # Verify the access addresses have been updated
-        resp, server = self.client.get_server(server['id'])
+        server = self.client.get_server(server['id'])
         self.assertEqual('1.1.1.1', server['accessIPv4'])
         self.assertEqual('::babe:202:202', server['accessIPv6'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('38fb1d02-c3c5-41de-91d3-9bc2025a75eb')
     def test_create_server_with_ipv6_addr_only(self):
         # Create a server without an IPv4 address(only IPv6 address).
-        resp, server = self.create_test_server(accessIPv6='2001:2001::3')
-        self.assertEqual('202', resp['status'])
+        server = self.create_test_server(accessIPv6='2001:2001::3')
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
-        resp, server = self.client.get_server(server['id'])
+        server = self.client.get_server(server['id'])
         self.assertEqual('2001:2001::3', server['accessIPv6'])
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index b703cfe..dd82893 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -15,13 +15,13 @@
 
 import sys
 
+from tempest_lib import exceptions as lib_exc
 import testtools
 
 from tempest.api.compute import base
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -46,18 +46,20 @@
         cls.client = cls.servers_client
         cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
         cls.alt_client = cls.alt_os.servers_client
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf')
     def test_server_name_blank(self):
         # Create a server with name parameter empty
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           name='')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b8a7235e-5246-4a8f-a08e-b34877c6586f')
     def test_personality_file_contents_not_encoded(self):
         # Use an unencoded file when creating a server with personality
 
@@ -65,77 +67,86 @@
         person = [{'path': '/etc/testfile.txt',
                    'contents': file_contents}]
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           personality=person)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fcba1052-0a50-4cf3-b1ac-fae241edf02f')
     def test_create_with_invalid_image(self):
         # Create a server with an unknown image
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           image_id=-1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('18f5227f-d155-4429-807c-ccb103887537')
     def test_create_with_invalid_flavor(self):
         # Create a server with an unknown flavor
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           flavor=-1,)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7f70a4d1-608f-4794-9e56-cb182765972c')
     def test_invalid_access_ip_v4_address(self):
         # An access IPv4 address must match a valid address pattern
 
         IPv4 = '1.1.1.1.1.1'
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server, accessIPv4=IPv4)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0')
     def test_invalid_ip_v6_address(self):
         # An access IPv6 address must match a valid address pattern
 
         IPv6 = 'notvalid'
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server, accessIPv6=IPv6)
 
+    @test.idempotent_id('7ea45b3e-e770-46fa-bfcc-9daaf6d987c0')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resize_nonexistent_server(self):
         # Resize a non-existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.resize,
                           nonexistent_server, self.flavor_ref)
 
+    @test.idempotent_id('ced1a1d7-2ab6-45c9-b90f-b27d87b30efd')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resize_server_with_non_existent_flavor(self):
         # Resize a server with non-existent flavor
         nonexistent_flavor = data_utils.rand_uuid()
-        self.assertRaises(exceptions.BadRequest, self.client.resize,
+        self.assertRaises(lib_exc.BadRequest, self.client.resize,
                           self.server_id, flavor_ref=nonexistent_flavor)
 
+    @test.idempotent_id('45436a7d-a388-4a35-a9d8-3adc5d0d940b')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resize_server_with_null_flavor(self):
         # Resize a server with null flavor
-        self.assertRaises(exceptions.BadRequest, self.client.resize,
+        self.assertRaises(lib_exc.BadRequest, self.client.resize,
                           self.server_id, flavor_ref="")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d4c023a0-9c55-4747-9dd5-413b820143c7')
     def test_reboot_non_existent_server(self):
         # Reboot a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.reboot,
+        self.assertRaises(lib_exc.NotFound, self.client.reboot,
                           nonexistent_server, 'SOFT')
 
+    @test.idempotent_id('d1417e7f-a509-41b5-a102-d5eed8613369')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -143,281 +154,310 @@
         # Pause a paused server.
         self.client.pause_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'PAUSED')
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.pause_server,
                           self.server_id)
         self.client.unpause_server(self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('98fa0458-1485-440f-873b-fe7f0d714930')
     def test_rebuild_reboot_deleted_server(self):
         # Rebuild and Reboot a deleted server
-        _, server = self.create_test_server()
+        server = self.create_test_server()
         self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.rebuild,
                           server['id'], self.image_ref_alt)
-        self.assertRaises(exceptions.NotFound, self.client.reboot,
+        self.assertRaises(lib_exc.NotFound, self.client.reboot,
                           server['id'], 'SOFT')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d86141a7-906e-4731-b187-d64a2ea61422')
     def test_rebuild_non_existent_server(self):
         # Rebuild a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.rebuild,
                           nonexistent_server,
                           self.image_ref_alt)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fd57f159-68d6-4c2a-902b-03070828a87e')
     def test_create_numeric_server_name(self):
         server_name = 12345
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           name=server_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c3e0fb12-07fc-4d76-a22e-37409887afe8')
     def test_create_server_name_length_exceeds_256(self):
         # Create a server with name length exceeding 256 characters
 
         server_name = 'a' * 256
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           name=server_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4e72dc2d-44c5-4336-9667-f7972e95c402')
     def test_create_with_invalid_network_uuid(self):
         # Pass invalid network uuid while creating a server
 
         networks = [{'fixed_ip': '10.0.1.1', 'uuid': 'a-b-c-d-e-f-g-h-i-j'}]
 
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           networks=networks)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7a2efc39-530c-47de-b875-2dd01c8d39bd')
     def test_create_with_non_existent_keypair(self):
         # Pass a non-existent keypair while creating a server
 
         key_name = data_utils.rand_name('key')
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           key_name=key_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7fc74810-0bd2-4cd7-8244-4f33a9db865a')
     def test_create_server_metadata_exceeds_length_limit(self):
         # Pass really long metadata while creating a server
 
         metadata = {'a': 'b' * 260}
-        self.assertRaises((exceptions.BadRequest, exceptions.OverLimit),
+        self.assertRaises((lib_exc.BadRequest, lib_exc.OverLimit),
                           self.create_test_server,
                           meta=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('aa8eed43-e2cb-4ebf-930b-da14f6a21d81')
     def test_update_name_of_non_existent_server(self):
         # Update name of a non-existent server
 
         server_name = data_utils.rand_name('server')
         new_name = data_utils.rand_name('server') + '_updated'
 
-        self.assertRaises(exceptions.NotFound, self.client.update_server,
+        self.assertRaises(lib_exc.NotFound, self.client.update_server,
                           server_name, name=new_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('38204696-17c6-44da-9590-40f87fb5a899')
     def test_update_server_set_empty_name(self):
         # Update name of the server to an empty string
 
         server_name = data_utils.rand_name('server')
         new_name = ''
 
-        self.assertRaises(exceptions.BadRequest, self.client.update_server,
+        self.assertRaises(lib_exc.BadRequest, self.client.update_server,
                           server_name, name=new_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
     def test_update_server_of_another_tenant(self):
         # Update name of a server that belongs to another tenant
 
         new_name = self.server_id + '_new'
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_client.update_server, self.server_id,
                           name=new_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5c8e244c-dada-4590-9944-749c455b431f')
     def test_update_server_name_length_exceeds_256(self):
         # Update name of server exceed the name length limit
 
         new_name = 'a' * 256
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_server,
                           self.server_id,
                           name=new_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1041b4e6-514b-4855-96a5-e974b60870a3')
     def test_delete_non_existent_server(self):
         # Delete a non existent server
 
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.delete_server,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_server,
                           nonexistent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
     def test_delete_a_server_of_another_tenant(self):
         # Delete a server that belongs to another tenant
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_client.delete_server,
                           self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('75f79124-277c-45e6-a373-a1d6803f4cc4')
     def test_delete_server_pass_negative_id(self):
         # Pass an invalid string parameter to delete server
 
-        self.assertRaises(exceptions.NotFound, self.client.delete_server, -1)
+        self.assertRaises(lib_exc.NotFound, self.client.delete_server, -1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5')
     def test_delete_server_pass_id_exceeding_length_limit(self):
         # Pass a server ID that exceeds length limit to delete server
 
-        self.assertRaises(exceptions.NotFound, self.client.delete_server,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_server,
                           sys.maxint + 1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c5fa6041-80cd-483b-aa6d-4e45f19d093c')
     def test_create_with_nonexistent_security_group(self):
         # Create a server with a nonexistent security group
 
         security_groups = [{'name': 'does_not_exist'}]
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           security_groups=security_groups)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3436b02f-1b1e-4f03-881e-c6a602327439')
     def test_get_non_existent_server(self):
         # Get a non existent server details
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.get_server,
+        self.assertRaises(lib_exc.NotFound, self.client.get_server,
                           nonexistent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a31460a9-49e1-42aa-82ee-06e0bb7c2d03')
     def test_stop_non_existent_server(self):
         # Stop a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.servers_client.stop,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.stop,
                           nonexistent_server)
 
+    @test.idempotent_id('6a8dc0c6-6cd4-4c0a-9f32-413881828091')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_pause_non_existent_server(self):
         # pause a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.pause_server,
+        self.assertRaises(lib_exc.NotFound, self.client.pause_server,
                           nonexistent_server)
 
+    @test.idempotent_id('705b8e3a-e8a7-477c-a19b-6868fc24ac75')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_unpause_non_existent_server(self):
         # unpause a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.unpause_server,
+        self.assertRaises(lib_exc.NotFound, self.client.unpause_server,
                           nonexistent_server)
 
+    @test.idempotent_id('c8e639a7-ece8-42dd-a2e0-49615917ba4f')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_unpause_server_invalid_state(self):
         # unpause an active server.
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.unpause_server,
                           self.server_id)
 
+    @test.idempotent_id('d1f032d5-7b6e-48aa-b252-d5f16dd994ca')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_suspend_non_existent_server(self):
         # suspend a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.suspend_server,
+        self.assertRaises(lib_exc.NotFound, self.client.suspend_server,
                           nonexistent_server)
 
+    @test.idempotent_id('7f323206-05a9-4bf8-996b-dd5b2036501b')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_suspend_server_invalid_state(self):
         # suspend a suspended server.
-        resp, _ = self.client.suspend_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.suspend_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.suspend_server,
                           self.server_id)
         self.client.resume_server(self.server_id)
 
+    @test.idempotent_id('221cd282-bddb-4837-a683-89c2487389b6')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resume_non_existent_server(self):
         # resume a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.resume_server,
+        self.assertRaises(lib_exc.NotFound, self.client.resume_server,
                           nonexistent_server)
 
+    @test.idempotent_id('ccb6294d-c4c9-498f-8a43-554c098bfadb')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resume_server_invalid_state(self):
         # resume an active server.
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.resume_server,
                           self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7dd919e7-413f-4198-bebb-35e2a01b13e9')
     def test_get_console_output_of_non_existent_server(self):
         # get the console output for a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_console_output,
                           nonexistent_server, 10)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6f47992b-5144-4250-9f8b-f00aa33950f3')
     def test_force_delete_nonexistent_server_id(self):
         # force-delete a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.force_delete_server,
                           nonexistent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c6d38cc-fcfb-437a-85b9-7b788af8bf01')
     def test_restore_nonexistent_server_id(self):
         # restore-delete a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.restore_soft_deleted_server,
                           nonexistent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7fcadfab-bd6a-4753-8db7-4a51e51aade9')
     def test_restore_server_invalid_state(self):
         # we can only restore-delete a server in 'soft-delete' state
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.restore_soft_deleted_server,
                           self.server_id)
 
+    @test.idempotent_id('abca56e2-a892-48ea-b5e5-e07e69774816')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_shelve_non_existent_server(self):
         # shelve a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.shelve_server,
+        self.assertRaises(lib_exc.NotFound, self.client.shelve_server,
                           nonexistent_server)
 
+    @test.idempotent_id('443e4f9b-e6bf-4389-b601-3a710f15fddd')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_shelve_shelved_server(self):
         # shelve a shelved server.
-        resp, server = self.client.shelve_server(self.server_id)
-        self.assertEqual(202, resp.status)
+        self.client.shelve_server(self.server_id)
 
         offload_time = CONF.compute.shelved_offload_time
         if offload_time >= 0:
@@ -428,33 +468,35 @@
             self.client.wait_for_server_status(self.server_id,
                                                'SHELVED')
 
-        resp, server = self.client.get_server(self.server_id)
+        server = self.client.get_server(self.server_id)
         image_name = server['name'] + '-shelved'
         params = {'name': image_name}
         images = self.images_client.list_images(params)
         self.assertEqual(1, len(images))
         self.assertEqual(image_name, images[0]['name'])
 
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.shelve_server,
                           self.server_id)
 
         self.client.unshelve_server(self.server_id)
 
+    @test.idempotent_id('23d23b37-afaf-40d7-aa5d-5726f82d8821')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_unshelve_non_existent_server(self):
         # unshelve a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.unshelve_server,
+        self.assertRaises(lib_exc.NotFound, self.client.unshelve_server,
                           nonexistent_server)
 
+    @test.idempotent_id('8f198ded-1cca-4228-9e65-c6b449c54880')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_unshelve_server_invalid_state(self):
         # unshelve an active server.
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.unshelve_server,
                           self.server_id)
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index e07a7ed..0b2f4c6 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -26,23 +26,31 @@
 class VirtualInterfacesTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def setup_credentials(cls):
         # This test needs a network and a subnet
         cls.set_network_resources(network=True, subnet=True)
-        super(VirtualInterfacesTestJSON, cls).resource_setup()
+        super(VirtualInterfacesTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def setup_clients(cls):
+        super(VirtualInterfacesTestJSON, cls).setup_clients()
         cls.client = cls.servers_client
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
+
+    @classmethod
+    def resource_setup(cls):
+        super(VirtualInterfacesTestJSON, cls).resource_setup()
+        server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
 
     @decorators.skip_because(bug="1183436",
                              condition=CONF.service_available.neutron)
     @test.attr(type='gate')
+    @test.idempotent_id('96c4e2ef-5e4d-4d7f-87f5-fed6dca18016')
     @test.services('network')
     def test_list_virtual_interfaces(self):
         # Positive test:Should be able to GET the virtual interfaces list
         # for a given server_id
-        resp, output = self.client.list_virtual_interfaces(self.server_id)
-        self.assertEqual(200, resp.status)
+        output = self.client.list_virtual_interfaces(self.server_id)
         self.assertIsNotNone(output)
         virt_ifaces = output
         self.assertNotEqual(0, len(virt_ifaces['virtual_interfaces']),
diff --git a/tempest/api/compute/servers/test_virtual_interfaces_negative.py b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
index e81ccc6..e5cb744 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces_negative.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
@@ -15,26 +15,32 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest import test
 
 
 class VirtualInterfacesNegativeTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
+    def setup_credentials(cls):
         # For this test no network resources are needed
         cls.set_network_resources()
-        super(VirtualInterfacesNegativeTestJSON, cls).resource_setup()
+        super(VirtualInterfacesNegativeTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def setup_clients(cls):
+        super(VirtualInterfacesNegativeTestJSON, cls).setup_clients()
         cls.client = cls.servers_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('64ebd03c-1089-4306-93fa-60f5eb5c803c')
     @test.services('network')
     def test_list_virtual_interfaces_invalid_server_id(self):
         # Negative test: Should not be able to GET virtual interfaces
         # for an invalid server_id
         invalid_server_id = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.list_virtual_interfaces,
                           invalid_server_id)
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index cdbaee8..2dbe123 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -15,11 +15,12 @@
 
 import StringIO
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest import test
 
@@ -29,32 +30,44 @@
 
 
 class AuthorizationTestJSON(base.BaseV2ComputeTest):
+
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
+        super(AuthorizationTestJSON, cls).skip_checks()
         if not CONF.service_available.glance:
             raise cls.skipException('Glance is not available.')
+
+    @classmethod
+    def setup_credentials(cls):
         # No network resources required for this test
         cls.set_network_resources()
-        super(AuthorizationTestJSON, cls).resource_setup()
+        super(AuthorizationTestJSON, cls).setup_credentials()
         if not cls.multi_user:
             msg = "Need >1 user"
             raise cls.skipException(msg)
+
+        creds = cls.isolated_creds.get_alt_creds()
+        cls.alt_manager = clients.Manager(credentials=creds)
+
+    @classmethod
+    def setup_clients(cls):
+        super(AuthorizationTestJSON, cls).setup_clients()
         cls.client = cls.os.servers_client
         cls.images_client = cls.os.images_client
         cls.glance_client = cls.os.image_client
         cls.keypairs_client = cls.os.keypairs_client
         cls.security_client = cls.os.security_groups_client
 
-        creds = cls.isolated_creds.get_alt_creds()
-        cls.alt_manager = clients.Manager(credentials=creds)
-
         cls.alt_client = cls.alt_manager.servers_client
         cls.alt_images_client = cls.alt_manager.images_client
         cls.alt_keypairs_client = cls.alt_manager.keypairs_client
         cls.alt_security_client = cls.alt_manager.security_groups_client
 
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
-        resp, cls.server = cls.client.get_server(server['id'])
+    @classmethod
+    def resource_setup(cls):
+        super(AuthorizationTestJSON, cls).resource_setup()
+        server = cls.create_test_server(wait_until='ACTIVE')
+        cls.server = cls.client.get_server(server['id'])
 
         name = data_utils.rand_name('image')
         body = cls.glance_client.create_image(name=name,
@@ -91,85 +104,98 @@
         super(AuthorizationTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('56816e4a-bd34-47b5-aee9-268c3efeb5d4')
     def test_get_server_for_alt_account_fails(self):
         # A GET request for a server on another user's account should fail
-        self.assertRaises(exceptions.NotFound, self.alt_client.get_server,
+        self.assertRaises(lib_exc.NotFound, self.alt_client.get_server,
                           self.server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('fb8a4870-6d9d-44ad-8375-95d52e98d9f6')
     def test_delete_server_for_alt_account_fails(self):
         # A DELETE request for another user's server should fail
-        self.assertRaises(exceptions.NotFound, self.alt_client.delete_server,
+        self.assertRaises(lib_exc.NotFound, self.alt_client.delete_server,
                           self.server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d792f91f-1d49-4eb5-b1ff-b229c4b9dc64')
     def test_update_server_for_alt_account_fails(self):
         # An update server request for another user's server should fail
-        self.assertRaises(exceptions.NotFound, self.alt_client.update_server,
+        self.assertRaises(lib_exc.NotFound, self.alt_client.update_server,
                           self.server['id'], name='test')
 
     @test.attr(type='gate')
+    @test.idempotent_id('488f24df-d7f7-4207-949a-f17fcb8e8769')
     def test_list_server_addresses_for_alt_account_fails(self):
         # A list addresses request for another user's server should fail
-        self.assertRaises(exceptions.NotFound, self.alt_client.list_addresses,
+        self.assertRaises(lib_exc.NotFound, self.alt_client.list_addresses,
                           self.server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('00b442d0-2e72-40e7-9b1f-31772e36da01')
     def test_list_server_addresses_by_network_for_alt_account_fails(self):
         # A list address/network request for another user's server should fail
         server_id = self.server['id']
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_client.list_addresses_by_network, server_id,
                           'public')
 
     @test.attr(type='gate')
+    @test.idempotent_id('cc90b35a-19f0-45d2-b680-2aabf934aa22')
     def test_list_servers_with_alternate_tenant(self):
         # A list on servers from one tenant should not
         # show on alternate tenant
         # Listing servers from alternate tenant
         alt_server_ids = []
-        resp, body = self.alt_client.list_servers()
+        body = self.alt_client.list_servers()
         alt_server_ids = [s['id'] for s in body['servers']]
         self.assertNotIn(self.server['id'], alt_server_ids)
 
     @test.attr(type='gate')
+    @test.idempotent_id('376dbc16-0779-4384-a723-752774799641')
     def test_change_password_for_alt_account_fails(self):
         # A change password request for another user's server should fail
-        self.assertRaises(exceptions.NotFound, self.alt_client.change_password,
+        self.assertRaises(lib_exc.NotFound, self.alt_client.change_password,
                           self.server['id'], 'newpass')
 
     @test.attr(type='gate')
+    @test.idempotent_id('14cb5ff5-f646-45ca-8f51-09081d6c0c24')
     def test_reboot_server_for_alt_account_fails(self):
         # A reboot request for another user's server should fail
-        self.assertRaises(exceptions.NotFound, self.alt_client.reboot,
+        self.assertRaises(lib_exc.NotFound, self.alt_client.reboot,
                           self.server['id'], 'HARD')
 
     @test.attr(type='gate')
+    @test.idempotent_id('8a0bce51-cd00-480b-88ba-dbc7d8408a37')
     def test_rebuild_server_for_alt_account_fails(self):
         # A rebuild request for another user's server should fail
-        self.assertRaises(exceptions.NotFound, self.alt_client.rebuild,
+        self.assertRaises(lib_exc.NotFound, self.alt_client.rebuild,
                           self.server['id'], self.image_ref_alt)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e4da647e-f982-4e61-9dad-1d1abebfb933')
     def test_resize_server_for_alt_account_fails(self):
         # A resize request for another user's server should fail
-        self.assertRaises(exceptions.NotFound, self.alt_client.resize,
+        self.assertRaises(lib_exc.NotFound, self.alt_client.resize,
                           self.server['id'], self.flavor_ref_alt)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a9fe8112-0ffa-4902-b061-f892bd5fe0d3')
     def test_create_image_for_alt_account_fails(self):
         # A create image request for another user's server should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_images_client.create_image,
                           self.server['id'], 'testImage')
 
     @test.attr(type='gate')
+    @test.idempotent_id('95d445f6-babc-4f2e-aea3-aa24ec5e7f0d')
     def test_create_server_with_unauthorized_image(self):
         # Server creation with another user's image should fail
-        self.assertRaises(exceptions.BadRequest, self.alt_client.create_server,
+        self.assertRaises(lib_exc.BadRequest, self.alt_client.create_server,
                           'test', self.image['id'], self.flavor_ref)
 
     @test.attr(type='gate')
+    @test.idempotent_id('acf8724b-142b-4044-82c3-78d31a533f24')
     def test_create_server_fails_when_tenant_incorrect(self):
         # A create server request should fail if the tenant id does not match
         # the current user
@@ -178,11 +204,12 @@
             request_part='url',
             auth_data=self.client.auth_provider.auth_data
         )
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.alt_client.create_server, 'test',
                           self.image['id'], self.flavor_ref)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f03d1ded-7fd4-4d29-bc13-e2391f29c625')
     def test_create_keypair_in_analt_user_tenant(self):
         # A create keypair request should fail if the tenant id does not match
         # the current user
@@ -196,7 +223,7 @@
             )
             resp = {}
             resp['status'] = None
-            self.assertRaises(exceptions.BadRequest,
+            self.assertRaises(lib_exc.BadRequest,
                               self.alt_keypairs_client.create_keypair, k_name)
         finally:
             # Next request the base_url is back to normal
@@ -206,33 +233,38 @@
                           "if the tenant id does not match the current user")
 
     @test.attr(type='gate')
+    @test.idempotent_id('85bcdd8f-56b4-4868-ae56-63fbf6f7e405')
     def test_get_keypair_of_alt_account_fails(self):
         # A GET request for another user's keypair should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_keypairs_client.get_keypair,
                           self.keypairname)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6d841683-a8e0-43da-a1b8-b339f7692b61')
     def test_delete_keypair_of_alt_account_fails(self):
         # A DELETE request for another user's keypair should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_keypairs_client.delete_keypair,
                           self.keypairname)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fcb2e144-36e3-4dfb-9f9f-e72fcdec5656')
     def test_get_image_for_alt_account_fails(self):
         # A GET request for an image on another user's account should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_images_client.get_image, self.image['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('9facb962-f043-4a9d-b9ee-166a32dea098')
     def test_delete_image_for_alt_account_fails(self):
         # A DELETE request for another user's image should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_images_client.delete_image,
                           self.image['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('752c917e-83be-499d-a422-3559127f7d3c')
     def test_create_security_group_in_analt_user_tenant(self):
         # A create security group request should fail if the tenant id does not
         # match the current user
@@ -247,7 +279,7 @@
             )
             resp = {}
             resp['status'] = None
-            self.assertRaises(exceptions.BadRequest,
+            self.assertRaises(lib_exc.BadRequest,
                               self.alt_security_client.create_security_group,
                               s_name, s_description)
         finally:
@@ -258,20 +290,23 @@
                           "the tenant id does not match the current user")
 
     @test.attr(type='gate')
+    @test.idempotent_id('9db3590f-4d15-4e5f-985e-b28514919a6f')
     def test_get_security_group_of_alt_account_fails(self):
         # A GET request for another user's security group should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_security_client.get_security_group,
                           self.security_group['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('155387a5-2bbc-4acf-ab06-698dae537ea5')
     def test_delete_security_group_of_alt_account_fails(self):
         # A DELETE request for another user's security group should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_security_client.delete_security_group,
                           self.security_group['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('b2b76de0-210a-4089-b921-591c9ec552f6')
     def test_create_security_group_rule_in_analt_user_tenant(self):
         # A create security group rule request should fail if the tenant id
         # does not match the current user
@@ -288,7 +323,7 @@
             )
             resp = {}
             resp['status'] = None
-            self.assertRaises(exceptions.BadRequest,
+            self.assertRaises(lib_exc.BadRequest,
                               self.alt_security_client.
                               create_security_group_rule,
                               parent_group_id, ip_protocol, from_port,
@@ -302,42 +337,47 @@
                           " current user")
 
     @test.attr(type='gate')
+    @test.idempotent_id('c6044177-37ef-4ce4-b12c-270ddf26d7da')
     def test_delete_security_group_rule_of_alt_account_fails(self):
         # A DELETE request for another user's security group rule
         # should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_security_client.delete_security_group_rule,
                           self.rule['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('c5f52351-53d9-4fc9-83e5-917f7f5e3d71')
     def test_set_metadata_of_alt_account_server_fails(self):
         # A set metadata for another user's server should fail
         req_metadata = {'meta1': 'data1', 'meta2': 'data2'}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_client.set_server_metadata,
                           self.server['id'],
                           req_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fb6f51e9-df15-4939-898d-1aca38c258f0')
     def test_set_metadata_of_alt_account_image_fails(self):
         # A set metadata for another user's image should fail
         req_metadata = {'meta1': 'value1', 'meta2': 'value2'}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_images_client.set_image_metadata,
                           self.image['id'], req_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('dea1936a-473d-49f2-92ad-97bb7aded22e')
     def test_get_metadata_of_alt_account_server_fails(self):
         # A get metadata for another user's server should fail
         req_metadata = {'meta1': 'data1'}
         self.client.set_server_metadata(self.server['id'], req_metadata)
         self.addCleanup(self.client.delete_server_metadata_item,
                         self.server['id'], 'meta1')
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_client.get_server_metadata_item,
                           self.server['id'], 'meta1')
 
     @test.attr(type='gate')
+    @test.idempotent_id('16b2d724-0d3b-4216-a9fa-97bd4d9cf670')
     def test_get_metadata_of_alt_account_image_fails(self):
         # A get metadata for another user's image should fail
         req_metadata = {'meta1': 'value1'}
@@ -345,22 +385,24 @@
                         self.image['id'], 'meta1')
         self.images_client.set_image_metadata(self.image['id'],
                                               req_metadata)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_images_client.get_image_metadata_item,
                           self.image['id'], 'meta1')
 
     @test.attr(type='gate')
+    @test.idempotent_id('79531e2e-e721-493c-8b30-a35db36fdaa6')
     def test_delete_metadata_of_alt_account_server_fails(self):
         # A delete metadata for another user's server should fail
         req_metadata = {'meta1': 'data1'}
         self.addCleanup(self.client.delete_server_metadata_item,
                         self.server['id'], 'meta1')
         self.client.set_server_metadata(self.server['id'], req_metadata)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_client.delete_server_metadata_item,
                           self.server['id'], 'meta1')
 
     @test.attr(type='gate')
+    @test.idempotent_id('a5175dcf-cef8-43d6-9b77-3cb707d62e94')
     def test_delete_metadata_of_alt_account_image_fails(self):
         # A delete metadata for another user's image should fail
         req_metadata = {'meta1': 'data1'}
@@ -368,13 +410,14 @@
                         self.image['id'], 'meta1')
         self.images_client.set_image_metadata(self.image['id'],
                                               req_metadata)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_images_client.delete_image_metadata_item,
                           self.image['id'], 'meta1')
 
     @test.attr(type='gate')
+    @test.idempotent_id('b0c1e7a0-8853-40fd-8384-01f93d116cae')
     def test_get_console_output_of_alt_account_server_fails(self):
         # A Get Console Output for another user's server should fail
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_client.get_console_output,
                           self.server['id'], 10)
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index 46e7251..1063f90 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -28,12 +28,12 @@
 class ExtensionsTestJSON(base.BaseV2ComputeTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('3bb27738-b759-4e0d-a5fa-37d7a6df07d1')
     def test_list_extensions(self):
         # List of all extensions
         if len(CONF.compute_feature_enabled.api_extensions) == 0:
             raise self.skipException('There are not any extensions configured')
-        resp, extensions = self.extensions_client.list_extensions()
-        self.assertEqual(200, resp.status)
+        extensions = self.extensions_client.list_extensions()
         ext = CONF.compute_feature_enabled.api_extensions[0]
         if ext == 'all':
             self.assertIn('Hosts', map(lambda x: x['name'], extensions))
@@ -45,10 +45,10 @@
         extension_list = map(lambda x: x['alias'], extensions)
         LOG.debug("Nova extensions: %s" % ','.join(extension_list))
 
+    @test.idempotent_id('05762f39-bdfa-4cdb-9b46-b78f8e78e2fd')
     @test.requires_ext(extension='os-consoles', service='compute')
     @test.attr(type='gate')
     def test_get_extension(self):
         # get the specified extensions
-        resp, extension = self.extensions_client.get_extension('os-consoles')
-        self.assertEqual(200, resp.status)
+        extension = self.extensions_client.get_extension('os-consoles')
         self.assertEqual('os-consoles', extension['alias'])
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index eb71d6d..a933f81 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -44,14 +44,14 @@
         ]
 
     def _get_server_details(self, server_id):
-        _resp, body = self.admin_servers_client.get_server(server_id)
+        body = self.admin_servers_client.get_server(server_id)
         return body
 
     def _get_host_for_server(self, server_id):
         return self._get_server_details(server_id)[self._host_key]
 
     def _migrate_server_to(self, server_id, dest_host):
-        _resp, body = self.admin_servers_client.live_migrate_server(
+        body = self.admin_servers_client.live_migrate_server(
             server_id, dest_host,
             CONF.compute_feature_enabled.block_migration_for_live_migration)
         return body
@@ -69,10 +69,8 @@
             if 'ACTIVE' == self._get_server_status(server_id):
                 return server_id
         else:
-            _, server = self.create_test_server(wait_until="ACTIVE")
+            server = self.create_test_server(wait_until="ACTIVE")
             server_id = server['id']
-            self.password = server['adminPass']
-            self.password = 'password'
             self.created_server_ids.append(server_id)
             return server_id
 
@@ -83,6 +81,7 @@
             self.volumes_client.wait_for_volume_status(volume_id, 'available')
         self.volumes_client.delete_volume(volume_id)
 
+    @test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
     @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
                       'Live migration not available')
     @test.attr(type='gate')
@@ -98,6 +97,7 @@
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
         self.assertEqual(target_host, self._get_host_for_server(server_id))
 
+    @test.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
     @testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
                       CONF.compute_feature_enabled.
                       block_migration_for_live_migration,
diff --git a/tempest/api/compute/test_live_block_migration_negative.py b/tempest/api/compute/test_live_block_migration_negative.py
index 281b2b3..bed53d6 100644
--- a/tempest/api/compute/test_live_block_migration_negative.py
+++ b/tempest/api/compute/test_live_block_migration_negative.py
@@ -13,11 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -35,19 +35,20 @@
         cls.admin_servers_client = cls.os_adm.servers_client
 
     def _migrate_server_to(self, server_id, dest_host):
-        _resp, body = self.admin_servers_client.live_migrate_server(
+        body = self.admin_servers_client.live_migrate_server(
             server_id, dest_host,
             CONF.compute_feature_enabled.
             block_migration_for_live_migration)
         return body
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7fb7856e-ae92-44c9-861a-af62d7830bcb')
     def test_invalid_host_for_migration(self):
         # Migrating to an invalid host should not change the status
         target_host = data_utils.rand_name('host-')
-        _, server = self.create_test_server(wait_until="ACTIVE")
+        server = self.create_test_server(wait_until="ACTIVE")
         server_id = server['id']
 
-        self.assertRaises(exceptions.BadRequest, self._migrate_server_to,
+        self.assertRaises(lib_exc.BadRequest, self._migrate_server_to,
                           server_id, target_host)
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
diff --git a/tempest/api/compute/test_networks.py b/tempest/api/compute/test_networks.py
index 86779b3..c30beb7 100644
--- a/tempest/api/compute/test_networks.py
+++ b/tempest/api/compute/test_networks.py
@@ -28,6 +28,7 @@
         cls.client = cls.os.networks_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('3fe07175-312e-49a5-a623-5f52eeada4c2')
     def test_list_networks(self):
-        _, networks = self.client.list_networks()
+        networks = self.client.list_networks()
         self.assertNotEmpty(networks, "No networks found.")
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index db2e281..1df67d9 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -40,6 +40,7 @@
                                      'cores', 'security_groups'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107')
     def test_get_quotas(self):
         # User can get the quota set for it's tenant
         expected_quota_set = self.default_quota_set | set(['id'])
@@ -56,6 +57,7 @@
             self.assertIn(quota, quota_set.keys())
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9bfecac7-b966-4f47-913f-1a9e2c12134a')
     def test_get_default_quotas(self):
         # User can get the default quota set for it's tenant
         expected_quota_set = self.default_quota_set | set(['id'])
@@ -65,6 +67,7 @@
             self.assertIn(quota, quota_set.keys())
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cd65d997-f7e4-4966-a7e9-d5001b674fdc')
     def test_compare_tenant_quotas_with_default_quotas(self):
         # Tenants are created with the default quota values
         defualt_quota_set = \
diff --git a/tempest/api/compute/test_tenant_networks.py b/tempest/api/compute/test_tenant_networks.py
index 0591acc..3a712dd 100644
--- a/tempest/api/compute/test_tenant_networks.py
+++ b/tempest/api/compute/test_tenant_networks.py
@@ -24,6 +24,7 @@
         cls.client = cls.os.tenant_networks_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('edfea98e-bbe3-4c7a-9739-87b986baff26')
     def test_list_show_tenant_networks(self):
         tenant_networks = self.client.list_tenant_networks()
         self.assertNotEmpty(tenant_networks, "No tenant networks found.")
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 7fef52f..43d2302 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -30,14 +30,22 @@
         self.attachment = None
 
     @classmethod
-    def resource_setup(cls):
-        cls.prepare_instance_network()
-        super(AttachVolumeTestJSON, cls).resource_setup()
-        cls.device = CONF.compute.volume_device_name
+    def skip_checks(cls):
+        super(AttachVolumeTestJSON, cls).skip_checks()
         if not CONF.service_available.cinder:
             skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
+    @classmethod
+    def setup_credentials(cls):
+        cls.prepare_instance_network()
+        super(AttachVolumeTestJSON, cls).setup_credentials()
+
+    @classmethod
+    def resource_setup(cls):
+        super(AttachVolumeTestJSON, cls).resource_setup()
+        cls.device = CONF.compute.volume_device_name
+
     def _detach(self, server_id, volume_id):
         if self.attachment:
             self.servers_client.detach_volume(server_id, volume_id)
@@ -53,11 +61,11 @@
     def _create_and_attach(self):
         # Start a server and wait for it to become ready
         admin_pass = self.image_ssh_password
-        _, self.server = self.create_test_server(wait_until='ACTIVE',
-                                                 adminPass=admin_pass)
+        self.server = self.create_test_server(wait_until='ACTIVE',
+                                              adminPass=admin_pass)
 
         # Record addresses so that we can ssh later
-        _, self.server['addresses'] = (
+        self.server['addresses'] = (
             self.servers_client.list_addresses(self.server['id']))
 
         # Create a volume and wait for it to become ready
@@ -68,7 +76,7 @@
                                                    'available')
 
         # Attach the volume to the server
-        _, self.attachment = self.servers_client.attach_volume(
+        self.attachment = self.servers_client.attach_volume(
             self.server['id'],
             self.volume['id'],
             device='/dev/%s' % self.device)
@@ -76,6 +84,7 @@
 
         self.addCleanup(self._detach, self.server['id'], self.volume['id'])
 
+    @test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
     @testtools.skipUnless(CONF.compute.run_ssh, 'SSH required for this test')
     @test.attr(type='gate')
     def test_attach_detach_volume(self):
@@ -112,17 +121,18 @@
         self.assertNotIn(self.device, partitions)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
     def test_list_get_volume_attachments(self):
         # Create Server, Volume and attach that Volume to Server
         self._create_and_attach()
         # List Volume attachment of the server
-        _, body = self.servers_client.list_volume_attachments(
+        body = self.servers_client.list_volume_attachments(
             self.server['id'])
         self.assertEqual(1, len(body))
         self.assertIn(self.attachment, body)
 
         # Get Volume attachment of the server
-        _, body = self.servers_client.get_volume_attachment(
+        body = self.servers_client.get_volume_attachment(
             self.server['id'],
             self.attachment['id'])
         self.assertEqual(self.server['id'], body['serverId'])
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index d441427..207476d 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -27,25 +27,29 @@
 class VolumesGetTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(VolumesGetTestJSON, cls).resource_setup()
-        cls.client = cls.volumes_extensions_client
+    def skip_checks(cls):
+        super(VolumesGetTestJSON, cls).skip_checks()
         if not CONF.service_available.cinder:
             skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
+    @classmethod
+    def setup_clients(cls):
+        super(VolumesGetTestJSON, cls).setup_clients()
+        cls.client = cls.volumes_extensions_client
+
     @test.attr(type='smoke')
+    @test.idempotent_id('f10f25eb-9775-4d9d-9cbe-1cf54dae9d5f')
     def test_volume_create_get_delete(self):
         # CREATE, GET, DELETE Volume
         volume = None
-        v_name = data_utils.rand_name('Volume-%s-') % self._interface
+        v_name = data_utils.rand_name('Volume')
         metadata = {'Type': 'work'}
         # Create volume
-        resp, volume = self.client.create_volume(size=1,
-                                                 display_name=v_name,
-                                                 metadata=metadata)
+        volume = self.client.create_volume(size=1,
+                                           display_name=v_name,
+                                           metadata=metadata)
         self.addCleanup(self.delete_volume, volume['id'])
-        self.assertEqual(200, resp.status)
         self.assertIn('id', volume)
         self.assertIn('displayName', volume)
         self.assertEqual(volume['displayName'], v_name,
@@ -56,8 +60,7 @@
         # Wait for Volume status to become ACTIVE
         self.client.wait_for_volume_status(volume['id'], 'available')
         # GET Volume
-        resp, fetched_volume = self.client.get_volume(volume['id'])
-        self.assertEqual(200, resp.status)
+        fetched_volume = self.client.get_volume(volume['id'])
         # Verification of details of fetched Volume
         self.assertEqual(v_name,
                          fetched_volume['displayName'],
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 6bf9519..501e9ed 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -32,24 +32,32 @@
     """
 
     @classmethod
-    def resource_setup(cls):
-        super(VolumesTestJSON, cls).resource_setup()
-        cls.client = cls.volumes_extensions_client
+    def skip_checks(cls):
+        super(VolumesTestJSON, cls).skip_checks()
         if not CONF.service_available.cinder:
             skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
+
+    @classmethod
+    def setup_clients(cls):
+        super(VolumesTestJSON, cls).setup_clients()
+        cls.client = cls.volumes_extensions_client
+
+    @classmethod
+    def resource_setup(cls):
+        super(VolumesTestJSON, cls).resource_setup()
         # Create 3 Volumes
         cls.volume_list = []
         cls.volume_id_list = []
         for i in range(3):
-            v_name = data_utils.rand_name('volume-%s' % cls._interface)
+            v_name = data_utils.rand_name('volume')
             metadata = {'Type': 'work'}
             try:
-                resp, volume = cls.client.create_volume(size=1,
-                                                        display_name=v_name,
-                                                        metadata=metadata)
+                volume = cls.client.create_volume(size=1,
+                                                  display_name=v_name,
+                                                  metadata=metadata)
                 cls.client.wait_for_volume_status(volume['id'], 'available')
-                resp, volume = cls.client.get_volume(volume['id'])
+                volume = cls.client.get_volume(volume['id'])
                 cls.volume_list.append(volume)
                 cls.volume_id_list.append(volume['id'])
             except Exception:
@@ -76,11 +84,11 @@
         super(VolumesTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('bc2dd1a0-15af-48e5-9990-f2e75a48325d')
     def test_volume_list(self):
         # Should return the list of Volumes
         # Fetch all Volumes
-        resp, fetched_list = self.client.list_volumes()
-        self.assertEqual(200, resp.status)
+        fetched_list = self.client.list_volumes()
         # Now check if all the Volumes created in setup are in fetched list
         missing_volumes = [
             v for v in self.volume_list if v not in fetched_list
@@ -92,11 +100,11 @@
                                    for m_vol in missing_volumes))
 
     @test.attr(type='gate')
+    @test.idempotent_id('bad0567a-5a4f-420b-851e-780b55bb867c')
     def test_volume_list_with_details(self):
         # Should return the list of Volumes with details
         # Fetch all Volumes
-        resp, fetched_list = self.client.list_volumes_with_detail()
-        self.assertEqual(200, resp.status)
+        fetched_list = self.client.list_volumes_with_detail()
         # Now check if all the Volumes created in setup are in fetched list
         missing_volumes = [
             v for v in self.volume_list if v not in fetched_list
@@ -108,34 +116,33 @@
                                    for m_vol in missing_volumes))
 
     @test.attr(type='gate')
+    @test.idempotent_id('1048ed81-2baf-487a-b284-c0622b86e7b8')
     def test_volume_list_param_limit(self):
         # Return the list of volumes based on limit set
         params = {'limit': 2}
-        resp, fetched_vol_list = self.client.list_volumes(params=params)
-        self.assertEqual(200, resp.status)
+        fetched_vol_list = self.client.list_volumes(params=params)
 
         self.assertEqual(len(fetched_vol_list), params['limit'],
                          "Failed to list volumes by limit set")
 
     @test.attr(type='gate')
+    @test.idempotent_id('33985568-4965-49d5-9bcc-0aa007ca5b7a')
     def test_volume_list_with_detail_param_limit(self):
         # Return the list of volumes with details based on limit set.
         params = {'limit': 2}
-        resp, fetched_vol_list = \
-            self.client.list_volumes_with_detail(params=params)
-        self.assertEqual(200, resp.status)
+        fetched_vol_list = self.client.list_volumes_with_detail(params=params)
 
         self.assertEqual(len(fetched_vol_list), params['limit'],
                          "Failed to list volume details by limit set")
 
     @test.attr(type='gate')
+    @test.idempotent_id('51c22651-a074-4ea7-af0b-094f9331303e')
     def test_volume_list_param_offset_and_limit(self):
         # Return the list of volumes based on offset and limit set.
         # get all volumes list
-        response, all_vol_list = self.client.list_volumes()
+        all_vol_list = self.client.list_volumes()
         params = {'offset': 1, 'limit': 1}
-        resp, fetched_vol_list = self.client.list_volumes(params=params)
-        self.assertEqual(200, resp.status)
+        fetched_vol_list = self.client.list_volumes(params=params)
 
         # Validating length of the fetched volumes
         self.assertEqual(len(fetched_vol_list), params['limit'],
@@ -147,14 +154,13 @@
                              "Failed to list volumes by offset and limit")
 
     @test.attr(type='gate')
+    @test.idempotent_id('06b6abc4-3f10-48e9-a7a1-3facc98f03e5')
     def test_volume_list_with_detail_param_offset_and_limit(self):
         # Return the list of volumes details based on offset and limit set.
         # get all volumes list
-        response, all_vol_list = self.client.list_volumes_with_detail()
+        all_vol_list = self.client.list_volumes_with_detail()
         params = {'offset': 1, 'limit': 1}
-        resp, fetched_vol_list = \
-            self.client.list_volumes_with_detail(params=params)
-        self.assertEqual(200, resp.status)
+        fetched_vol_list = self.client.list_volumes_with_detail(params=params)
 
         # Validating length of the fetched volumes
         self.assertEqual(len(fetched_vol_list), params['limit'],
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index f0f9879..89f6817 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -15,10 +15,11 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -27,74 +28,87 @@
 class VolumesNegativeTest(base.BaseV2ComputeTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(VolumesNegativeTest, cls).resource_setup()
-        cls.client = cls.volumes_extensions_client
+    def skip_checks(cls):
+        super(VolumesNegativeTest, cls).skip_checks()
         if not CONF.service_available.cinder:
             skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
+    @classmethod
+    def setup_clients(cls):
+        super(VolumesNegativeTest, cls).setup_clients()
+        cls.client = cls.volumes_extensions_client
+
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c03ea686-905b-41a2-8748-9635154b7c57')
     def test_volume_get_nonexistent_volume_id(self):
         # Negative: Should not be able to get details of nonexistent volume
         # Creating a nonexistent volume id
         # Trying to GET a non existent volume
-        self.assertRaises(exceptions.NotFound, self.client.get_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.get_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('54a34226-d910-4b00-9ef8-8683e6c55846')
     def test_volume_delete_nonexistent_volume_id(self):
         # Negative: Should not be able to delete nonexistent Volume
         # Creating nonexistent volume id
         # Trying to DELETE a non existent volume
-        self.assertRaises(exceptions.NotFound, self.client.delete_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5125ae14-152b-40a7-b3c5-eae15e9022ef')
     def test_create_volume_with_invalid_size(self):
         # Negative: Should not be able to create volume with invalid size
         # in request
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_volume,
                           size='#$%', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('131cb3a1-75cc-4d40-b4c3-1317f64719b0')
     def test_create_volume_with_out_passing_size(self):
         # Negative: Should not be able to create volume without passing size
         # in request
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_volume,
                           size='', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8cce995e-0a83-479a-b94d-e1e40b8a09d1')
     def test_create_volume_with_size_zero(self):
         # Negative: Should not be able to create volume with size zero
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_volume,
                           size='0', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f01904f2-e975-4915-98ce-cb5fa27bde4f')
     def test_get_invalid_volume_id(self):
         # Negative: Should not be able to get volume with invalid id
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_volume, '#$%%&^&^')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('62bab09a-4c03-4617-8cca-8572bc94af9b')
     def test_get_volume_without_passing_volume_id(self):
         # Negative: Should not be able to get volume when empty ID is passed
-        self.assertRaises(exceptions.NotFound, self.client.get_volume, '')
+        self.assertRaises(lib_exc.NotFound, self.client.get_volume, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('62972737-124b-4513-b6cf-2f019f178494')
     def test_delete_invalid_volume_id(self):
         # Negative: Should not be able to delete volume when invalid ID is
         # passed
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_volume, '!@#$%^&*()')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0d1417c5-4ae8-4c2c-adc5-5f0b864253e5')
     def test_delete_volume_without_passing_volume_id(self):
         # Negative: Should not be able to delete volume when empty ID is passed
-        self.assertRaises(exceptions.NotFound, self.client.delete_volume, '')
+        self.assertRaises(lib_exc.NotFound, self.client.delete_volume, '')
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index 2ec1017..5992921 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -12,8 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest import config
-from tempest import exceptions
 import tempest.test
 
 
@@ -21,16 +22,26 @@
 
 
 class BaseDataProcessingTest(tempest.test.BaseTestCase):
-    _interface = 'json'
+
+    @classmethod
+    def skip_checks(cls):
+        super(BaseDataProcessingTest, cls).skip_checks()
+        if not CONF.service_available.sahara:
+            raise cls.skipException('Sahara support is required')
+
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseDataProcessingTest, cls).setup_credentials()
+        cls.os = cls.get_client_manager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseDataProcessingTest, cls).setup_clients()
+        cls.client = cls.os.data_processing_client
 
     @classmethod
     def resource_setup(cls):
         super(BaseDataProcessingTest, cls).resource_setup()
-        if not CONF.service_available.sahara:
-            raise cls.skipException('Sahara support is required')
-
-        cls.os = cls.get_client_manager()
-        cls.client = cls.os.data_processing_client
 
         cls.flavor_ref = CONF.compute.flavor_ref
 
@@ -63,7 +74,7 @@
         for resource_id in resource_id_list:
             try:
                 method(resource_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 # ignore errors while auto removing created resource
                 pass
 
@@ -77,12 +88,12 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        _, resp_body = cls.client.create_node_group_template(name, plugin_name,
-                                                             hadoop_version,
-                                                             node_processes,
-                                                             flavor_id,
-                                                             node_configs,
-                                                             **kwargs)
+        resp_body = cls.client.create_node_group_template(name, plugin_name,
+                                                          hadoop_version,
+                                                          node_processes,
+                                                          flavor_id,
+                                                          node_configs,
+                                                          **kwargs)
         # store id of created node group template
         cls._node_group_templates.append(resp_body['id'])
 
@@ -97,11 +108,11 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        _, resp_body = cls.client.create_cluster_template(name, plugin_name,
-                                                          hadoop_version,
-                                                          node_groups,
-                                                          cluster_configs,
-                                                          **kwargs)
+        resp_body = cls.client.create_cluster_template(name, plugin_name,
+                                                       hadoop_version,
+                                                       node_groups,
+                                                       cluster_configs,
+                                                       **kwargs)
         # store id of created cluster template
         cls._cluster_templates.append(resp_body['id'])
 
@@ -115,7 +126,7 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        _, resp_body = cls.client.create_data_source(name, type, url, **kwargs)
+        resp_body = cls.client.create_data_source(name, type, url, **kwargs)
         # store id of created data source
         cls._data_sources.append(resp_body['id'])
 
@@ -128,7 +139,7 @@
         It returns created object. All resources created in this method will
         be automatically removed in tearDownClass method.
         """
-        _, resp_body = cls.client.create_job_binary_internal(name, data)
+        resp_body = cls.client.create_job_binary_internal(name, data)
         # store id of created job binary internal
         cls._job_binary_internals.append(resp_body['id'])
 
@@ -142,7 +153,7 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        _, resp_body = cls.client.create_job_binary(name, url, extra, **kwargs)
+        resp_body = cls.client.create_job_binary(name, url, extra, **kwargs)
         # store id of created job binary
         cls._job_binaries.append(resp_body['id'])
 
@@ -156,8 +167,8 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        _, resp_body = cls.client.create_job(name,
-                                             job_type, mains, libs, **kwargs)
+        resp_body = cls.client.create_job(name,
+                                          job_type, mains, libs, **kwargs)
         # store id of created job
         cls._jobs.append(resp_body['id'])
 
diff --git a/tempest/api/data_processing/test_cluster_templates.py b/tempest/api/data_processing/test_cluster_templates.py
index 537f90c..af7cbaf 100644
--- a/tempest/api/data_processing/test_cluster_templates.py
+++ b/tempest/api/data_processing/test_cluster_templates.py
@@ -112,29 +112,33 @@
         return resp_body['id'], template_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3525f1f1-3f9c-407d-891a-a996237e728b')
     def test_cluster_template_create(self):
         self._create_cluster_template()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7a161882-e430-4840-a1c6-1d928201fab2')
     def test_cluster_template_list(self):
         template_info = self._create_cluster_template()
 
         # check for cluster template in list
-        _, templates = self.client.list_cluster_templates()
+        templates = self.client.list_cluster_templates()
         templates_info = [(template['id'], template['name'])
                           for template in templates]
         self.assertIn(template_info, templates_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2b75fe22-f731-4b0f-84f1-89ab25f86637')
     def test_cluster_template_get(self):
         template_id, template_name = self._create_cluster_template()
 
         # check cluster template fetch by id
-        _, template = self.client.get_cluster_template(template_id)
+        template = self.client.get_cluster_template(template_id)
         self.assertEqual(template_name, template['name'])
         self.assertDictContainsSubset(self.cluster_template, template)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ff1fd989-171c-4dd7-91fd-9fbc71b09675')
     def test_cluster_template_delete(self):
         template_id, _ = self._create_cluster_template()
 
diff --git a/tempest/api/data_processing/test_data_sources.py b/tempest/api/data_processing/test_data_sources.py
index 3650751..dd16b2f 100644
--- a/tempest/api/data_processing/test_data_sources.py
+++ b/tempest/api/data_processing/test_data_sources.py
@@ -68,33 +68,37 @@
 
     def _list_data_sources(self, source_info):
         # check for data source in list
-        _, sources = self.client.list_data_sources()
+        sources = self.client.list_data_sources()
         sources_info = [(source['id'], source['name']) for source in sources]
         self.assertIn(source_info, sources_info)
 
     def _get_data_source(self, source_id, source_name, source_body):
         # check data source fetch by id
-        _, source = self.client.get_data_source(source_id)
+        source = self.client.get_data_source(source_id)
         self.assertEqual(source_name, source['name'])
         self.assertDictContainsSubset(source_body, source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9e0e836d-c372-4fca-91b7-b66c3e9646c8')
     def test_swift_data_source_create(self):
         self._create_data_source(self.swift_data_source_with_creds)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3cb87a4a-0534-4b97-9edc-8bbc822b68a0')
     def test_swift_data_source_list(self):
         source_info = (
             self._create_data_source(self.swift_data_source_with_creds))
         self._list_data_sources(source_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fc07409b-6477-4cb3-9168-e633c46b227f')
     def test_swift_data_source_get(self):
         source_id, source_name = (
             self._create_data_source(self.swift_data_source_with_creds))
         self._get_data_source(source_id, source_name, self.swift_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('df53669c-0cd1-4cf7-b408-4cf215d8beb8')
     def test_swift_data_source_delete(self):
         source_id, _ = (
             self._create_data_source(self.swift_data_source_with_creds))
@@ -103,15 +107,18 @@
         self.client.delete_data_source(source_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('88505d52-db01-4229-8f1d-a1137da5fe2d')
     def test_local_hdfs_data_source_create(self):
         self._create_data_source(self.local_hdfs_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('81d7d42a-d7f6-4d9b-b38c-0801a4dfe3c2')
     def test_local_hdfs_data_source_list(self):
         source_info = self._create_data_source(self.local_hdfs_data_source)
         self._list_data_sources(source_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ec0144c6-db1e-4169-bb06-7abae14a8443')
     def test_local_hdfs_data_source_get(self):
         source_id, source_name = (
             self._create_data_source(self.local_hdfs_data_source))
@@ -119,6 +126,7 @@
             source_id, source_name, self.local_hdfs_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e398308b-4230-4f86-ba10-9b0b60a59c8d')
     def test_local_hdfs_data_source_delete(self):
         source_id, _ = self._create_data_source(self.local_hdfs_data_source)
 
@@ -126,15 +134,18 @@
         self.client.delete_data_source(source_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bfd91128-e642-4d95-a973-3e536962180c')
     def test_external_hdfs_data_source_create(self):
         self._create_data_source(self.external_hdfs_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('92e2be72-f7ab-499d-ae01-fb9943c90d8e')
     def test_external_hdfs_data_source_list(self):
         source_info = self._create_data_source(self.external_hdfs_data_source)
         self._list_data_sources(source_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a31edb1b-6bc6-4f42-871f-70cd243184ac')
     def test_external_hdfs_data_source_get(self):
         source_id, source_name = (
             self._create_data_source(self.external_hdfs_data_source))
@@ -142,6 +153,7 @@
             source_id, source_name, self.external_hdfs_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('295924cd-a085-4b45-aea8-0707cdb2da7e')
     def test_external_hdfs_data_source_delete(self):
         source_id, _ = self._create_data_source(self.external_hdfs_data_source)
 
diff --git a/tempest/api/data_processing/test_job_binaries.py b/tempest/api/data_processing/test_job_binaries.py
index d006991..fb21270 100644
--- a/tempest/api/data_processing/test_job_binaries.py
+++ b/tempest/api/data_processing/test_job_binaries.py
@@ -70,29 +70,33 @@
         return resp_body['id'], binary_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c00d43f8-4360-45f8-b280-af1a201b12d3')
     def test_swift_job_binary_create(self):
         self._create_job_binary(self.swift_job_binary_with_extra)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f8809352-e79d-4748-9359-ce1efce89f2a')
     def test_swift_job_binary_list(self):
         binary_info = self._create_job_binary(self.swift_job_binary_with_extra)
 
         # check for job binary in list
-        _, binaries = self.client.list_job_binaries()
+        binaries = self.client.list_job_binaries()
         binaries_info = [(binary['id'], binary['name']) for binary in binaries]
         self.assertIn(binary_info, binaries_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2d4a670f-e8f1-413c-b5ac-50c1bfe9e1b1')
     def test_swift_job_binary_get(self):
         binary_id, binary_name = (
             self._create_job_binary(self.swift_job_binary_with_extra))
 
         # check job binary fetch by id
-        _, binary = self.client.get_job_binary(binary_id)
+        binary = self.client.get_job_binary(binary_id)
         self.assertEqual(binary_name, binary['name'])
         self.assertDictContainsSubset(self.swift_job_binary, binary)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9b0e8f38-04f3-4616-b399-cfa7eb2677ed')
     def test_swift_job_binary_delete(self):
         binary_id, _ = (
             self._create_job_binary(self.swift_job_binary_with_extra))
@@ -101,29 +105,33 @@
         self.client.delete_job_binary(binary_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('63662f6d-8291-407e-a6fc-f654522ebab6')
     def test_internal_db_job_binary_create(self):
         self._create_job_binary(self.internal_db_job_binary)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('38731e7b-6d9d-4ffa-8fd1-193c453e88b1')
     def test_internal_db_job_binary_list(self):
         binary_info = self._create_job_binary(self.internal_db_job_binary)
 
         # check for job binary in list
-        _, binaries = self.client.list_job_binaries()
+        binaries = self.client.list_job_binaries()
         binaries_info = [(binary['id'], binary['name']) for binary in binaries]
         self.assertIn(binary_info, binaries_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1b32199b-c3f5-43e1-a37a-3797e57b7066')
     def test_internal_db_job_binary_get(self):
         binary_id, binary_name = (
             self._create_job_binary(self.internal_db_job_binary))
 
         # check job binary fetch by id
-        _, binary = self.client.get_job_binary(binary_id)
+        binary = self.client.get_job_binary(binary_id)
         self.assertEqual(binary_name, binary['name'])
         self.assertDictContainsSubset(self.internal_db_job_binary, binary)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3c42b0c3-3e03-46a5-adf0-df0650271a4e')
     def test_internal_db_job_binary_delete(self):
         binary_id, _ = self._create_job_binary(self.internal_db_job_binary)
 
@@ -131,6 +139,7 @@
         self.client.delete_job_binary(binary_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d5d47659-7e2c-4ea7-b292-5b3e559e8587')
     def test_job_binary_get_data(self):
         binary_id, _ = self._create_job_binary(self.internal_db_job_binary)
 
diff --git a/tempest/api/data_processing/test_job_binary_internals.py b/tempest/api/data_processing/test_job_binary_internals.py
index 7e99867..3d76ebe 100644
--- a/tempest/api/data_processing/test_job_binary_internals.py
+++ b/tempest/api/data_processing/test_job_binary_internals.py
@@ -47,27 +47,31 @@
         return resp_body['id'], binary_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('249c4dc2-946f-4939-83e6-212ddb6ea0be')
     def test_job_binary_internal_create(self):
         self._create_job_binary_internal()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1e3c2ecd-5673-499d-babe-4fe2fcdf64ee')
     def test_job_binary_internal_list(self):
         binary_info = self._create_job_binary_internal()
 
         # check for job binary internal in list
-        _, binaries = self.client.list_job_binary_internals()
+        binaries = self.client.list_job_binary_internals()
         binaries_info = [(binary['id'], binary['name']) for binary in binaries]
         self.assertIn(binary_info, binaries_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a2046a53-386c-43ab-be35-df54b19db776')
     def test_job_binary_internal_get(self):
         binary_id, binary_name = self._create_job_binary_internal()
 
         # check job binary internal fetch by id
-        _, binary = self.client.get_job_binary_internal(binary_id)
+        binary = self.client.get_job_binary_internal(binary_id)
         self.assertEqual(binary_name, binary['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b3568c33-4eed-40d5-aae4-6ff3b2ac58f5')
     def test_job_binary_internal_delete(self):
         binary_id, _ = self._create_job_binary_internal()
 
@@ -75,6 +79,7 @@
         self.client.delete_job_binary_internal(binary_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8871f2b0-5782-4d66-9bb9-6f95bcb839ea')
     def test_job_binary_internal_get_data(self):
         binary_id, _ = self._create_job_binary_internal()
 
diff --git a/tempest/api/data_processing/test_jobs.py b/tempest/api/data_processing/test_jobs.py
index 5af2eef..83eb54d 100644
--- a/tempest/api/data_processing/test_jobs.py
+++ b/tempest/api/data_processing/test_jobs.py
@@ -61,27 +61,31 @@
         return resp_body['id'], job_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8cf785ca-adf4-473d-8281-fb9a5efa3073')
     def test_job_create(self):
         self._create_job()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('41e253fe-b02a-41a0-b186-5ff1f0463ba3')
     def test_job_list(self):
         job_info = self._create_job()
 
         # check for job in list
-        _, jobs = self.client.list_jobs()
+        jobs = self.client.list_jobs()
         jobs_info = [(job['id'], job['name']) for job in jobs]
         self.assertIn(job_info, jobs_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3faf17fa-bc94-4a60-b1c3-79e53674c16c')
     def test_job_get(self):
         job_id, job_name = self._create_job()
 
         # check job fetch by id
-        _, job = self.client.get_job(job_id)
+        job = self.client.get_job(job_id)
         self.assertEqual(job_name, job['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('dff85e62-7dda-4ad8-b1ee-850adecb0c6e')
     def test_job_delete(self):
         job_id, _ = self._create_job()
 
diff --git a/tempest/api/data_processing/test_node_group_templates.py b/tempest/api/data_processing/test_node_group_templates.py
index f3f59fc..9d84218 100644
--- a/tempest/api/data_processing/test_node_group_templates.py
+++ b/tempest/api/data_processing/test_node_group_templates.py
@@ -61,29 +61,33 @@
         return resp_body['id'], template_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('63164051-e46d-4387-9741-302ef4791cbd')
     def test_node_group_template_create(self):
         self._create_node_group_template()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('eb39801d-2612-45e5-88b1-b5d70b329185')
     def test_node_group_template_list(self):
         template_info = self._create_node_group_template()
 
         # check for node group template in list
-        _, templates = self.client.list_node_group_templates()
+        templates = self.client.list_node_group_templates()
         templates_info = [(template['id'], template['name'])
                           for template in templates]
         self.assertIn(template_info, templates_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6ee31539-a708-466f-9c26-4093ce09a836')
     def test_node_group_template_get(self):
         template_id, template_name = self._create_node_group_template()
 
         # check node group template fetch by id
-        _, template = self.client.get_node_group_template(template_id)
+        template = self.client.get_node_group_template(template_id)
         self.assertEqual(template_name, template['name'])
         self.assertDictContainsSubset(self.node_group_template, template)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f4f5cb82-708d-4031-81c4-b0618a706a2f')
     def test_node_group_template_delete(self):
         template_id, _ = self._create_node_group_template()
 
diff --git a/tempest/api/data_processing/test_plugins.py b/tempest/api/data_processing/test_plugins.py
index 4b4ec48..92a5bd0 100644
--- a/tempest/api/data_processing/test_plugins.py
+++ b/tempest/api/data_processing/test_plugins.py
@@ -25,7 +25,7 @@
 
         It ensures main plugins availability.
         """
-        _, plugins = self.client.list_plugins()
+        plugins = self.client.list_plugins()
         plugins_names = [plugin['name'] for plugin in plugins]
         for enabled_plugin in CONF.data_processing_feature_enabled.plugins:
             self.assertIn(enabled_plugin, plugins_names)
@@ -33,18 +33,20 @@
         return plugins_names
 
     @test.attr(type='smoke')
+    @test.idempotent_id('01a005a3-426c-4c0b-9617-d09475403e09')
     def test_plugin_list(self):
         self._list_all_plugin_names()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('53cf6487-2cfb-4a6f-8671-97c542c6e901')
     def test_plugin_get(self):
         for plugin_name in self._list_all_plugin_names():
-            _, plugin = self.client.get_plugin(plugin_name)
+            plugin = self.client.get_plugin(plugin_name)
             self.assertEqual(plugin_name, plugin['name'])
 
             for plugin_version in plugin['versions']:
-                _, detailed_plugin = self.client.get_plugin(plugin_name,
-                                                            plugin_version)
+                detailed_plugin = self.client.get_plugin(plugin_name,
+                                                         plugin_version)
                 self.assertEqual(plugin_name, detailed_plugin['name'])
 
                 # check that required image tags contains name and version
diff --git a/tempest/api/database/base.py b/tempest/api/database/base.py
index dd4c684..31c5d2a 100644
--- a/tempest/api/database/base.py
+++ b/tempest/api/database/base.py
@@ -24,22 +24,30 @@
 class BaseDatabaseTest(tempest.test.BaseTestCase):
     """Base test case class for all Database API tests."""
 
-    _interface = 'json'
-
     @classmethod
-    def resource_setup(cls):
-        super(BaseDatabaseTest, cls).resource_setup()
+    def skip_checks(cls):
+        super(BaseDatabaseTest, cls).skip_checks()
         if not CONF.service_available.trove:
             skip_msg = ("%s skipped as trove is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
-        cls.catalog_type = CONF.database.catalog_type
-        cls.db_flavor_ref = CONF.database.db_flavor_ref
-        cls.db_current_version = CONF.database.db_current_version
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseDatabaseTest, cls).setup_credentials()
+        cls.os = cls.get_client_manager()
 
-        os = cls.get_client_manager()
-        cls.os = os
+    @classmethod
+    def setup_clients(cls):
+        super(BaseDatabaseTest, cls).setup_clients()
         cls.database_flavors_client = cls.os.database_flavors_client
         cls.os_flavors_client = cls.os.flavors_client
         cls.database_limits_client = cls.os.database_limits_client
         cls.database_versions_client = cls.os.database_versions_client
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaseDatabaseTest, cls).resource_setup()
+
+        cls.catalog_type = CONF.database.catalog_type
+        cls.db_flavor_ref = CONF.database.db_flavor_ref
+        cls.db_current_version = CONF.database.db_current_version
diff --git a/tempest/api/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
index ed172e9..eeb472c 100644
--- a/tempest/api/database/flavors/test_flavors.py
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -20,24 +20,26 @@
 class DatabaseFlavorsTest(base.BaseDatabaseTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(DatabaseFlavorsTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(DatabaseFlavorsTest, cls).setup_clients()
         cls.client = cls.database_flavors_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c94b825e-0132-4686-8049-8a4a2bc09525')
     def test_get_db_flavor(self):
         # The expected flavor details should be returned
-        _, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+        flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
         self.assertEqual(self.db_flavor_ref, str(flavor['id']))
         self.assertIn('ram', flavor)
         self.assertIn('links', flavor)
         self.assertIn('name', flavor)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('685025d6-0cec-4673-8a8d-995cb8e0d3bb')
     def test_list_db_flavors(self):
-        _, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+        flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
         # List of all flavors should contain the expected flavor
-        _, flavors = self.client.list_db_flavors()
+        flavors = self.client.list_db_flavors()
         self.assertIn(flavor, flavors)
 
     def _check_values(self, names, db_flavor, os_flavor, in_db=True):
@@ -52,15 +54,16 @@
                 self.assertNotIn(name, db_flavor)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('afb2667f-4ec2-4925-bcb7-313fdcffb80d')
     @test.services('compute')
     def test_compare_db_flavors_with_os(self):
-        _, db_flavors = self.client.list_db_flavors()
+        db_flavors = self.client.list_db_flavors()
         os_flavors = self.os_flavors_client.list_flavors_with_detail()
         self.assertEqual(len(os_flavors), len(db_flavors),
                          "OS flavors %s do not match DB flavors %s" %
                          (os_flavors, db_flavors))
         for os_flavor in os_flavors:
-            _, db_flavor =\
+            db_flavor =\
                 self.client.get_db_flavor_details(os_flavor['id'])
             self._check_values(['id', 'name', 'ram'], db_flavor, os_flavor)
             self._check_values(['disk', 'vcpus', 'swap'], db_flavor, os_flavor,
diff --git a/tempest/api/database/flavors/test_flavors_negative.py b/tempest/api/database/flavors/test_flavors_negative.py
index 9f14cce..1b2c88c 100644
--- a/tempest/api/database/flavors/test_flavors_negative.py
+++ b/tempest/api/database/flavors/test_flavors_negative.py
@@ -13,20 +13,22 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.database import base
-from tempest import exceptions
 from tempest import test
 
 
 class DatabaseFlavorsNegativeTest(base.BaseDatabaseTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(DatabaseFlavorsNegativeTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(DatabaseFlavorsNegativeTest, cls).setup_clients()
         cls.client = cls.database_flavors_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f8e7b721-373f-4a64-8e9c-5327e975af3e')
     def test_get_non_existent_db_flavor(self):
         # flavor details are not returned for non-existent flavors
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_db_flavor_details, -1)
diff --git a/tempest/api/database/limits/test_limits.py b/tempest/api/database/limits/test_limits.py
index 30d0a77..7d2fbac 100644
--- a/tempest/api/database/limits/test_limits.py
+++ b/tempest/api/database/limits/test_limits.py
@@ -18,7 +18,6 @@
 
 
 class DatabaseLimitsTest(base.BaseDatabaseTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -26,10 +25,11 @@
         cls.client = cls.database_limits_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('73024538-f316-4829-b3e9-b459290e137a')
     def test_absolute_limits(self):
         # Test to verify if all absolute limit paramaters are
         # present when verb is ABSOLUTE
-        _, limits = self.client.list_db_limits()
+        limits = self.client.list_db_limits()
         expected_abs_limits = ['max_backups', 'max_volumes',
                                'max_instances', 'verb']
         absolute_limit = [l for l in limits
diff --git a/tempest/api/database/versions/test_versions.py b/tempest/api/database/versions/test_versions.py
index 80fcecf..55d8246 100644
--- a/tempest/api/database/versions/test_versions.py
+++ b/tempest/api/database/versions/test_versions.py
@@ -18,16 +18,16 @@
 
 
 class DatabaseVersionsTest(base.BaseDatabaseTest):
-    _interface = 'json'
 
     @classmethod
-    def resource_setup(cls):
-        super(DatabaseVersionsTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(DatabaseVersionsTest, cls).setup_clients()
         cls.client = cls.database_versions_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6952cd77-90cd-4dca-bb60-8e2c797940cf')
     def test_list_db_versions(self):
-        _, versions = self.client.list_db_versions()
+        versions = self.client.list_db_versions()
         self.assertTrue(len(versions) > 0, "No database versions found")
         # List of all versions should contain the current version, and there
         # should only be one 'current' version
diff --git a/tempest/services/identity/json/__init__.py b/tempest/api/identity/admin/v2/__init__.py
similarity index 100%
copy from tempest/services/identity/json/__init__.py
copy to tempest/api/identity/admin/v2/__init__.py
diff --git a/tempest/api/identity/admin/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
similarity index 91%
rename from tempest/api/identity/admin/test_roles.py
rename to tempest/api/identity/admin/v2/test_roles.py
index c6c7dc3..3eb6c08 100644
--- a/tempest/api/identity/admin/test_roles.py
+++ b/tempest/api/identity/admin/v2/test_roles.py
@@ -21,7 +21,6 @@
 
 
 class RolesTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -47,6 +46,7 @@
         self.assertTrue(found, "assigned role was not in list")
 
     @test.attr(type='gate')
+    @test.idempotent_id('75d9593f-50b7-4fcf-bd64-e3fb4a278e23')
     def test_list_roles(self):
         """Return a list of all roles."""
         body = self.client.list_roles()
@@ -55,6 +55,7 @@
         self.assertEqual(len(found), len(self.data.roles))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c62d909d-6c21-48c0-ae40-0a0760e6db5e')
     def test_role_create_delete(self):
         """Role should be created, verified, and deleted."""
         role_name = data_utils.rand_name(name='role-test-')
@@ -72,6 +73,7 @@
         self.assertFalse(any(found))
 
     @test.attr(type='gate')
+    @test.idempotent_id('db6870bd-a6ed-43be-a9b1-2f10a5c9994f')
     def test_get_role_by_id(self):
         """Get a role by its id."""
         self.data.setup_test_role()
@@ -82,6 +84,7 @@
         self.assertEqual(role_name, body['name'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('0146f675-ffbd-4208-b3a4-60eb628dbc5e')
     def test_assign_user_role(self):
         """Assign a role to a user on a tenant."""
         (user, tenant, role) = self._get_role_params()
@@ -90,6 +93,7 @@
         self.assert_role_in_role_list(role, roles)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f0b9292c-d3ba-4082-aa6c-440489beef69')
     def test_remove_user_role(self):
         """Remove a role assigned to a user on a tenant."""
         (user, tenant, role) = self._get_role_params()
@@ -99,6 +103,7 @@
                                      user_role['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('262e1e3e-ed71-4edd-a0e5-d64e83d66d05')
     def test_list_user_roles(self):
         """List roles assigned to a user on tenant."""
         (user, tenant, role) = self._get_role_params()
diff --git a/tempest/api/identity/admin/test_roles_negative.py b/tempest/api/identity/admin/v2/test_roles_negative.py
similarity index 78%
rename from tempest/api/identity/admin/test_roles_negative.py
rename to tempest/api/identity/admin/v2/test_roles_negative.py
index 58f726a..be9fb52 100644
--- a/tempest/api/identity/admin/test_roles_negative.py
+++ b/tempest/api/identity/admin/v2/test_roles_negative.py
@@ -13,16 +13,15 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import uuid
 
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class RolesNegativeTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     def _get_role_params(self):
         self.data.setup_test_user()
@@ -33,62 +32,70 @@
         return (user, tenant, role)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d5d5f1df-f8ca-4de0-b2ef-259c1cc67025')
     def test_list_roles_by_unauthorized_user(self):
         # Non-administrator user should not be able to list roles
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_roles)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('11a3c7da-df6c-40c2-abc2-badd682edf9f')
     def test_list_roles_request_without_token(self):
         # Request to list roles without a valid token should fail
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.list_roles)
+        self.assertRaises(lib_exc.Unauthorized, self.client.list_roles)
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c0b89e56-accc-4c73-85f8-9c0f866104c1')
     def test_role_create_blank_name(self):
         # Should not be able to create a role with a blank name
-        self.assertRaises(exceptions.BadRequest, self.client.create_role, '')
+        self.assertRaises(lib_exc.BadRequest, self.client.create_role, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('585c8998-a8a4-4641-a5dd-abef7a8ced00')
     def test_create_role_by_unauthorized_user(self):
         # Non-administrator user should not be able to create role
         role_name = data_utils.rand_name(name='role-')
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.create_role, role_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a7edd17a-e34a-4aab-8bb7-fa6f498645b8')
     def test_create_role_request_without_token(self):
         # Request to create role without a valid token should fail
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
         role_name = data_utils.rand_name(name='role-')
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.client.create_role, role_name)
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c0cde2c8-81c1-4bb0-8fe2-cf615a3547a8')
     def test_role_create_duplicate(self):
         # Role names should be unique
         role_name = data_utils.rand_name(name='role-dup-')
         body = self.client.create_role(role_name)
         role1_id = body.get('id')
         self.addCleanup(self.client.delete_role, role1_id)
-        self.assertRaises(exceptions.Conflict, self.client.create_role,
+        self.assertRaises(lib_exc.Conflict, self.client.create_role,
                           role_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('15347635-b5b1-4a87-a280-deb2bd6d865e')
     def test_delete_role_by_unauthorized_user(self):
         # Non-administrator user should not be able to delete role
         role_name = data_utils.rand_name(name='role-')
         body = self.client.create_role(role_name)
         self.data.roles.append(body)
         role_id = body.get('id')
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.delete_role, role_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('44b60b20-70de-4dac-beaf-a3fc2650a16b')
     def test_delete_role_request_without_token(self):
         # Request to delete role without a valid token should fail
         role_name = data_utils.rand_name(name='role-')
@@ -97,63 +104,70 @@
         role_id = body.get('id')
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.client.delete_role,
                           role_id)
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('38373691-8551-453a-b074-4260ad8298ef')
     def test_delete_role_non_existent(self):
         # Attempt to delete a non existent role should fail
         non_existent_role = str(uuid.uuid4().hex)
-        self.assertRaises(exceptions.NotFound, self.client.delete_role,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_role,
                           non_existent_role)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('391df5cf-3ec3-46c9-bbe5-5cb58dd4dc41')
     def test_assign_user_role_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to
         # assign a role to user
         (user, tenant, role) = self._get_role_params()
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.assign_user_role,
                           tenant['id'], user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f0d2683c-5603-4aee-95d7-21420e87cfd8')
     def test_assign_user_role_request_without_token(self):
         # Request to assign a role to a user without a valid token
         (user, tenant, role) = self._get_role_params()
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.client.assign_user_role, tenant['id'],
                           user['id'], role['id'])
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('99b297f6-2b5d-47c7-97a9-8b6bb4f91042')
     def test_assign_user_role_for_non_existent_role(self):
         # Attempt to assign a non existent role to user should fail
         (user, tenant, role) = self._get_role_params()
         non_existent_role = str(uuid.uuid4().hex)
-        self.assertRaises(exceptions.NotFound, self.client.assign_user_role,
+        self.assertRaises(lib_exc.NotFound, self.client.assign_user_role,
                           tenant['id'], user['id'], non_existent_role)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b2285aaa-9e76-4704-93a9-7a8acd0a6c8f')
     def test_assign_user_role_for_non_existent_tenant(self):
         # Attempt to assign a role on a non existent tenant should fail
         (user, tenant, role) = self._get_role_params()
         non_existent_tenant = str(uuid.uuid4().hex)
-        self.assertRaises(exceptions.NotFound, self.client.assign_user_role,
+        self.assertRaises(lib_exc.NotFound, self.client.assign_user_role,
                           non_existent_tenant, user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5c3132cd-c4c8-4402-b5ea-71eb44e97793')
     def test_assign_duplicate_user_role(self):
         # Duplicate user role should not get assigned
         (user, tenant, role) = self._get_role_params()
         self.client.assign_user_role(tenant['id'], user['id'], role['id'])
-        self.assertRaises(exceptions.Conflict, self.client.assign_user_role,
+        self.assertRaises(lib_exc.Conflict, self.client.assign_user_role,
                           tenant['id'], user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d0537987-0977-448f-a435-904c15de7298')
     def test_remove_user_role_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to
         # remove a user's role
@@ -161,11 +175,12 @@
         self.client.assign_user_role(tenant['id'],
                                      user['id'],
                                      role['id'])
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.remove_user_role,
                           tenant['id'], user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('cac81cf4-c1d2-47dc-90d3-f2b7eb572286')
     def test_remove_user_role_request_without_token(self):
         # Request to remove a user's role without a valid token
         (user, tenant, role) = self._get_role_params()
@@ -174,12 +189,13 @@
                                      role['id'])
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.client.remove_user_role, tenant['id'],
                           user['id'], role['id'])
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ab32d759-cd16-41f1-a86e-44405fa9f6d2')
     def test_remove_user_role_non_existent_role(self):
         # Attempt to delete a non existent role from a user should fail
         (user, tenant, role) = self._get_role_params()
@@ -187,10 +203,11 @@
                                      user['id'],
                                      role['id'])
         non_existent_role = str(uuid.uuid4().hex)
-        self.assertRaises(exceptions.NotFound, self.client.remove_user_role,
+        self.assertRaises(lib_exc.NotFound, self.client.remove_user_role,
                           tenant['id'], user['id'], non_existent_role)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('67a679ec-03dd-4551-bbfc-d1c93284f023')
     def test_remove_user_role_non_existent_tenant(self):
         # Attempt to remove a role from a non existent tenant should fail
         (user, tenant, role) = self._get_role_params()
@@ -198,27 +215,29 @@
                                      user['id'],
                                      role['id'])
         non_existent_tenant = str(uuid.uuid4().hex)
-        self.assertRaises(exceptions.NotFound, self.client.remove_user_role,
+        self.assertRaises(lib_exc.NotFound, self.client.remove_user_role,
                           non_existent_tenant, user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7391ab4c-06f3-477a-a64a-c8e55ce89837')
     def test_list_user_roles_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to list
         # a user's roles
         (user, tenant, role) = self._get_role_params()
         self.client.assign_user_role(tenant['id'], user['id'], role['id'])
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_user_roles, tenant['id'],
                           user['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('682adfb2-fd5f-4b0a-a9ca-322e9bebb907')
     def test_list_user_roles_request_without_token(self):
         # Request to list user's roles without a valid token should fail
         (user, tenant, role) = self._get_role_params()
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
         try:
-            self.assertRaises(exceptions.Unauthorized,
+            self.assertRaises(lib_exc.Unauthorized,
                               self.client.list_user_roles, tenant['id'],
                               user['id'])
         finally:
diff --git a/tempest/api/identity/admin/test_services.py b/tempest/api/identity/admin/v2/test_services.py
similarity index 92%
rename from tempest/api/identity/admin/test_services.py
rename to tempest/api/identity/admin/v2/test_services.py
index 03d6e35..035f5f8 100644
--- a/tempest/api/identity/admin/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -14,24 +14,24 @@
 #    under the License.
 
 from six import moves
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class ServicesTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     def _del_service(self, service_id):
         # Deleting the service created in this method
         self.client.delete_service(service_id)
         # Checking whether service is deleted successfully
-        self.assertRaises(exceptions.NotFound, self.client.get_service,
+        self.assertRaises(lib_exc.NotFound, self.client.get_service,
                           service_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('84521085-c6e6-491c-9a08-ec9f70f90110')
     def test_create_get_delete_service(self):
         # GET Service
         # Creating a Service
@@ -64,6 +64,7 @@
                          service_data['description'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('5d3252c8-e555-494b-a6c8-e11d7335da42')
     def test_create_service_without_description(self):
         # Create a service only with name and type
         name = data_utils.rand_name('service-')
@@ -77,6 +78,7 @@
         self.assertEqual(type, service['type'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('34ea6489-012d-4a86-9038-1287cadd5eca')
     def test_list_services(self):
         # Create, List, Verify and Delete Services
         services = []
diff --git a/tempest/api/identity/admin/test_tenant_negative.py b/tempest/api/identity/admin/v2/test_tenant_negative.py
similarity index 75%
rename from tempest/api/identity/admin/test_tenant_negative.py
rename to tempest/api/identity/admin/v2/test_tenant_negative.py
index 75f0152..8346a3d 100644
--- a/tempest/api/identity/admin/test_tenant_negative.py
+++ b/tempest/api/identity/admin/v2/test_tenant_negative.py
@@ -13,41 +13,44 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import uuid
 
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class TenantsNegativeTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ca9bb202-63dd-4240-8a07-8ef9c19c04bb')
     def test_list_tenants_by_unauthorized_user(self):
         # Non-administrator user should not be able to list tenants
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_tenants)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('df33926c-1c96-4d8d-a762-79cc6b0c3cf4')
     def test_list_tenant_request_without_token(self):
         # Request to list tenants without a valid token should fail
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.list_tenants)
+        self.assertRaises(lib_exc.Unauthorized, self.client.list_tenants)
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('162ba316-f18b-4987-8c0c-fd9140cd63ed')
     def test_tenant_delete_by_unauthorized_user(self):
         # Non-administrator user should not be able to delete a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
         tenant = self.client.create_tenant(tenant_name)
         self.data.tenants.append(tenant)
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.delete_tenant, tenant['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e450db62-2e9d-418f-893a-54772d6386b1')
     def test_tenant_delete_request_without_token(self):
         # Request to delete a tenant without a valid token should fail
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -55,17 +58,19 @@
         self.data.tenants.append(tenant)
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.delete_tenant,
+        self.assertRaises(lib_exc.Unauthorized, self.client.delete_tenant,
                           tenant['id'])
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c9a2aed-6e3c-467a-8f5c-89da9d1b516b')
     def test_delete_non_existent_tenant(self):
         # Attempt to delete a non existent tenant should fail
-        self.assertRaises(exceptions.NotFound, self.client.delete_tenant,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_tenant,
                           str(uuid.uuid4().hex))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('af16f44b-a849-46cb-9f13-a751c388f739')
     def test_tenant_create_duplicate(self):
         # Tenant names should be unique
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -76,55 +81,62 @@
 
         self.addCleanup(self.client.delete_tenant, tenant1_id)
         self.addCleanup(self.data.tenants.remove, tenant)
-        self.assertRaises(exceptions.Conflict, self.client.create_tenant,
+        self.assertRaises(lib_exc.Conflict, self.client.create_tenant,
                           tenant_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d26b278a-6389-4702-8d6e-5980d80137e0')
     def test_create_tenant_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to create a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.create_tenant, tenant_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a3ee9d7e-6920-4dd5-9321-d4b2b7f0a638')
     def test_create_tenant_request_without_token(self):
         # Create tenant request without a token should not be authorized
         tenant_name = data_utils.rand_name(name='tenant-')
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.create_tenant,
+        self.assertRaises(lib_exc.Unauthorized, self.client.create_tenant,
                           tenant_name)
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5a2e4ca9-b0c0-486c-9c48-64a94fba2395')
     def test_create_tenant_with_empty_name(self):
         # Tenant name should not be empty
-        self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_tenant,
                           name='')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('2ff18d1e-dfe3-4359-9dc3-abf582c196b9')
     def test_create_tenants_name_length_over_64(self):
         # Tenant name length should not be greater than 64 characters
         tenant_name = 'a' * 65
-        self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_tenant,
                           tenant_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bd20dc2a-9557-4db7-b755-f48d952ad706')
     def test_update_non_existent_tenant(self):
         # Attempt to update a non existent tenant should fail
-        self.assertRaises(exceptions.NotFound, self.client.update_tenant,
+        self.assertRaises(lib_exc.NotFound, self.client.update_tenant,
                           str(uuid.uuid4().hex))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('41704dc5-c5f7-4f79-abfa-76e6fedc570b')
     def test_tenant_update_by_unauthorized_user(self):
         # Non-administrator user should not be able to update a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
         tenant = self.client.create_tenant(tenant_name)
         self.data.tenants.append(tenant)
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.update_tenant, tenant['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7a421573-72c7-4c22-a98e-ce539219c657')
     def test_tenant_update_request_without_token(self):
         # Request to update a tenant without a valid token should fail
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -132,6 +144,6 @@
         self.data.tenants.append(tenant)
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.update_tenant,
+        self.assertRaises(lib_exc.Unauthorized, self.client.update_tenant,
                           tenant['id'])
         self.client.auth_provider.clear_auth()
diff --git a/tempest/api/identity/admin/test_tenants.py b/tempest/api/identity/admin/v2/test_tenants.py
similarity index 93%
rename from tempest/api/identity/admin/test_tenants.py
rename to tempest/api/identity/admin/v2/test_tenants.py
index 549e952..3f1c3cd 100644
--- a/tempest/api/identity/admin/test_tenants.py
+++ b/tempest/api/identity/admin/v2/test_tenants.py
@@ -21,9 +21,9 @@
 
 
 class TenantsTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
+    @test.idempotent_id('16c6e05c-6112-4b0e-b83f-5e43f221b6b0')
     def test_tenant_list_delete(self):
         # Create several tenants and delete them
         tenants = []
@@ -46,6 +46,7 @@
         self.assertFalse(any(found), 'Tenants failed to delete')
 
     @test.attr(type='gate')
+    @test.idempotent_id('d25e9f24-1310-4d29-b61b-d91299c21d6d')
     def test_tenant_create_with_description(self):
         # Create tenant with a description
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -66,6 +67,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('670bdddc-1cd7-41c7-b8e2-751cfb67df50')
     def test_tenant_create_enabled(self):
         # Create a tenant that is enabled
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -82,6 +84,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3be22093-b30f-499d-b772-38340e5e16fb')
     def test_tenant_create_not_enabled(self):
         # Create a tenant that is not enabled
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -100,6 +103,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('781f2266-d128-47f3-8bdb-f70970add238')
     def test_tenant_update_name(self):
         # Update name attribute of a tenant
         t_name1 = data_utils.rand_name(name='tenant-')
@@ -126,6 +130,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('859fcfe1-3a03-41ef-86f9-b19a47d1cd87')
     def test_tenant_update_desc(self):
         # Update description attribute of a tenant
         t_name = data_utils.rand_name(name='tenant-')
@@ -153,6 +158,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('8fc8981f-f12d-4c66-9972-2bdcf2bc2e1a')
     def test_tenant_update_enable(self):
         # Update the enabled attribute of a tenant
         t_name = data_utils.rand_name(name='tenant-')
diff --git a/tempest/api/identity/admin/test_tokens.py b/tempest/api/identity/admin/v2/test_tokens.py
similarity index 96%
rename from tempest/api/identity/admin/test_tokens.py
rename to tempest/api/identity/admin/v2/test_tokens.py
index bec621c..751f5fd 100644
--- a/tempest/api/identity/admin/test_tokens.py
+++ b/tempest/api/identity/admin/v2/test_tokens.py
@@ -19,9 +19,9 @@
 
 
 class TokensTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
+    @test.idempotent_id('453ad4d5-e486-4b2f-be72-cffc8149e586')
     def test_create_get_delete_token(self):
         # get a token by username and password
         user_name = data_utils.rand_name(name='user-')
@@ -52,6 +52,7 @@
         self.client.delete_token(token_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('25ba82ee-8a32-4ceb-8f50-8b8c71e8765e')
     def test_rescope_token(self):
         """An unscoped token can be requested, that token can be used to
            request a scoped token.
diff --git a/tempest/api/identity/admin/test_users.py b/tempest/api/identity/admin/v2/test_users.py
similarity index 93%
rename from tempest/api/identity/admin/test_users.py
rename to tempest/api/identity/admin/v2/test_users.py
index 25312e8..fc64f67 100644
--- a/tempest/api/identity/admin/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -21,7 +21,6 @@
 
 
 class UsersTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -31,6 +30,7 @@
         cls.alt_email = cls.alt_user + '@testmail.tm'
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2d55a71e-da1d-4b43-9c03-d269fd93d905')
     def test_create_user(self):
         # Create a user
         self.data.setup_test_tenant()
@@ -41,6 +41,7 @@
         self.assertEqual(self.alt_user, user['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('89d9fdb8-15c2-4304-a429-48715d0af33d')
     def test_create_user_with_enabled(self):
         # Create a user with enabled : False
         self.data.setup_test_tenant()
@@ -54,6 +55,7 @@
         self.assertEqual(self.alt_email, user['email'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('39d05857-e8a5-4ed4-ba83-0b52d3ab97ee')
     def test_update_user(self):
         # Test case to check if updating of user attributes is successful.
         test_user = data_utils.rand_name('test_user_')
@@ -80,6 +82,7 @@
         self.assertEqual('false', str(updated_user['enabled']).lower())
 
     @test.attr(type='smoke')
+    @test.idempotent_id('29ed26f4-a74e-4425-9a85-fdb49fa269d2')
     def test_delete_user(self):
         # Delete a user
         test_user = data_utils.rand_name('test_user_')
@@ -90,6 +93,7 @@
         self.client.delete_user(user['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aca696c3-d645-4f45-b728-63646045beb1')
     def test_user_authentication(self):
         # Valid user's token is authenticated
         self.data.setup_test_user()
@@ -102,6 +106,7 @@
                                self.data.test_tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5d1fa498-4c2d-4732-a8fe-2b054598cfdd')
     def test_authentication_request_without_token(self):
         # Request for token authentication with a valid token in header
         self.data.setup_test_user()
@@ -118,6 +123,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a149c02e-e5e0-4b89-809e-7e8faf33ccda')
     def test_get_users(self):
         # Get a list of users and find the test user
         self.data.setup_test_user()
@@ -127,6 +133,7 @@
                         "Could not find %s" % self.data.test_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6e317209-383a-4bed-9f10-075b7c82c79a')
     def test_list_users_for_tenant(self):
         # Return a list of all users for a tenant
         self.data.setup_test_tenant()
@@ -157,6 +164,7 @@
                          ', '.join(m_user for m_user in missing_users))
 
     @test.attr(type='gate')
+    @test.idempotent_id('a8b54974-40e1-41c0-b812-50fc90827971')
     def test_list_users_with_roles_for_tenant(self):
         # Return list of users on tenant when roles are assigned to users
         self.data.setup_test_user()
@@ -192,6 +200,7 @@
                          ', '.join(m_user for m_user in missing_users))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1aeb25ac-6ec5-4d8b-97cb-7ac3567a989f')
     def test_update_user_password(self):
         # Test case to check if updating of user password is successful.
         self.data.setup_test_user()
diff --git a/tempest/api/identity/admin/test_users_negative.py b/tempest/api/identity/admin/v2/test_users_negative.py
similarity index 76%
rename from tempest/api/identity/admin/test_users_negative.py
rename to tempest/api/identity/admin/v2/test_users_negative.py
index c039da6..f40621b 100644
--- a/tempest/api/identity/admin/test_users_negative.py
+++ b/tempest/api/identity/admin/v2/test_users_negative.py
@@ -13,16 +13,15 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import uuid
 
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class UsersNegativeTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -32,46 +31,52 @@
         cls.alt_email = cls.alt_user + '@testmail.tm'
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('60a1f5fa-5744-4cdf-82bf-60b7de2d29a4')
     def test_create_user_by_unauthorized_user(self):
         # Non-administrator should not be authorized to create a user
         self.data.setup_test_tenant()
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.create_user, self.alt_user,
                           self.alt_password, self.data.tenant['id'],
                           self.alt_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d80d0c2f-4514-4d1e-806d-0930dfc5a187')
     def test_create_user_with_empty_name(self):
         # User with an empty name should not be created
         self.data.setup_test_tenant()
-        self.assertRaises(exceptions.BadRequest, self.client.create_user, '',
+        self.assertRaises(lib_exc.BadRequest, self.client.create_user, '',
                           self.alt_password, self.data.tenant['id'],
                           self.alt_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7704b4f3-3b75-4b82-87cc-931d41c8f780')
     def test_create_user_with_name_length_over_255(self):
         # Length of user name filed should be restricted to 255 characters
         self.data.setup_test_tenant()
-        self.assertRaises(exceptions.BadRequest, self.client.create_user,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_user,
                           'a' * 256, self.alt_password,
                           self.data.tenant['id'], self.alt_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('57ae8558-120c-4723-9308-3751474e7ecf')
     def test_create_user_with_duplicate_name(self):
         # Duplicate user should not be created
         self.data.setup_test_user()
-        self.assertRaises(exceptions.Conflict, self.client.create_user,
+        self.assertRaises(lib_exc.Conflict, self.client.create_user,
                           self.data.test_user, self.data.test_password,
                           self.data.tenant['id'], self.data.test_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0132cc22-7c4f-42e1-9e50-ac6aad31d59a')
     def test_create_user_for_non_existent_tenant(self):
         # Attempt to create a user in a non-existent tenant should fail
-        self.assertRaises(exceptions.NotFound, self.client.create_user,
+        self.assertRaises(lib_exc.NotFound, self.client.create_user,
                           self.alt_user, self.alt_password, '49ffgg99999',
                           self.alt_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('55bbb103-d1ae-437b-989b-bcdf8175c1f4')
     def test_create_user_request_without_a_token(self):
         # Request to create a user without a valid token should fail
         self.data.setup_test_tenant()
@@ -79,7 +84,7 @@
         token = self.client.auth_provider.get_token()
         # Delete the token from database
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.create_user,
+        self.assertRaises(lib_exc.Unauthorized, self.client.create_user,
                           self.alt_user, self.alt_password,
                           self.data.tenant['id'], self.alt_email)
 
@@ -87,24 +92,27 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('23a2f3da-4a1a-41da-abdd-632328a861ad')
     def test_create_user_with_enabled_non_bool(self):
         # Attempt to create a user with valid enabled para should fail
         self.data.setup_test_tenant()
         name = data_utils.rand_name('test_user_')
-        self.assertRaises(exceptions.BadRequest, self.client.create_user,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_user,
                           name, self.alt_password,
                           self.data.tenant['id'],
                           self.alt_email, enabled=3)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3d07e294-27a0-4144-b780-a2a1bf6fee19')
     def test_update_user_for_non_existent_user(self):
         # Attempt to update a user non-existent user should fail
         user_name = data_utils.rand_name('user-')
         non_existent_id = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound, self.client.update_user,
+        self.assertRaises(lib_exc.NotFound, self.client.update_user,
                           non_existent_id, name=user_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3cc2a64b-83aa-4b02-88f0-d6ab737c4466')
     def test_update_user_request_without_a_token(self):
         # Request to update a user without a valid token should fail
 
@@ -112,34 +120,38 @@
         token = self.client.auth_provider.get_token()
         # Delete the token from database
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.update_user,
+        self.assertRaises(lib_exc.Unauthorized, self.client.update_user,
                           self.alt_user)
 
         # Unset the token to allow further tests to generate a new token
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('424868d5-18a7-43e1-8903-a64f95ee3aac')
     def test_update_user_by_unauthorized_user(self):
         # Non-administrator should not be authorized to update user
         self.data.setup_test_tenant()
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.update_user, self.alt_user)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d45195d5-33ed-41b9-a452-7d0d6a00f6e9')
     def test_delete_users_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to delete a user
         self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.delete_user,
                           self.data.user['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7cc82f7e-9998-4f89-abae-23df36495867')
     def test_delete_non_existent_user(self):
         # Attempt to delete a non-existent user should fail
-        self.assertRaises(exceptions.NotFound, self.client.delete_user,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_user,
                           'junk12345123')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('57fe1df8-0aa7-46c0-ae9f-c2e785c7504a')
     def test_delete_user_request_without_a_token(self):
         # Request to delete a user without a valid token should fail
 
@@ -147,73 +159,81 @@
         token = self.client.auth_provider.get_token()
         # Delete the token from database
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.delete_user,
+        self.assertRaises(lib_exc.Unauthorized, self.client.delete_user,
                           self.alt_user)
 
         # Unset the token to allow further tests to generate a new token
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('593a4981-f6d4-460a-99a1-57a78bf20829')
     def test_authentication_for_disabled_user(self):
         # Disabled user's token should not get authenticated
         self.data.setup_test_user()
         self.disable_user(self.data.test_user)
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+        self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
                           self.data.test_user,
                           self.data.test_password,
                           self.data.test_tenant)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('440a7a8d-9328-4b7b-83e0-d717010495e4')
     def test_authentication_when_tenant_is_disabled(self):
         # User's token for a disabled tenant should not be authenticated
         self.data.setup_test_user()
         self.disable_tenant(self.data.test_tenant)
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+        self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
                           self.data.test_user,
                           self.data.test_password,
                           self.data.test_tenant)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('921f1ad6-7907-40b8-853f-637e7ee52178')
     def test_authentication_with_invalid_tenant(self):
         # User's token for an invalid tenant should not be authenticated
         self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+        self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
                           self.data.test_user,
                           self.data.test_password,
                           'junktenant1234')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bde9aecd-3b1c-4079-858f-beb5deaa5b5e')
     def test_authentication_with_invalid_username(self):
         # Non-existent user's token should not get authenticated
         self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+        self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
                           'junkuser123', self.data.test_password,
                           self.data.test_tenant)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d5308b33-3574-43c3-8d87-1c090c5e1eca')
     def test_authentication_with_invalid_password(self):
         # User's token with invalid password should not be authenticated
         self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+        self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
                           self.data.test_user, 'junkpass1234',
                           self.data.test_tenant)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('284192ce-fb7c-4909-a63b-9a502e0ddd11')
     def test_get_users_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to get user list
         self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.get_users)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a73591ec-1903-4ffe-be42-282b39fefc9d')
     def test_get_users_request_without_token(self):
         # Request to get list of users without a valid token should fail
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.get_users)
+        self.assertRaises(lib_exc.Unauthorized, self.client.get_users)
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f5d39046-fc5f-425c-b29e-bac2632da28e')
     def test_list_users_with_invalid_tenant(self):
         # Should not be able to return a list of all
         # users for a non-existent tenant
@@ -225,5 +245,5 @@
         invalid_id.append('!@#()$%^&*?<>{}[]')
         # List the users with invalid tenant id
         for invalid in invalid_id:
-            self.assertRaises(exceptions.NotFound,
+            self.assertRaises(lib_exc.NotFound,
                               self.client.list_users_for_tenant, invalid)
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 6f2f6d4..6fbd544 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -19,7 +19,6 @@
 
 
 class CredentialsTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -52,6 +51,7 @@
         self.creds_client.delete_credential(cred_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7cd59bf9-bda4-4c72-9467-d21cab278355')
     def test_credentials_create_get_update_delete(self):
         keys = [data_utils.rand_name('Access-'),
                 data_utils.rand_name('Secret-')]
@@ -84,6 +84,7 @@
                              get_body['blob'][value2])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('13202c00-0021-42a1-88d4-81b44d448aab')
     def test_credentials_list_delete(self):
         created_cred_ids = list()
         fetched_cred_ids = list()
diff --git a/tempest/api/identity/admin/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index bd29cb8..f74b30d 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -14,16 +14,19 @@
 from tempest import auth
 from tempest import clients
 from tempest.common.utils import data_utils
+from tempest import config
+from tempest import manager
 from tempest import test
 
+CONF = config.CONF
+
 
 class TestDefaultProjectId (base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     @classmethod
-    def resource_setup(cls):
+    def setup_credentials(cls):
         cls.set_network_resources()
-        super(TestDefaultProjectId, cls).resource_setup()
+        super(TestDefaultProjectId, cls).setup_credentials()
 
     def _delete_domain(self, domain_id):
         # It is necessary to disable the domain before deleting,
@@ -32,6 +35,7 @@
         self.client.delete_domain(domain_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d6110661-6a71-49a7-a453-b5e26640ff6d')
     def test_default_project_id(self):
         # create a domain
         dom_name = data_utils.rand_name('dom')
@@ -72,10 +76,9 @@
         creds = auth.KeystoneV3Credentials(username=user_name,
                                            password=user_name,
                                            domain_name=dom_name)
-        auth_provider = auth.KeystoneV3AuthProvider(creds)
+        auth_provider = manager.get_auth_provider(creds)
         creds = auth_provider.fill_credentials()
-        admin_client = clients.Manager(interface=self._interface,
-                                       credentials=creds)
+        admin_client = clients.Manager(credentials=creds)
 
         # verify the user's token and see that it is scoped to the project
         token, auth_data = admin_client.auth_provider.get_auth()
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index c1bc705..0441f6d 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -20,7 +20,6 @@
 
 
 class DomainsTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     def _delete_domain(self, domain_id):
         # It is necessary to disable the domain before deleting,
@@ -29,6 +28,7 @@
         self.client.delete_domain(domain_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8cf516ef-2114-48f1-907b-d32726c734d4')
     def test_list_domains(self):
         # Test to list domains
         domain_ids = list()
@@ -48,6 +48,7 @@
         self.assertEqual(0, len(missing_doms))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f2f5b44a-82e8-4dad-8084-0661ea3b18cf')
     def test_create_update_delete_domain(self):
         d_name = data_utils.rand_name('domain-')
         d_desc = data_utils.rand_name('domain-desc-')
@@ -62,10 +63,7 @@
         self.assertIsNotNone(domain['id'])
         self.assertEqual(d_name, domain['name'])
         self.assertEqual(d_desc, domain['description'])
-        if self._interface == "json":
-            self.assertEqual(True, domain['enabled'])
-        else:
-            self.assertEqual('true', str(domain['enabled']).lower())
+        self.assertEqual(True, domain['enabled'])
         new_desc = data_utils.rand_name('new-desc-')
         new_name = data_utils.rand_name('new-name-')
 
@@ -85,3 +83,16 @@
         self.assertEqual(new_name, fetched_domain['name'])
         self.assertEqual(new_desc, fetched_domain['description'])
         self.assertEqual('true', str(fetched_domain['enabled']).lower())
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('036df86e-bb5d-42c0-a7c2-66b9db3a6046')
+    def test_create_domain_with_disabled_status(self):
+        # Create domain with enabled status as false
+        d_name = data_utils.rand_name('domain-')
+        d_desc = data_utils.rand_name('domain-desc-')
+        domain = self.client.create_domain(
+            d_name, description=d_desc, enabled=False)
+        self.addCleanup(self.client.delete_domain, domain['id'])
+        self.assertEqual(d_name, domain['name'])
+        self.assertFalse(domain['enabled'])
+        self.assertEqual(d_desc, domain['description'])
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index eed0eb5..4a11c95 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -19,13 +19,16 @@
 
 
 class EndPointsTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
+
+    @classmethod
+    def setup_clients(cls):
+        super(EndPointsTestJSON, cls).setup_clients()
+        cls.identity_client = cls.client
+        cls.client = cls.endpoints_client
 
     @classmethod
     def resource_setup(cls):
         super(EndPointsTestJSON, cls).resource_setup()
-        cls.identity_client = cls.client
-        cls.client = cls.endpoints_client
         cls.service_ids = list()
         s_name = data_utils.rand_name('service-')
         s_type = data_utils.rand_name('type--')
@@ -54,6 +57,7 @@
         super(EndPointsTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('c19ecf90-240e-4e23-9966-21cee3f6a618')
     def test_list_endpoints(self):
         # Get a list of endpoints
         fetched_endpoints = self.client.list_endpoints()
@@ -65,6 +69,7 @@
                          ', '.join(str(e) for e in missing_endpoints))
 
     @test.attr(type='gate')
+    @test.idempotent_id('0e2446d2-c1fd-461b-a729-b9e73e3e3b37')
     def test_create_list_delete_endpoint(self):
         region = data_utils.rand_name('region')
         url = data_utils.rand_url()
@@ -88,6 +93,7 @@
         self.assertNotIn(endpoint['id'], fetched_endpoints_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('37e8f15e-ee7c-4657-a1e7-f6b61e375eff')
     def test_update_endpoint(self):
         # Creating an endpoint so as to check update endpoint
         # with new values
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index 9da0a57..06c8e77 100644
--- a/tempest/api/identity/admin/v3/test_endpoints_negative.py
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -14,21 +14,24 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class EndpointsNegativeTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
+
+    @classmethod
+    def setup_clients(cls):
+        super(EndpointsNegativeTestJSON, cls).setup_clients()
+        cls.identity_client = cls.client
+        cls.client = cls.endpoints_client
 
     @classmethod
     def resource_setup(cls):
         super(EndpointsNegativeTestJSON, cls).resource_setup()
-        cls.identity_client = cls.client
-        cls.client = cls.endpoints_client
         cls.service_ids = list()
         s_name = data_utils.rand_name('service-')
         s_type = data_utils.rand_name('type--')
@@ -46,22 +49,24 @@
         super(EndpointsNegativeTestJSON, cls).resource_cleanup()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ac6c137e-4d3d-448f-8c83-4f13d0942651')
     def test_create_with_enabled_False(self):
         # Enabled should be a boolean, not a string like 'False'
         interface = 'public'
         url = data_utils.rand_url()
         region = data_utils.rand_name('region')
-        self.assertRaises(exceptions.BadRequest, self.client.create_endpoint,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_endpoint,
                           self.service_id, interface, url, region=region,
                           force_enabled='False')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c43181e-0627-484a-8c79-923e8a59598b')
     def test_create_with_enabled_True(self):
         # Enabled should be a boolean, not a string like 'True'
         interface = 'public'
         url = data_utils.rand_url()
         region = data_utils.rand_name('region')
-        self.assertRaises(exceptions.BadRequest, self.client.create_endpoint,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_endpoint,
                           self.service_id, interface, url, region=region,
                           force_enabled='True')
 
@@ -76,15 +81,17 @@
                                         url1, region=region1, enabled=True))
         self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
 
-        self.assertRaises(exceptions.BadRequest, self.client.update_endpoint,
+        self.assertRaises(lib_exc.BadRequest, self.client.update_endpoint,
                           endpoint_for_update['id'], force_enabled=enabled)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('65e41f32-5eb7-498f-a92a-a6ccacf7439a')
     def test_update_with_enabled_False(self):
         # Enabled should be a boolean, not a string like 'False'
         self._assert_update_raises_bad_request('False')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('faba3587-f066-4757-a48e-b4a3f01803bb')
     def test_update_with_enabled_True(self):
         # Enabled should be a boolean, not a string like 'True'
         self._assert_update_raises_bad_request('True')
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index d8c7063..2c70a7c 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -19,13 +19,9 @@
 
 
 class GroupsV3TestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
-
-    @classmethod
-    def resource_setup(cls):
-        super(GroupsV3TestJSON, cls).resource_setup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2e80343b-6c81-4ac3-88c7-452f3e9d5129')
     def test_group_create_update_get(self):
         name = data_utils.rand_name('Group')
         description = data_utils.rand_name('Description')
@@ -49,6 +45,7 @@
         self.assertEqual(new_desc, new_group['description'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1598521a-2f36-4606-8df9-30772bd51339')
     def test_group_users_add_list_delete(self):
         name = data_utils.rand_name('Group')
         group = self.client.create_group(name)
@@ -73,6 +70,7 @@
         self.assertEqual(len(group_users), 0)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('64573281-d26a-4a52-b899-503cb0f4e4ec')
     def test_list_user_groups(self):
         # create a user
         user = self.client.create_user(
@@ -93,6 +91,7 @@
         self.assertEqual(2, len(user_groups))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cc9a57a5-a9ed-4f2d-a29f-4f979a06ec71')
     def test_list_groups(self):
         # Test to list groups
         group_ids = list()
diff --git a/tempest/api/identity/admin/v3/test_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
index c0187f9..ca30b6e 100644
--- a/tempest/api/identity/admin/v3/test_list_projects.py
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -19,7 +19,6 @@
 
 
 class ListProjectsTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -39,6 +38,7 @@
         cls.project_ids.append(cls.p2['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('1d830662-22ad-427c-8c3e-4ec854b0af44')
     def test_projects_list(self):
         # List projects
         list_projects = self.client.list_projects()
@@ -48,17 +48,20 @@
             self.assertIn(get_project, list_projects)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fab13f3c-f6a6-4b9f-829b-d32fd44fdf10')
     def test_list_projects_with_domains(self):
         # List projects with domain
         self._list_projects_with_params(
             {'domain_id': self.data.domain['id']}, 'domain_id')
 
     @test.attr(type='gate')
+    @test.idempotent_id('0fe7a334-675a-4509-b00e-1c4b95d5dae8')
     def test_list_projects_with_enabled(self):
         # List the projects with enabled
         self._list_projects_with_params({'enabled': False}, 'enabled')
 
     @test.attr(type='gate')
+    @test.idempotent_id('fa178524-4e6d-4925-907c-7ab9f42c7e26')
     def test_list_projects_with_name(self):
         # List projects with name
         self._list_projects_with_params({'name': self.p1_name}, 'name')
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index e728867..1407f38 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -19,7 +19,6 @@
 
 
 class UsersV3TestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     def _list_users_with_params(self, params, key, expected, not_expected):
         # Helper method to list users filtered with params and
@@ -52,6 +51,7 @@
         cls.data.v3_users.append(cls.non_domain_enabled_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('08f9aabb-dcfe-41d0-8172-82b5fa0bd73d')
     def test_list_user_domains(self):
         # List users with domain
         params = {'domain_id': self.data.domain['id']}
@@ -60,6 +60,7 @@
                                      self.non_domain_enabled_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('bff8bf2f-9408-4ef5-b63a-753c8c2124eb')
     def test_list_users_with_not_enabled(self):
         # List the users with not enabled
         params = {'enabled': False}
@@ -68,6 +69,7 @@
                                      self.domain_enabled_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('c285bb37-7325-4c02-bff3-3da5d946d683')
     def test_list_users_with_name(self):
         # List users with name
         params = {'name': self.domain_enabled_user['name']}
@@ -76,6 +78,7 @@
                                      self.non_domain_enabled_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('b30d4651-a2ea-4666-8551-0c0e49692635')
     def test_list_users(self):
         # List users
         body = self.client.get_users()
@@ -87,6 +90,7 @@
                          ', '.join(m_user for m_user in missing_users))
 
     @test.attr(type='gate')
+    @test.idempotent_id('b4baa3ae-ac00-4b4e-9e27-80deaad7771f')
     def test_get_user(self):
         # Get a user detail
         user = self.client.get_user(self.data.v3_users[0]['id'])
diff --git a/tempest/api/identity/admin/v3/test_policies.py b/tempest/api/identity/admin/v3/test_policies.py
index 23df13d..900c26e 100644
--- a/tempest/api/identity/admin/v3/test_policies.py
+++ b/tempest/api/identity/admin/v3/test_policies.py
@@ -19,12 +19,12 @@
 
 
 class PoliciesTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     def _delete_policy(self, policy_id):
         self.policy_client.delete_policy(policy_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1a0ad286-2d06-4123-ab0d-728893a76201')
     def test_list_policies(self):
         # Test to list policies
         policy_ids = list()
@@ -45,6 +45,7 @@
         self.assertEqual(0, len(missing_pols))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e544703a-2f03-4cf2-9b0f-350782fdb0d3')
     def test_create_update_delete_policy(self):
         # Test to update policy
         blob = data_utils.rand_name('BlobName-')
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index 2cf6458..052cf0e 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -19,9 +19,9 @@
 
 
 class ProjectsTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
+    @test.idempotent_id('0ecf465c-0dc4-4532-ab53-91ffeb74d12d')
     def test_project_create_with_description(self):
         # Create project with a description
         project_name = data_utils.rand_name('project-')
@@ -39,6 +39,7 @@
                          'to be set')
 
     @test.attr(type='gate')
+    @test.idempotent_id('5f50fe07-8166-430b-a882-3b2ee0abe26f')
     def test_project_create_with_domain(self):
         # Create project with a domain
         self.data.setup_test_domain()
@@ -54,6 +55,7 @@
         self.assertEqual(self.data.domain['id'], body['domain_id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('1f66dc76-50cc-4741-a200-af984509e480')
     def test_project_create_enabled(self):
         # Create a project that is enabled
         project_name = data_utils.rand_name('project-')
@@ -68,6 +70,7 @@
         self.assertTrue(en2, 'Enable should be True in lookup')
 
     @test.attr(type='gate')
+    @test.idempotent_id('78f96a9c-e0e0-4ee6-a3ba-fbf6dfd03207')
     def test_project_create_not_enabled(self):
         # Create a project that is not enabled
         project_name = data_utils.rand_name('project-')
@@ -83,6 +86,7 @@
                          'Enable should be False in lookup')
 
     @test.attr(type='gate')
+    @test.idempotent_id('f608f368-048c-496b-ad63-d286c26dab6b')
     def test_project_update_name(self):
         # Update name attribute of a project
         p_name1 = data_utils.rand_name('project-')
@@ -104,6 +108,7 @@
         self.assertEqual(resp2_name, resp3_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f138b715-255e-4a7d-871d-351e1ef2e153')
     def test_project_update_desc(self):
         # Update description attribute of a project
         p_name = data_utils.rand_name('project-')
@@ -127,6 +132,7 @@
         self.assertEqual(resp2_desc, resp3_desc)
 
     @test.attr(type='gate')
+    @test.idempotent_id('b6b25683-c97f-474d-a595-55d410b68100')
     def test_project_update_enable(self):
         # Update the enabled attribute of a project
         p_name = data_utils.rand_name('project-')
@@ -150,6 +156,7 @@
         self.assertEqual(resp2_en, resp3_en)
 
     @test.attr(type='gate')
+    @test.idempotent_id('59398d4a-5dc5-4f86-9a4c-c26cc804d6c6')
     def test_associate_user_to_project(self):
         # Associate a user to a project
         # Create a Project
diff --git a/tempest/api/identity/admin/v3/test_projects_negative.py b/tempest/api/identity/admin/v3/test_projects_negative.py
index f5e832b..bc92900 100644
--- a/tempest/api/identity/admin/v3/test_projects_negative.py
+++ b/tempest/api/identity/admin/v3/test_projects_negative.py
@@ -13,22 +13,24 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class ProjectsNegativeTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('24c49279-45dd-4155-887a-cb738c2385aa')
     def test_list_projects_by_unauthorized_user(self):
         # Non-admin user should not be able to list projects
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_projects)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('874c3e84-d174-4348-a16b-8c01f599561b')
     def test_project_create_duplicate(self):
         # Project names should be unique
         project_name = data_utils.rand_name('project-dup-')
@@ -36,41 +38,46 @@
         self.data.projects.append(project)
 
         self.assertRaises(
-            exceptions.Conflict, self.client.create_project, project_name)
+            lib_exc.Conflict, self.client.create_project, project_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8fba9de2-3e1f-4e77-812a-60cb68f8df13')
     def test_create_project_by_unauthorized_user(self):
         # Non-admin user should not be authorized to create a project
         project_name = data_utils.rand_name('project-')
         self.assertRaises(
-            exceptions.Unauthorized, self.non_admin_client.create_project,
+            lib_exc.Unauthorized, self.non_admin_client.create_project,
             project_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7828db17-95e5-475b-9432-9a51b4aa79a9')
     def test_create_project_with_empty_name(self):
         # Project name should not be empty
-        self.assertRaises(exceptions.BadRequest, self.client.create_project,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_project,
                           name='')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('502b6ceb-b0c8-4422-bf53-f08fdb21e2f0')
     def test_create_projects_name_length_over_64(self):
         # Project name length should not be greater than 64 characters
         project_name = 'a' * 65
-        self.assertRaises(exceptions.BadRequest, self.client.create_project,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_project,
                           project_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8d68c012-89e0-4394-8d6b-ccd7196def97')
     def test_project_delete_by_unauthorized_user(self):
         # Non-admin user should not be able to delete a project
         project_name = data_utils.rand_name('project-')
         project = self.client.create_project(project_name)
         self.data.projects.append(project)
         self.assertRaises(
-            exceptions.Unauthorized, self.non_admin_client.delete_project,
+            lib_exc.Unauthorized, self.non_admin_client.delete_project,
             project['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7965b581-60c1-43b7-8169-95d4ab7fc6fb')
     def test_delete_non_existent_project(self):
         # Attempt to delete a non existent project should fail
-        self.assertRaises(exceptions.NotFound, self.client.delete_project,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_project,
                           data_utils.rand_uuid_hex())
diff --git a/tempest/api/identity/admin/v3/test_regions.py b/tempest/api/identity/admin/v3/test_regions.py
index c71cbf3..bf3c12e 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -13,20 +13,24 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class RegionsTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
+
+    @classmethod
+    def setup_clients(cls):
+        super(RegionsTestJSON, cls).setup_clients()
+        cls.client = cls.region_client
 
     @classmethod
     def resource_setup(cls):
         super(RegionsTestJSON, cls).resource_setup()
         cls.setup_regions = list()
-        cls.client = cls.region_client
         for i in range(2):
             r_description = data_utils.rand_name('description-')
             region = cls.client.create_region(r_description)
@@ -40,10 +44,11 @@
 
     def _delete_region(self, region_id):
         self.client.delete_region(region_id)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_region, region_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('56186092-82e4-43f2-b954-91013218ba42')
     def test_create_update_get_delete_region(self):
         r_description = data_utils.rand_name('description-')
         region = self.client.create_region(
@@ -68,6 +73,7 @@
                          region['parent_region_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2c12c5b5-efcf-4aa5-90c5-bff1ab0cdbe2')
     def test_create_region_with_specific_id(self):
         # Create a region with a specific id
         r_region_id = data_utils.rand_uuid()
@@ -80,6 +86,7 @@
         self.assertEqual(r_description, region['description'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d180bf99-544a-445c-ad0d-0c0d27663796')
     def test_list_regions(self):
         # Get a list of regions
         fetched_regions = self.client.list_regions()
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index b8b309d..24da22a 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -19,7 +19,6 @@
 
 
 class RolesV3TestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -67,6 +66,7 @@
         self.assertIn(role_id, fetched_role_ids)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('18afc6c0-46cf-4911-824e-9989cc056c3a')
     def test_role_create_update_get_list(self):
         r_name = data_utils.rand_name('Role-')
         role = self.client.create_role(r_name)
@@ -89,6 +89,7 @@
         self.assertIn(role['id'], [r['id'] for r in roles])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c6b80012-fe4a-498b-9ce8-eb391c05169f')
     def test_grant_list_revoke_role_to_user_on_project(self):
         self.client.assign_user_role_on_project(
             self.project['id'], self.user_body['id'], self.role['id'])
@@ -106,6 +107,7 @@
             self.project['id'], self.user_body['id'], self.role['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6c9a2940-3625-43a3-ac02-5dcec62ef3bd')
     def test_grant_list_revoke_role_to_user_on_domain(self):
         self.client.assign_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
@@ -123,6 +125,7 @@
             self.domain['id'], self.user_body['id'], self.role['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cbf11737-1904-4690-9613-97bcbb3df1c4')
     def test_grant_list_revoke_role_to_group_on_project(self):
         # Grant role to group on project
         self.client.assign_group_role_on_project(
@@ -140,9 +143,11 @@
         self.client.add_group_user(self.group_body['id'], self.user_body['id'])
         self.addCleanup(self.client.delete_group_user,
                         self.group_body['id'], self.user_body['id'])
-        body = self.token.auth(self.user_body['id'], self.u_password,
-                               self.project['name'],
-                               domain=self.domain['name'])
+        body = self.token.auth(user=self.user_body['id'],
+                               password=self.u_password,
+                               user_domain=self.domain['name'],
+                               project=self.project['name'],
+                               project_domain=self.domain['name'])
         roles = body['token']['roles']
         self.assertEqual(len(roles), 1)
         self.assertEqual(roles[0]['id'], self.role['id'])
@@ -151,6 +156,7 @@
             self.project['id'], self.group_body['id'], self.role['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4bf8a70b-e785-413a-ad53-9f91ce02faa7')
     def test_grant_list_revoke_role_to_group_on_domain(self):
         self.client.assign_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
@@ -168,6 +174,7 @@
             self.domain['id'], self.group_body['id'], self.role['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('f5654bcc-08c4-4f71-88fe-05d64e06de94')
     def test_list_roles(self):
         # Return a list of all roles
         body = self.client.list_roles()
diff --git a/tempest/api/identity/admin/v3/test_services.py b/tempest/api/identity/admin/v3/test_services.py
index 9e45b50..bf5cc3e 100644
--- a/tempest/api/identity/admin/v3/test_services.py
+++ b/tempest/api/identity/admin/v3/test_services.py
@@ -13,23 +13,24 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class ServicesTestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     def _del_service(self, service_id):
         # Used for deleting the services created in this class
         self.service_client.delete_service(service_id)
         # Checking whether service is deleted successfully
-        self.assertRaises(exceptions.NotFound, self.service_client.get_service,
+        self.assertRaises(lib_exc.NotFound, self.service_client.get_service,
                           service_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5193aad5-bcb7-411d-85b0-b3b61b96ef06')
     def test_create_update_get_service(self):
         # Creating a Service
         name = data_utils.rand_name('service')
@@ -62,6 +63,7 @@
         self.assertDictContainsSubset(update_service, fetched_service)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d1dcb1a1-2b6b-4da8-bbb8-5532ef6e8269')
     def test_create_service_without_description(self):
         # Create a service only with name and type
         name = data_utils.rand_name('service')
@@ -74,6 +76,7 @@
         self.assertDictContainsSubset(expected_data, service)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e55908e8-360e-439e-8719-c3230a3e179e')
     def test_list_services(self):
         # Create, List, Verify and Delete Services
         service_ids = list()
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index f0acfdf..47f9dbd 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -13,16 +13,17 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class TokensV3TestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0f9f5a5f-d5cd-4a86-8a5b-c5ded151f212')
     def test_tokens(self):
         # Valid user's token is authenticated
         # Create a User
@@ -44,10 +45,11 @@
         self.assertEqual(token_details['user']['name'], u_name)
         # Perform Delete Token
         self.client.delete_token(subject_token)
-        self.assertRaises(exceptions.NotFound, self.client.get_token,
+        self.assertRaises(lib_exc.NotFound, self.client.get_token,
                           subject_token)
 
     @test.attr(type='gate')
+    @test.idempotent_id('565fa210-1da1-4563-999b-f7b5b67cf112')
     def test_rescope_token(self):
         """Rescope a token.
 
@@ -108,8 +110,8 @@
 
         # Use the unscoped token to get a scoped token.
         token_auth = self.token.auth(token=token_id,
-                                     tenant=project1_name,
-                                     domain='Default')
+                                     project=project1_name,
+                                     project_domain='Default')
         token1_id = token_auth.response['x-subject-token']
 
         self.assertEqual(orig_expires_at, token_auth['token']['expires_at'],
@@ -138,8 +140,8 @@
 
         # Now get another scoped token using the unscoped token.
         token_auth = self.token.auth(token=token_id,
-                                     tenant=project2_name,
-                                     domain='Default')
+                                     project=project2_name,
+                                     project_domain='Default')
 
         self.assertEqual(project2['id'],
                          token_auth['token']['project']['id'])
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index cd28e96..db64a5b 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -13,12 +13,13 @@
 import datetime
 import re
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.identity import base
-from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import timeutils
 from tempest import test
 
@@ -87,13 +88,11 @@
         self.assertIsNotNone(self.trustee_user_id)
 
         # Initialize a new client with the trustor credentials
-        creds = auth.get_credentials(
+        creds = cred_provider.get_credentials(
             username=self.trustor_username,
             password=self.trustor_password,
             tenant_name=self.trustor_project_name)
-        os = clients.Manager(
-            credentials=creds,
-            interface=self._interface)
+        os = clients.Manager(credentials=creds)
         self.trustor_client = os.identity_v3_client
 
     def cleanup_user_and_roles(self):
@@ -120,13 +119,10 @@
                        summary=False):
         self.assertIsNotNone(trust['id'])
         self.assertEqual(impersonate, trust['impersonation'])
-        # FIXME(shardy): ref bug #1246383 we can't check the
-        # microsecond component of the expiry time, because mysql
-        # <5.6.4 doesn't support microseconds.
-        # expected format 2013-12-20T16:08:36.036987Z
         if expires is not None:
-            expires_nousec = re.sub(r'\.([0-9]){6}Z', '', expires)
-            self.assertTrue(trust['expires_at'].startswith(expires_nousec))
+            # Omit microseconds component of the expiry time
+            trust_expires_at = re.sub(r'\.([0-9]){6}', '', trust['expires_at'])
+            self.assertEqual(expires, trust_expires_at)
         else:
             self.assertIsNone(trust['expires_at'])
         self.assertEqual(self.trustor_user_id, trust['trustor_user_id'])
@@ -166,26 +162,25 @@
             self.trust_id, self.delegated_role_id)
 
         # And that we don't find not_delegated_role
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.trustor_client.get_trust_role,
                           self.trust_id,
                           self.not_delegated_role_id)
 
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.trustor_client.check_trust_role,
                           self.trust_id,
                           self.not_delegated_role_id)
 
     def delete_trust(self):
         self.trustor_client.delete_trust(self.trust_id)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.trustor_client.get_trust,
                           self.trust_id)
         self.trust_id = None
 
 
 class TrustsV3TestJSON(BaseTrustsV3Test):
-    _interface = 'json'
 
     def setUp(self):
         super(TrustsV3TestJSON, self).setUp()
@@ -193,6 +188,7 @@
         self.addCleanup(self.cleanup_user_and_roles)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5a0a91a4-baef-4a14-baba-59bf4d7fcace')
     def test_trust_impersonate(self):
         # Test case to check we can create, get and delete a trust
         # updates are not supported for trusts
@@ -205,6 +201,7 @@
         self.check_trust_roles()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ed2a8779-a7ac-49dc-afd7-30f32f936ed2')
     def test_trust_noimpersonate(self):
         # Test case to check we can create, get and delete a trust
         # with impersonation=False
@@ -217,11 +214,21 @@
         self.check_trust_roles()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0ed14b66-cefd-4b5c-a964-65759453e292')
     def test_trust_expire(self):
         # Test case to check we can create, get and delete a trust
         # with an expiry specified
         expires_at = timeutils.utcnow() + datetime.timedelta(hours=1)
-        expires_str = timeutils.isotime(at=expires_at, subsecond=True)
+        # NOTE(ylobankov) In some cases the expiry time may be rounded up
+        # because of microseconds. In fact, it depends on database and its
+        # version. At least MySQL 5.6.16 does this.
+        # For example, when creating a trust, we will set the expiry time of
+        # the trust to 2015-02-17T17:34:01.907051Z. However, if we make a GET
+        # request on the trust, the response will contain the time rounded up
+        # to 2015-02-17T17:34:02.000000Z. That is why we shouldn't set flag
+        # "subsecond" to True when we invoke timeutils.isotime(...) to avoid
+        # problems with rounding.
+        expires_str = timeutils.isotime(at=expires_at)
 
         trust = self.create_trust(expires=expires_str)
         self.validate_trust(trust, expires=expires_str)
@@ -233,16 +240,18 @@
         self.check_trust_roles()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3e48f95d-e660-4fa9-85e0-5a3d85594384')
     def test_trust_expire_invalid(self):
         # Test case to check we can check an invlaid expiry time
         # is rejected with the correct error
         # with an expiry specified
         expires_str = 'bad.123Z'
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_trust,
                           expires=expires_str)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6268b345-87ca-47c0-9ce3-37792b43403a')
     def test_get_trusts_query(self):
         self.create_trust()
         trusts_get = self.trustor_client.get_trusts(
@@ -251,6 +260,7 @@
         self.validate_trust(trusts_get[0], summary=True)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4773ebd5-ecbf-4255-b8d8-b63e6f72b65d')
     def test_get_trusts_all(self):
         self.create_trust()
         trusts_get = self.client.get_trusts()
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 4f3ec05..8120fa7 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -19,9 +19,9 @@
 
 
 class UsersV3TestJSON(base.BaseIdentityV3AdminTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
+    @test.idempotent_id('b537d090-afb9-4519-b95d-270b0708e87e')
     def test_user_update(self):
         # Test case to check if updating of user attributes is successful.
         # Creating first user
@@ -65,6 +65,7 @@
         self.assertEqual('false', str(new_user_get['enabled']).lower())
 
     @test.attr(type='gate')
+    @test.idempotent_id('2d223a0e-e457-4a70-9fb1-febe027a0ff9')
     def test_update_user_password(self):
         # Creating User to check password updation
         u_name = data_utils.rand_name('user')
@@ -86,6 +87,7 @@
         self.assertEqual(token_details['user']['name'], u_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a831e70c-e35b-430b-92ed-81ebbc5437b8')
     def test_list_user_projects(self):
         # List the projects that a user has access upon
         assigned_project_ids = list()
@@ -139,6 +141,7 @@
                                    in missing_projects))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c10dcd90-461d-4b16-8e23-4eb836c00644')
     def test_get_user(self):
         # Get a user detail
         self.data.setup_test_v3_user()
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 08bfd4f..ce54baa 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -13,12 +13,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 
-from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import log as logging
 import tempest.test
 
@@ -29,10 +29,10 @@
 class BaseIdentityAdminTest(tempest.test.BaseTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseIdentityAdminTest, cls).resource_setup()
-        cls.os_adm = clients.AdminManager(interface=cls._interface)
-        cls.os = clients.Manager(interface=cls._interface)
+    def setup_credentials(cls):
+        super(BaseIdentityAdminTest, cls).setup_credentials()
+        cls.os_adm = clients.AdminManager()
+        cls.os = clients.Manager()
 
     @classmethod
     def disable_user(cls, user_name):
@@ -72,18 +72,27 @@
 class BaseIdentityV2AdminTest(BaseIdentityAdminTest):
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
+        super(BaseIdentityV2AdminTest, cls).skip_checks()
         if not CONF.identity_feature_enabled.api_v2:
             raise cls.skipException("Identity api v2 is not enabled")
-        super(BaseIdentityV2AdminTest, cls).resource_setup()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseIdentityV2AdminTest, cls).setup_clients()
         cls.client = cls.os_adm.identity_client
         cls.token_client = cls.os_adm.token_client
         if not cls.client.has_admin_extensions():
             raise cls.skipException("Admin extensions disabled")
-        cls.data = DataGenerator(cls.client)
+
         cls.non_admin_client = cls.os.identity_client
 
     @classmethod
+    def resource_setup(cls):
+        super(BaseIdentityV2AdminTest, cls).resource_setup()
+        cls.data = DataGenerator(cls.client)
+
+    @classmethod
     def resource_cleanup(cls):
         cls.data.teardown_all()
         super(BaseIdentityV2AdminTest, cls).resource_cleanup()
@@ -92,10 +101,14 @@
 class BaseIdentityV3AdminTest(BaseIdentityAdminTest):
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
+        super(BaseIdentityV3AdminTest, cls).skip_checks()
         if not CONF.identity_feature_enabled.api_v3:
             raise cls.skipException("Identity api v3 is not enabled")
-        super(BaseIdentityV3AdminTest, cls).resource_setup()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseIdentityV3AdminTest, cls).setup_clients()
         cls.client = cls.os_adm.identity_v3_client
         cls.token = cls.os_adm.token_v3_client
         cls.endpoints_client = cls.os_adm.endpoints_client
@@ -149,11 +162,11 @@
 
         @property
         def test_credentials(self):
-            return auth.get_credentials(username=self.test_user,
-                                        user_id=self.user['id'],
-                                        password=self.test_password,
-                                        tenant_name=self.test_tenant,
-                                        tenant_id=self.tenant['id'])
+            return cred_provider.get_credentials(username=self.test_user,
+                                                 user_id=self.user['id'],
+                                                 password=self.test_password,
+                                                 tenant_name=self.test_tenant,
+                                                 tenant_id=self.tenant['id'])
 
         def setup_test_user(self):
             """Set up a test user."""
@@ -226,7 +239,7 @@
                     func(item['id'], **kwargs)
                 else:
                     func(item['id'])
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
             except Exception:
                 LOG.exception("Unexpected exception occurred in %s deletion."
diff --git a/tempest/api/identity/test_extension.py b/tempest/api/identity/test_extension.py
index e3badfc..f4a5c86 100644
--- a/tempest/api/identity/test_extension.py
+++ b/tempest/api/identity/test_extension.py
@@ -18,9 +18,9 @@
 
 
 class ExtensionTestJSON(base.BaseIdentityV2AdminTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
+    @test.idempotent_id('85f3f661-f54c-4d48-b563-72ae952b9383')
     def test_list_extensions(self):
         # List all the extensions
         body = self.non_admin_client.list_extensions()
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 12f3fdd..ffc3071 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -13,12 +13,12 @@
 #    under the License.
 
 import cStringIO as StringIO
+from tempest_lib import exceptions as lib_exc
 
 from tempest import clients
 from tempest.common import credentials
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import log as logging
 import tempest.test
 
@@ -31,24 +31,31 @@
     """Base test class for Image API tests."""
 
     @classmethod
+    def skip_checks(cls):
+        super(BaseImageTest, cls).skip_checks()
+        if not CONF.service_available.glance:
+            skip_msg = ("%s skipped as glance is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseImageTest, cls).setup_credentials()
+        cls.isolated_creds = credentials.get_isolated_credentials(
+            cls.__name__, network_resources=cls.network_resources)
+        cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
+
+    @classmethod
     def resource_setup(cls):
         cls.set_network_resources()
         super(BaseImageTest, cls).resource_setup()
         cls.created_images = []
-        cls._interface = 'json'
-        cls.isolated_creds = credentials.get_isolated_credentials(
-            cls.__name__, network_resources=cls.network_resources)
-        if not CONF.service_available.glance:
-            skip_msg = ("%s skipped as glance is not available" % cls.__name__)
-            raise cls.skipException(skip_msg)
-        cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
 
     @classmethod
     def resource_cleanup(cls):
         for image_id in cls.created_images:
             try:
                 cls.client.delete_image(image_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
 
         for image_id in cls.created_images:
@@ -76,21 +83,33 @@
 class BaseV1ImageTest(BaseImageTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseV1ImageTest, cls).resource_setup()
-        cls.client = cls.os.image_client
+    def skip_checks(cls):
+        super(BaseV1ImageTest, cls).skip_checks()
         if not CONF.image_feature_enabled.api_v1:
             msg = "Glance API v1 not supported"
             raise cls.skipException(msg)
 
+    @classmethod
+    def setup_clients(cls):
+        super(BaseV1ImageTest, cls).setup_clients()
+        cls.client = cls.os.image_client
+
 
 class BaseV1ImageMembersTest(BaseV1ImageTest):
+
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseV1ImageMembersTest, cls).setup_credentials()
+        cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseV1ImageMembersTest, cls).setup_clients()
+        cls.alt_img_cli = cls.os_alt.image_client
+
     @classmethod
     def resource_setup(cls):
         super(BaseV1ImageMembersTest, cls).resource_setup()
-        cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
-
-        cls.alt_img_cli = cls.os_alt.image_client
         cls.alt_tenant_id = cls.alt_img_cli.tenant_id
 
     def _create_image(self):
@@ -106,23 +125,35 @@
 class BaseV2ImageTest(BaseImageTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseV2ImageTest, cls).resource_setup()
-        cls.client = cls.os.image_client_v2
+    def skip_checks(cls):
+        super(BaseV2ImageTest, cls).skip_checks()
         if not CONF.image_feature_enabled.api_v2:
             msg = "Glance API v2 not supported"
             raise cls.skipException(msg)
 
+    @classmethod
+    def setup_clients(cls):
+        super(BaseV2ImageTest, cls).setup_clients()
+        cls.client = cls.os.image_client_v2
+
 
 class BaseV2MemberImageTest(BaseV2ImageTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseV2MemberImageTest, cls).resource_setup()
+    def setup_credentials(cls):
+        super(BaseV2MemberImageTest, cls).setup_credentials()
         creds = cls.isolated_creds.get_alt_creds()
         cls.os_alt = clients.Manager(creds)
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseV2MemberImageTest, cls).setup_clients()
         cls.os_img_client = cls.os.image_client_v2
         cls.alt_img_client = cls.os_alt.image_client_v2
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaseV2MemberImageTest, cls).resource_setup()
         cls.alt_tenant_id = cls.alt_img_client.tenant_id
 
     def _list_image_ids_as_alt(self):
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index d18a274..07a0df8 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -20,6 +20,7 @@
 class ImageMembersTest(base.BaseV1ImageMembersTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('1d6ef640-3a20-4c84-8710-d95828fdb6ad')
     def test_add_image_member(self):
         image = self._create_image()
         self.client.add_member(self.alt_tenant_id, image)
@@ -31,6 +32,7 @@
         self.alt_img_cli.get_image(image)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6a5328a5-80e8-4b82-bd32-6c061f128da9')
     def test_get_shared_images(self):
         image = self._create_image()
         self.client.add_member(self.alt_tenant_id, image)
@@ -43,6 +45,7 @@
         self.assertIn(image, images)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a76a3191-8948-4b44-a9d6-4053e5f2b138')
     def test_remove_member(self):
         image_id = self._create_image()
         self.client.add_member(self.alt_tenant_id, image_id)
diff --git a/tempest/api/image/v1/test_image_members_negative.py b/tempest/api/image/v1/test_image_members_negative.py
index aac63b4..c276d25 100644
--- a/tempest/api/image/v1/test_image_members_negative.py
+++ b/tempest/api/image/v1/test_image_members_negative.py
@@ -12,41 +12,45 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.image import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class ImageMembersNegativeTest(base.BaseV1ImageMembersTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('147a9536-18e3-45da-91ea-b037a028f364')
     def test_add_member_with_non_existing_image(self):
         # Add member with non existing image.
         non_exist_image = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.add_member,
+        self.assertRaises(lib_exc.NotFound, self.client.add_member,
                           self.alt_tenant_id, non_exist_image)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e1559f05-b667-4f1b-a7af-518b52dc0c0f')
     def test_delete_member_with_non_existing_image(self):
         # Delete member with non existing image.
         non_exist_image = data_utils.rand_uuid()
-        self.assertRaises(exceptions.NotFound, self.client.delete_member,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_member,
                           self.alt_tenant_id, non_exist_image)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f5720333-dd69-4194-bb76-d2f048addd56')
     def test_delete_member_with_non_existing_tenant(self):
         # Delete member with non existing tenant.
         image_id = self._create_image()
         non_exist_tenant = data_utils.rand_uuid_hex()
-        self.assertRaises(exceptions.NotFound, self.client.delete_member,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_member,
                           non_exist_tenant, image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f25f89e4-0b6c-453b-a853-1f80b9d7ef26')
     def test_get_image_without_membership(self):
         # Image is hidden from another tenants.
         image_id = self._create_image()
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.alt_img_cli.get_image,
                           image_id)
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index b9f12e6..a268128 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -27,6 +27,7 @@
     """Here we test the registration and creation of images."""
 
     @test.attr(type='gate')
+    @test.idempotent_id('3027f8e6-3492-4a11-8575-c3293017af4d')
     def test_register_then_upload(self):
         # Register, then upload an image
         properties = {'prop1': 'val1'}
@@ -50,6 +51,7 @@
         self.assertEqual(1024, body.get('size'))
 
     @test.attr(type='gate')
+    @test.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
     def test_register_remote_image(self):
         # Register a new remote image
         body = self.create_image(name='New Remote Image',
@@ -67,6 +69,7 @@
         self.assertEqual(properties['key2'], 'value2')
 
     @test.attr(type='gate')
+    @test.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
     def test_register_http_image(self):
         body = self.create_image(name='New Http Image',
                                  container_format='bare',
@@ -80,6 +83,7 @@
         self.client.get_image(image_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
     def test_register_image_with_min_ram(self):
         # Register an image with min ram
         properties = {'prop1': 'val1'}
@@ -166,6 +170,7 @@
         return image_id
 
     @test.attr(type='gate')
+    @test.idempotent_id('246178ab-3b33-4212-9a4b-a7fe8261794d')
     def test_index_no_params(self):
         # Simple test to see all fixture images returned
         images_list = self.client.image_list()
@@ -174,6 +179,7 @@
             self.assertIn(image_id, image_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
     def test_index_disk_format(self):
         images_list = self.client.image_list(disk_format='ami')
         for image in images_list:
@@ -183,6 +189,7 @@
         self.assertFalse(self.created_set - self.ami_set <= result_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
     def test_index_container_format(self):
         images_list = self.client.image_list(container_format='bare')
         for image in images_list:
@@ -192,6 +199,7 @@
         self.assertFalse(self.created_set - self.bare_set <= result_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
     def test_index_max_size(self):
         images_list = self.client.image_list(size_max=42)
         for image in images_list:
@@ -201,6 +209,7 @@
         self.assertFalse(self.created_set - self.size42_set <= result_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6ffc16d0-4cbf-4401-95c8-4ac63eac34d8')
     def test_index_min_size(self):
         images_list = self.client.image_list(size_min=142)
         for image in images_list:
@@ -210,6 +219,7 @@
         self.assertFalse(self.size42_set <= result_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e5dc26d9-9aa2-48dd-bda5-748e1445da98')
     def test_index_status_active_detail(self):
         images_list = self.client.image_list_detail(status='active',
                                                     sort_key='size',
@@ -222,6 +232,7 @@
             self.assertEqual(image['status'], 'active')
 
     @test.attr(type='gate')
+    @test.idempotent_id('097af10a-bae8-4342-bff4-edf89969ed2a')
     def test_index_name(self):
         images_list = self.client.image_list_detail(
             name='New Remote Image dup')
@@ -256,6 +267,7 @@
         return image_id
 
     @test.attr(type='gate')
+    @test.idempotent_id('01752c1c-0275-4de3-9e5b-876e44541928')
     def test_list_image_metadata(self):
         # All metadata key/value pairs for an image should be returned
         resp_metadata = self.client.get_image_meta(self.image_id)
@@ -263,6 +275,7 @@
         self.assertEqual(expected, resp_metadata['properties'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d6d7649c-08ce-440d-9ea7-e3dda552f33c')
     def test_update_image_metadata(self):
         # The metadata for the image should match the updated values
         req_metadata = {'key1': 'alt1', 'key2': 'value2'}
diff --git a/tempest/api/image/v1/test_images_negative.py b/tempest/api/image/v1/test_images_negative.py
index 66556e0..85b9435 100644
--- a/tempest/api/image/v1/test_images_negative.py
+++ b/tempest/api/image/v1/test_images_negative.py
@@ -13,8 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.image import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -22,49 +23,57 @@
     """Here are negative tests for the deletion and creation of images."""
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('036ede36-6160-4463-8c01-c781eee6369d')
     def test_register_with_invalid_container_format(self):
         # Negative tests for invalid data supplied to POST /images
-        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           'test', 'wrong', 'vhd')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('993face5-921d-4e84-aabf-c1bba4234a67')
     def test_register_with_invalid_disk_format(self):
-        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           'test', 'bare', 'wrong')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bb016f15-0820-4f27-a92d-09b2f67d2488')
     def test_delete_image_with_invalid_image_id(self):
         # An image should not be deleted with invalid image id
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           '!@$%^&*()')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ec652588-7e3c-4b67-a2f2-0fa96f57c8fc')
     def test_delete_non_existent_image(self):
         # Return an error while trying to delete a non-existent image
 
         non_existent_image_id = '11a22b9-12a9-5555-cc11-00ab112223fa'
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           non_existent_image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('04f72aa3-fcec-45a3-81a3-308ef7cc82bc')
     def test_delete_image_blank_id(self):
         # Return an error while trying to delete an image with blank Id
-        self.assertRaises(exceptions.NotFound, self.client.delete_image, '')
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('950e5054-a3c7-4dee-ada5-e576f1087abd')
     def test_delete_image_non_hex_string_id(self):
         # Return an error while trying to delete an image with non hex id
         image_id = '11a22b9-120q-5555-cc11-00ab112223gj'
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4ed757cd-450c-44b1-9fd1-c819748c650d')
     def test_delete_image_negative_image_id(self):
         # Return an error while trying to delete an image with negative id
-        self.assertRaises(exceptions.NotFound, self.client.delete_image, -1)
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image, -1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a4a448ab-3db2-4d2d-b9b2-6a1271241dfe')
     def test_delete_image_id_is_over_35_character_limit(self):
         # Return an error while trying to delete image with id over limit
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           '11a22b9-12a9-5555-cc11-00ab112223fa-3fac')
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index e307c5c..a4f5ae3 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -28,6 +28,7 @@
     """
 
     @test.attr(type='gate')
+    @test.idempotent_id('139b765e-7f3d-4b3d-8b37-3ca3876ee318')
     def test_register_upload_get_image_file(self):
 
         """
@@ -65,10 +66,11 @@
         self.assertEqual(1024, body.get('size'))
 
         # Now try get image file
-        _, body = self.client.get_image_file(image_id)
-        self.assertEqual(file_content, body)
+        body = self.client.get_image_file(image_id)
+        self.assertEqual(file_content, body.data)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f848bb94-1c6e-45a4-8726-39e3a5b23535')
     def test_delete_image(self):
         # Deletes an image by image_id
 
@@ -90,6 +92,7 @@
         self.assertNotIn(image_id, images_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f66891a7-a35c-41a8-b590-a065c2a1caa6')
     def test_update_image(self):
         # Updates an image by image_id
 
@@ -168,6 +171,7 @@
                 self.assertEqual(params[key], image[key], msg)
 
     @test.attr(type='gate')
+    @test.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
     def test_index_no_params(self):
         # Simple test to see all fixture images returned
         images_list = self.client.image_list()
@@ -177,24 +181,28 @@
             self.assertIn(image, image_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e')
     def test_list_images_param_container_format(self):
         # Test to get all images with container_format='bare'
         params = {"container_format": "bare"}
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4a4735a7-f22f-49b6-b0d9-66e1ef7453eb')
     def test_list_images_param_disk_format(self):
         # Test to get all images with disk_format = raw
         params = {"disk_format": "raw"}
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7a95bb92-d99e-4b12-9718-7bc6ab73e6d2')
     def test_list_images_param_visibility(self):
         # Test to get all images with visibility = private
         params = {"visibility": "private"}
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('cf1b9a48-8340-480e-af7b-fe7e17690876')
     def test_list_images_param_size(self):
         # Test to get all images by size
         image_id = self.created_images[1]
@@ -205,6 +213,7 @@
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4ad8c157-971a-4ba8-aa84-ed61154b1e7f')
     def test_list_images_param_min_max_size(self):
         # Test to get all images with size between 2000 to 3000
         image_id = self.created_images[1]
@@ -222,12 +231,14 @@
                             "Failed to get images by size_min and size_max")
 
     @test.attr(type='gate')
+    @test.idempotent_id('7fc9e369-0f58-4d05-9aa5-0969e2d59d15')
     def test_list_images_param_status(self):
         # Test to get all active images
         params = {"status": "active"}
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e914a891-3cc8-4b40-ad32-e0a39ffbddbb')
     def test_list_images_param_limit(self):
         # Test to get images by limit
         params = {"limit": 2}
@@ -237,6 +248,7 @@
                          "Failed to get images by limit")
 
     @test.attr(type='gate')
+    @test.idempotent_id('622b925c-479f-4736-860d-adeaf13bc371')
     def test_get_image_schema(self):
         # Test to get image schema
         schema = "image"
@@ -244,6 +256,7 @@
         self.assertEqual("image", body['name'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('25c8d7b2-df21-460f-87ac-93130bcdc684')
     def test_get_images_schema(self):
         # Test to get images schema
         schema = "images"
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index ec1cf14..bbe4ce8 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -15,9 +15,9 @@
 
 
 class ImagesMemberTest(base.BaseV2MemberImageTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
+    @test.idempotent_id('5934c6ea-27dc-4d6e-9421-eeb5e045494a')
     def test_image_share_accept(self):
         image_id = self._create_image()
         member = self.os_img_client.add_member(image_id,
@@ -39,6 +39,7 @@
         self.assertEqual(member['status'], 'accepted')
 
     @test.attr(type='gate')
+    @test.idempotent_id('d9e83e5f-3524-4b38-a900-22abcb26e90e')
     def test_image_share_reject(self):
         image_id = self._create_image()
         member = self.os_img_client.add_member(image_id,
@@ -53,6 +54,7 @@
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
 
     @test.attr(type='gate')
+    @test.idempotent_id('a6ee18b9-4378-465e-9ad9-9a6de58a3287')
     def test_get_image_member(self):
         image_id = self._create_image()
         self.os_img_client.add_member(image_id,
@@ -69,6 +71,7 @@
         self.assertEqual('accepted', member['status'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('72989bc7-2268-48ed-af22-8821e835c914')
     def test_remove_image_member(self):
         image_id = self._create_image()
         self.os_img_client.add_member(image_id,
@@ -82,11 +85,13 @@
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
 
     @test.attr(type='gate')
+    @test.idempotent_id('634dcc3f-f6e2-4409-b8fd-354a0bb25d83')
     def test_get_image_member_schema(self):
         body = self.os_img_client.get_schema("member")
         self.assertEqual("member", body['name'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('6ae916ef-1052-4e11-8d36-b3ae14853cbb')
     def test_get_image_members_schema(self):
         body = self.os_img_client.get_schema("members")
         self.assertEqual("members", body['name'])
diff --git a/tempest/api/image/v2/test_images_member_negative.py b/tempest/api/image/v2/test_images_member_negative.py
index 1f8e3d0..a0c59ff 100644
--- a/tempest/api/image/v2/test_images_member_negative.py
+++ b/tempest/api/image/v2/test_images_member_negative.py
@@ -10,32 +10,34 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.image import base
-from tempest import exceptions
 from tempest import test
 
 
 class ImagesMemberNegativeTest(base.BaseV2MemberImageTest):
-    _interface = 'json'
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b79efb37-820d-4cf0-b54c-308b00cf842c')
     def test_image_share_invalid_status(self):
         image_id = self._create_image()
         member = self.os_img_client.add_member(image_id,
                                                self.alt_tenant_id)
         self.assertEqual(member['status'], 'pending')
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.alt_img_client.update_member_status,
                           image_id, self.alt_tenant_id, 'notavalidstatus')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('27002f74-109e-4a37-acd0-f91cd4597967')
     def test_image_share_owner_cannot_accept(self):
         image_id = self._create_image()
         member = self.os_img_client.add_member(image_id,
                                                self.alt_tenant_id)
         self.assertEqual(member['status'], 'pending')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.os_img_client.update_member_status,
                           image_id, self.alt_tenant_id, 'accepted')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index fc781b1..23d32f4 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -16,8 +16,9 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.image import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -36,19 +37,22 @@
      """
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('668743d5-08ad-4480-b2b8-15da34f81d9f')
     def test_get_non_existent_image(self):
         # get the non-existent image
         non_existent_id = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound, self.client.get_image,
+        self.assertRaises(lib_exc.NotFound, self.client.get_image,
                           non_existent_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ef45000d-0a72-4781-866d-4cb7bf2562ad')
     def test_get_image_null_id(self):
         # get image with image_id = NULL
         image_id = ""
-        self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
+        self.assertRaises(lib_exc.NotFound, self.client.get_image, image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e57fc127-7ba0-4693-92d7-1d8a05ebcba9')
     def test_get_delete_deleted_image(self):
         # get and delete the deleted image
         # create and delete image
@@ -60,33 +64,37 @@
         self.client.wait_for_resource_deletion(image_id)
 
         # get the deleted image
-        self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
+        self.assertRaises(lib_exc.NotFound, self.client.get_image, image_id)
 
         # delete the deleted image
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6fe40f1c-57bd-4918-89cc-8500f850f3de')
     def test_delete_non_existing_image(self):
         # delete non-existent image
         non_existent_image_id = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           non_existent_image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('32248db1-ab88-4821-9604-c7c369f1f88c')
     def test_delete_image_null_id(self):
         # delete image with image_id=NULL
         image_id = ""
-        self.assertRaises(exceptions.NotFound, self.client.delete_image,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('292bd310-369b-41c7-a7a3-10276ef76753')
     def test_register_with_invalid_container_format(self):
         # Negative tests for invalid data supplied to POST /images
-        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           'test', 'wrong', 'vhd')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('70c6040c-5a97-4111-9e13-e73665264ce1')
     def test_register_with_invalid_disk_format(self):
-        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           'test', 'bare', 'wrong')
diff --git a/tempest/api/image/v2/test_images_tags.py b/tempest/api/image/v2/test_images_tags.py
index 4686de2..350ede3 100644
--- a/tempest/api/image/v2/test_images_tags.py
+++ b/tempest/api/image/v2/test_images_tags.py
@@ -20,6 +20,7 @@
 class ImagesTagsTest(base.BaseV2ImageTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('10407036-6059-4f95-a2cd-cbbbee7ed329')
     def test_update_delete_tags_for_image(self):
         body = self.create_image(container_format='bare',
                                  disk_format='raw',
diff --git a/tempest/api/image/v2/test_images_tags_negative.py b/tempest/api/image/v2/test_images_tags_negative.py
index aa0a214..bbe0431 100644
--- a/tempest/api/image/v2/test_images_tags_negative.py
+++ b/tempest/api/image/v2/test_images_tags_negative.py
@@ -14,23 +14,26 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.image import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class ImagesTagsNegativeTest(base.BaseV2ImageTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8cd30f82-6f9a-4c6e-8034-c1b51fba43d9')
     def test_update_tags_for_non_existing_image(self):
         # Update tag with non existing image.
         tag = data_utils.rand_name('tag-')
         non_exist_image = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound, self.client.add_image_tag,
+        self.assertRaises(lib_exc.NotFound, self.client.add_image_tag,
                           non_exist_image, tag)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('39c023a2-325a-433a-9eea-649bf1414b19')
     def test_delete_non_existing_tag(self):
         # Delete non existing tag.
         body = self.create_image(container_format='bare',
@@ -40,5 +43,5 @@
         image_id = body['id']
         tag = data_utils.rand_name('non-exist-tag-')
         self.addCleanup(self.client.delete_image, image_id)
-        self.assertRaises(exceptions.NotFound, self.client.delete_image_tag,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_image_tag,
                           image_id, tag)
diff --git a/tempest/api/messaging/base.py b/tempest/api/messaging/base.py
index 58511a9..eae0707 100644
--- a/tempest/api/messaging/base.py
+++ b/tempest/api/messaging/base.py
@@ -35,13 +35,25 @@
     """
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseMessagingTest, cls).resource_setup()
+    def skip_checks(cls):
+        super(BaseMessagingTest, cls).skip_checks()
         if not CONF.service_available.zaqar:
             raise cls.skipException("Zaqar support is required")
-        os = cls.get_client_manager()
+
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseMessagingTest, cls).setup_credentials()
+        cls.os = cls.get_client_manager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseMessagingTest, cls).setup_clients()
+        cls.client = cls.os.messaging_client
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaseMessagingTest, cls).resource_setup()
         cls.messaging_cfg = CONF.messaging
-        cls.client = os.messaging_client
 
     @classmethod
     def create_queue(cls, queue_name):
diff --git a/tempest/api/messaging/test_claims.py b/tempest/api/messaging/test_claims.py
index 1aab8d2..ebaa283 100644
--- a/tempest/api/messaging/test_claims.py
+++ b/tempest/api/messaging/test_claims.py
@@ -29,7 +29,6 @@
 
 
 class TestClaims(base.BaseMessagingTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -56,6 +55,7 @@
         return resp, body
 
     @test.attr(type='smoke')
+    @test.idempotent_id('936cb1ca-b7af-44dd-a752-805e8c98156f')
     def test_post_claim(self):
         _, body = self._post_and_claim_messages(queue_name=self.queue_name)
         claimed_message_uri = body[0]['href']
@@ -69,6 +69,7 @@
 
     @decorators.skip_because(bug="1331517")
     @test.attr(type='smoke')
+    @test.idempotent_id('84e491f4-68c6-451f-9846-b8f868eb27c5')
     def test_query_claim(self):
         # Post a Claim
         resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
@@ -83,6 +84,7 @@
 
     @decorators.skip_because(bug="1328111")
     @test.attr(type='smoke')
+    @test.idempotent_id('420ef0c5-9bd6-4b82-b06d-d9da330fefd3')
     def test_update_claim(self):
         # Post a Claim
         resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
@@ -106,6 +108,7 @@
         self.client.delete_messages(claimed_message_uri)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fd4c7921-cb3f-4ed8-9ac8-e8f1e74c44aa')
     def test_release_claim(self):
         # Post a Claim
         resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
diff --git a/tempest/api/messaging/test_messages.py b/tempest/api/messaging/test_messages.py
index 3c27ac2..12a3df5 100644
--- a/tempest/api/messaging/test_messages.py
+++ b/tempest/api/messaging/test_messages.py
@@ -26,7 +26,6 @@
 
 
 class TestMessages(base.BaseMessagingTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -42,6 +41,7 @@
         return resp, body
 
     @test.attr(type='smoke')
+    @test.idempotent_id('93867172-a414-4eb3-a639-96e943c516b4')
     def test_post_messages(self):
         # Post Messages
         resp, _ = self._post_messages()
@@ -54,6 +54,7 @@
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c967d59a-e919-41cb-994b-1c4300452c80')
     def test_list_messages(self):
         # Post Messages
         self._post_messages()
@@ -65,6 +66,7 @@
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2a68e3de-24df-47c3-9039-ec4156656bf8')
     def test_get_message(self):
         # Post Messages
         _, body = self._post_messages()
@@ -77,6 +79,7 @@
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c4b0a30b-efda-4b87-a395-0c43140df74d')
     def test_get_multiple_messages(self):
         # Post Messages
         resp, _ = self._post_messages()
@@ -89,6 +92,7 @@
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fc0fca47-dd8b-4ecc-8522-d9c191f9bc9f')
     def test_delete_single_message(self):
         # Post Messages
         _, body = self._post_messages()
@@ -104,6 +108,7 @@
         self.assertEqual('204', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('00cca069-5c8f-4b42-bff1-c577da2a4546')
     def test_delete_multiple_messages(self):
         # Post Messages
         resp, _ = self._post_messages()
diff --git a/tempest/api/messaging/test_queues.py b/tempest/api/messaging/test_queues.py
index accbd17..5d9a7c7 100644
--- a/tempest/api/messaging/test_queues.py
+++ b/tempest/api/messaging/test_queues.py
@@ -16,11 +16,11 @@
 import logging
 
 from six import moves
+from tempest_lib import exceptions as lib_exc
 from testtools import matchers
 
 from tempest.api.messaging import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -30,6 +30,7 @@
 class TestQueues(base.BaseMessagingTest):
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9f1c4c72-80c5-4dac-acf3-188cef42e36c')
     def test_create_delete_queue(self):
         # Create & Delete Queue
         queue_name = data_utils.rand_name('test-')
@@ -42,13 +43,12 @@
         self.assertEqual('', body)
 
         self.delete_queue(queue_name)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.get_queue,
                           queue_name)
 
 
 class TestManageQueue(base.BaseMessagingTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -61,18 +61,21 @@
             cls.client.create_queue(queue_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ccd3d69e-f156-4c5f-8a12-b4f24bee44e1')
     def test_check_queue_existence(self):
         # Checking Queue Existence
         for queue_name in self.queues:
             self.check_queue_exists(queue_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e27634d8-9c8f-47d8-a677-655c47658d3e')
     def test_check_queue_head(self):
         # Checking Queue Existence by calling HEAD
         for queue_name in self.queues:
             self.check_queue_exists_head(queue_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0a0feeca-7768-4303-806d-82bbbb796ad3')
     def test_list_queues(self):
         # Listing queues
         _, body = self.list_queues()
@@ -81,6 +84,7 @@
             self.assertIn(item['name'], self.queues)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8fb66602-077d-49d6-ae1a-5f2091739178')
     def test_get_queue_stats(self):
         # Retrieve random queue
         queue_name = self.queues[data_utils.rand_int_id(0,
@@ -94,6 +98,7 @@
             self.assertNotIn(element, msgs)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0e2441e6-6593-4bdb-a3c0-20e66eeb3fff')
     def test_set_and_get_queue_metadata(self):
         # Retrieve random queue
         queue_name = self.queues[data_utils.rand_int_id(0,
diff --git a/tempest/api/network/admin/test_agent_management.py b/tempest/api/network/admin/test_agent_management.py
index e7fd016..d5454ec 100644
--- a/tempest/api/network/admin/test_agent_management.py
+++ b/tempest/api/network/admin/test_agent_management.py
@@ -18,7 +18,6 @@
 
 
 class AgentManagementTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -31,6 +30,7 @@
         cls.agent = agents[0]
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9c80f04d-11f3-44a4-8738-ed2f879b0ff4')
     def test_list_agent(self):
         body = self.admin_client.list_agents()
         agents = body['agents']
@@ -43,17 +43,20 @@
         self.assertIn(self.agent, agents)
 
     @test.attr(type=['smoke'])
+    @test.idempotent_id('e335be47-b9a1-46fd-be30-0874c0b751e6')
     def test_list_agents_non_admin(self):
         body = self.client.list_agents()
         self.assertEqual(len(body["agents"]), 0)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('869bc8e8-0fda-4a30-9b71-f8a7cf58ca9f')
     def test_show_agent(self):
         body = self.admin_client.show_agent(self.agent['id'])
         agent = body['agent']
         self.assertEqual(agent['id'], self.agent['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('371dfc5b-55b9-4cb5-ac82-c40eadaac941')
     def test_update_agent_status(self):
         origin_status = self.agent['admin_state_up']
         # Try to update the 'admin_state_up' to the original
@@ -65,6 +68,7 @@
         self.assertEqual(origin_status, updated_status)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('68a94a14-1243-46e6-83bf-157627e31556')
     def test_update_agent_description(self):
         self.useFixture(fixtures.LockFixture('agent_description'))
         description = 'description for update agent.'
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index a89f25c..26f5e7a 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -17,7 +17,6 @@
 
 
 class DHCPAgentSchedulersTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -33,11 +32,13 @@
         cls.port = cls.create_port(cls.network)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
     def test_list_dhcp_agent_hosting_network(self):
         self.admin_client.list_dhcp_agent_hosting_network(
             self.network['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('30c48f98-e45d-4ffb-841c-b8aad57c7587')
     def test_list_networks_hosted_by_one_dhcp(self):
         body = self.admin_client.list_dhcp_agent_hosting_network(
             self.network['id'])
@@ -57,6 +58,7 @@
         return network_id in network_ids
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a0856713-6549-470c-a656-e97c8df9a14d')
     def test_add_remove_network_from_dhcp_agent(self):
         # The agent is now bound to the network, we can free the port
         self.client.delete_port(self.port['id'])
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index 3110aab..d942641 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -12,10 +12,10 @@
 
 from tempest.api.network import base
 from tempest.common.utils import data_utils
+from tempest import test
 
 
 class ExternalNetworksTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -31,6 +31,7 @@
         self.addCleanup(self.admin_client.delete_network, network['id'])
         return network
 
+    @test.idempotent_id('462be770-b310-4df9-9c42-773217e4c8b1')
     def test_create_external_network(self):
         # Create a network as an admin user specifying the
         # external network extension attribute
@@ -39,6 +40,7 @@
         self.assertIsNotNone(ext_network['id'])
         self.assertTrue(ext_network['router:external'])
 
+    @test.idempotent_id('4db5417a-e11c-474d-a361-af00ebef57c5')
     def test_update_external_network(self):
         # Update a network as an admin user specifying the
         # external network extension attribute
@@ -51,6 +53,7 @@
         # Verify that router:external parameter was updated
         self.assertTrue(updated_network['router:external'])
 
+    @test.idempotent_id('39be4c9b-a57e-4ff9-b7c7-b218e209dfcc')
     def test_list_external_networks(self):
         # Create external_net
         external_network = self._create_network()
@@ -67,6 +70,7 @@
             elif net['id'] == external_network['id']:
                 self.assertTrue(net['router:external'])
 
+    @test.idempotent_id('2ac50ab2-7ebd-4e27-b3ce-a9e399faaea2')
     def test_show_external_networks_attribute(self):
         # Create external_net
         external_network = self._create_network()
@@ -84,6 +88,7 @@
         self.assertEqual(self.network['id'], show_net['id'])
         self.assertFalse(show_net['router:external'])
 
+    @test.idempotent_id('82068503-2cf2-4ed4-b3be-ecb89432e4bb')
     def test_delete_external_networks_with_floating_ip(self):
         """Verifies external network can be deleted while still holding
         (unassociated) floating IPs
diff --git a/tempest/api/network/admin/test_external_networks_negative.py b/tempest/api/network/admin/test_external_networks_negative.py
index 7dbb347..c2fa0dd 100644
--- a/tempest/api/network/admin/test_external_networks_negative.py
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -13,18 +13,19 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.network import base
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
 class ExternalNetworksAdminNegativeTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     @test.attr(type=['negative'])
+    @test.idempotent_id('d402ae6c-0be0-4d8e-833b-a738895d98d0')
     def test_create_port_with_precreated_floatingip_as_fixed_ip(self):
         """
         External networks can be used to create both floating-ip as well
@@ -47,7 +48,7 @@
         fixed_ips = [{'ip_address': floating_ip_address}]
 
         # create a port which will internally create an instance-ip
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           client.create_port,
                           network_id=CONF.network.public_network_id,
                           fixed_ips=fixed_ips)
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 62ba1b3..a3a9977 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -15,6 +15,7 @@
 
 from tempest.api.network import base
 from tempest import clients
+from tempest.common.utils import data_utils
 from tempest import config
 from tempest import test
 
@@ -22,7 +23,7 @@
 
 
 class FloatingIPAdminTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
+
     force_tenant_isolation = True
 
     @classmethod
@@ -32,8 +33,15 @@
         cls.floating_ip = cls.create_floatingip(cls.ext_net_id)
         cls.alt_manager = clients.Manager(cls.isolated_creds.get_alt_creds())
         cls.alt_client = cls.alt_manager.network_client
+        cls.network = cls.create_network()
+        cls.subnet = cls.create_subnet(cls.network)
+        cls.router = cls.create_router(data_utils.rand_name('router-'),
+                                       external_network_id=cls.ext_net_id)
+        cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+        cls.port = cls.create_port(cls.network)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
     def test_list_floating_ips_from_admin_and_nonadmin(self):
         # Create floating ip from admin user
         floating_ip_admin = self.admin_client.create_floatingip(
@@ -63,3 +71,40 @@
         self.assertNotIn(floating_ip_admin['floatingip']['id'],
                          floating_ip_ids)
         self.assertNotIn(floating_ip_alt['id'], floating_ip_ids)
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('32727cc3-abe2-4485-a16e-48f2d54c14f2')
+    def test_create_list_show_floating_ip_with_tenant_id_by_admin(self):
+        # Creates a floating IP
+        body = self.admin_client.create_floatingip(
+            floating_network_id=self.ext_net_id,
+            tenant_id=self.network['tenant_id'],
+            port_id=self.port['id'])
+        created_floating_ip = body['floatingip']
+        self.addCleanup(self.client.delete_floatingip,
+                        created_floating_ip['id'])
+        self.assertIsNotNone(created_floating_ip['id'])
+        self.assertIsNotNone(created_floating_ip['tenant_id'])
+        self.assertIsNotNone(created_floating_ip['floating_ip_address'])
+        self.assertEqual(created_floating_ip['port_id'], self.port['id'])
+        self.assertEqual(created_floating_ip['floating_network_id'],
+                         self.ext_net_id)
+        port = self.port['fixed_ips']
+        self.assertEqual(created_floating_ip['fixed_ip_address'],
+                         port[0]['ip_address'])
+        # Verifies the details of a floating_ip
+        floating_ip = self.admin_client.show_floatingip(
+            created_floating_ip['id'])
+        shown_floating_ip = floating_ip['floatingip']
+        self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
+        self.assertEqual(shown_floating_ip['floating_network_id'],
+                         self.ext_net_id)
+        self.assertEqual(shown_floating_ip['tenant_id'],
+                         self.network['tenant_id'])
+        self.assertEqual(shown_floating_ip['floating_ip_address'],
+                         created_floating_ip['floating_ip_address'])
+        self.assertEqual(shown_floating_ip['port_id'], self.port['id'])
+        # Verify the floating ip exists in the list of all floating_ips
+        floating_ips = self.admin_client.list_floatingips()
+        floatingip_id_list = [f['id'] for f in floating_ips['floatingips']]
+        self.assertIn(created_floating_ip['id'], floatingip_id_list)
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index a6de581..e6fa0a6 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -18,7 +18,6 @@
 
 
 class L3AgentSchedulerTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -51,10 +50,12 @@
             raise cls.skipException(msg)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b7ce6e89-e837-4ded-9b78-9ed3c9c6a45a')
     def test_list_routers_on_l3_agent(self):
         self.admin_client.list_routers_on_l3_agent(self.agent['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9464e5e7-8625-49c3-8fd1-89c52be59d66')
     def test_add_list_remove_router_on_l3_agent(self):
         l3_agent_ids = list()
         name = data_utils.rand_name('router1-')
diff --git a/tempest/api/network/admin/test_lbaas_agent_scheduler.py b/tempest/api/network/admin/test_lbaas_agent_scheduler.py
index da1af36..c178fc0 100644
--- a/tempest/api/network/admin/test_lbaas_agent_scheduler.py
+++ b/tempest/api/network/admin/test_lbaas_agent_scheduler.py
@@ -18,7 +18,6 @@
 
 
 class LBaaSAgentSchedulerTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -47,6 +46,7 @@
                                    "HTTP", cls.subnet)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e5ea8b15-4f44-4350-963c-e0fcb533ee79')
     def test_list_pools_on_lbaas_agent(self):
         found = False
         body = self.admin_client.list_agents(
@@ -65,6 +65,7 @@
         self.assertTrue(found, msg)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e2745593-fd79-4b98-a262-575fd7865796')
     def test_show_lbaas_agent_hosting_pool(self):
         body = self.admin_client.show_lbaas_agent_hosting_pool(
             self.pool['id'])
diff --git a/tempest/api/network/admin/test_load_balancer_admin_actions.py b/tempest/api/network/admin/test_load_balancer_admin_actions.py
index e81616b..931f079 100644
--- a/tempest/api/network/admin/test_load_balancer_admin_actions.py
+++ b/tempest/api/network/admin/test_load_balancer_admin_actions.py
@@ -19,7 +19,6 @@
 
 
 class LoadBalancerAdminTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     """
     Test admin actions for load balancer.
@@ -44,6 +43,7 @@
                                    "ROUND_ROBIN", "HTTP", cls.subnet)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6b0a20d8-4fcd-455e-b54f-ec4db5199518')
     def test_create_vip_as_admin_for_another_tenant(self):
         name = data_utils.rand_name('vip-')
         body = self.admin_client.create_pool(
@@ -70,6 +70,7 @@
         self.assertEqual(vip['name'], show_vip['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('74552cfc-ab78-4fb6-825b-f67bca379921')
     def test_create_health_monitor_as_admin_for_another_tenant(self):
         body = (
             self.admin_client.create_health_monitor(delay=4,
@@ -87,6 +88,7 @@
         self.assertEqual(health_monitor['id'], show_health_monitor['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('266a192d-3c22-46c4-a8fb-802450301e82')
     def test_create_pool_from_admin_user_other_tenant(self):
         body = self.admin_client.create_pool(
             name=data_utils.rand_name('pool-'),
@@ -100,6 +102,7 @@
         self.assertEqual(self.tenant_id, pool['tenant_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('158bb272-b9ed-4cfc-803c-661dac46f783')
     def test_create_member_from_admin_user_other_tenant(self):
         body = self.admin_client.create_member(address="10.0.9.47",
                                                protocol_port=80,
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index f8dfca9..1ea24fe 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -20,7 +20,6 @@
 
 
 class QuotasTest(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -84,10 +83,12 @@
             self.assertNotEqual(tenant_id, q['tenant_id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
     def test_quotas(self):
         new_quotas = {'network': 0, 'security_group': 0}
         self._check_quotas(new_quotas)
 
+    @test.idempotent_id('a7add2b1-691e-44d6-875f-697d9685f091')
     @test.requires_ext(extension='lbaas', service='network')
     @test.attr(type='gate')
     def test_lbaas_quotas(self):
diff --git a/tempest/api/network/admin/test_routers_dvr.py b/tempest/api/network/admin/test_routers_dvr.py
new file mode 100644
index 0000000..d1833dd
--- /dev/null
+++ b/tempest/api/network/admin/test_routers_dvr.py
@@ -0,0 +1,101 @@
+# Copyright 2015 OpenStack Foundation
+# 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.
+
+from tempest.api.network import base_routers as base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class RoutersTestDVR(base.BaseRouterTest):
+
+    @classmethod
+    def resource_setup(cls):
+        for ext in ['router', 'dvr']:
+            if not test.is_extension_enabled(ext, 'network'):
+                msg = "%s extension not enabled." % ext
+                raise cls.skipException(msg)
+        # The check above will pass if api_extensions=all, which does
+        # not mean DVR extension itself is present.
+        # Instead, we have to check whether DVR is actually present by using
+        # admin credentials to create router with distributed=True attribute
+        # and checking for BadRequest exception and that the resulting router
+        # has a distributed attribute.
+        super(RoutersTestDVR, cls).resource_setup()
+        name = data_utils.rand_name('pretest-check')
+        router = cls.admin_client.create_router(name)
+        if 'distributed' not in router['router']:
+            msg = "'distributed' attribute not found. DVR Possibly not enabled"
+            raise cls.skipException(msg)
+        cls.admin_client.delete_router(router['router']['id'])
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('08a2a0a8-f1e4-4b34-8e30-e522e836c44e')
+    def test_distributed_router_creation(self):
+        """
+        Test uses administrative credentials to creates a
+        DVR (Distributed Virtual Routing) router using the
+        distributed=True.
+
+        Acceptance
+        The router is created and the "distributed" attribute is
+        set to True
+        """
+        name = data_utils.rand_name('router')
+        router = self.admin_client.create_router(name, distributed=True)
+        self.addCleanup(self.admin_client.delete_router,
+                        router['router']['id'])
+        self.assertTrue(router['router']['distributed'])
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('8a0a72b4-7290-4677-afeb-b4ffe37bc352')
+    def test_centralized_router_creation(self):
+        """
+        Test uses administrative credentials to creates a
+        CVR (Centralized Virtual Routing) router using the
+        distributed=False.
+
+        Acceptance
+        The router is created and the "distributed" attribute is
+        set to False, thus making it a "Centralized Virtual Router"
+        as opposed to a "Distributed Virtual Router"
+        """
+        name = data_utils.rand_name('router')
+        router = self.admin_client.create_router(name, distributed=False)
+        self.addCleanup(self.admin_client.delete_router,
+                        router['router']['id'])
+        self.assertFalse(router['router']['distributed'])
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('acd43596-c1fb-439d-ada8-31ad48ae3c2e')
+    def test_centralized_router_update_to_dvr(self):
+        """
+        Test uses administrative credentials to creates a
+        CVR (Centralized Virtual Routing) router using the
+        distributed=False.Then it will "update" the router
+        distributed attribute to True
+
+        Acceptance
+        The router is created and the "distributed" attribute is
+        set to False. Once the router is updated, the distributed
+        attribute will be set to True
+        """
+        name = data_utils.rand_name('router')
+        router = self.admin_client.create_router(name, distributed=False)
+        self.addCleanup(self.admin_client.delete_router,
+                        router['router']['id'])
+        self.assertFalse(router['router']['distributed'])
+        router = self.admin_client.update_router(router['router']['id'],
+                                                 distributed=True)
+        self.assertTrue(router['router']['distributed'])
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 10cda53..e8c8de3 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 import netaddr
+from tempest_lib import exceptions as lib_exc
 
 from tempest import clients
 from tempest.common.utils import data_utils
@@ -49,7 +50,6 @@
         neutron as True
     """
 
-    _interface = 'json'
     force_tenant_isolation = False
 
     # Default to ipv4.
@@ -177,7 +177,7 @@
         try:
             delete_callable(*args, **kwargs)
         # if resource is not found, this means it was deleted in the test
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
 
     @classmethod
@@ -223,7 +223,7 @@
                     gateway_ip=gateway_ip,
                     **kwargs)
                 break
-            except exceptions.BadRequest as e:
+            except lib_exc.BadRequest as e:
                 is_overlapping_cidr = 'overlaps with another subnet' in str(e)
                 if not is_overlapping_cidr:
                     raise
@@ -399,7 +399,7 @@
             try:
                 cls.client.remove_router_interface_with_subnet_id(
                     router['id'], i['fixed_ips'][0]['subnet_id'])
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
         cls.client.delete_router(router['id'])
 
@@ -420,8 +420,7 @@
 
         try:
             creds = cls.isolated_creds.get_admin_creds()
-            cls.os_adm = clients.Manager(
-                credentials=creds, interface=cls._interface)
+            cls.os_adm = clients.Manager(credentials=creds)
         except NotImplementedError:
             msg = ("Missing Administrative Network API credentials "
                    "in configuration.")
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index 57887ac..99bd82c 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -23,7 +23,6 @@
 
 
 class AllowedAddressPairTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     """
     Tests the Neutron Allowed Address Pair API extension using the Tempest
@@ -54,6 +53,7 @@
         cls.mac_address = port['mac_address']
 
     @test.attr(type='smoke')
+    @test.idempotent_id('86c3529b-1231-40de-803c-00e40882f043')
     def test_create_list_port_with_address_pair(self):
         # Create port with allowed address pair attribute
         allowed_address_pairs = [{'ip_address': self.ip_address,
@@ -92,17 +92,20 @@
         self.assertEqual(allowed_address_pair, allowed_address_pairs)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9599b337-272c-47fd-b3cf-509414414ac4')
     def test_update_port_with_address_pair(self):
         # Update port with allowed address pair
         self._update_port_with_address(self.ip_address)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4d6d178f-34f6-4bff-a01c-0a2f8fe909e4')
     def test_update_port_with_cidr_address_pair(self):
         # Update allowed address pair with cidr
         cidr = str(netaddr.IPNetwork(CONF.network.tenant_network_cidr))
         self._update_port_with_address(cidr)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
     def test_update_port_with_multiple_ip_mac_address_pair(self):
         # Create an ip _address and mac_address through port create
         resp = self.client.create_port(network_id=self.network['id'])
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 1257699..5168219 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -16,10 +16,12 @@
 import netaddr
 import random
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
+from tempest import test
 
 CONF = config.CONF
 
@@ -93,6 +95,7 @@
                                                    port_mac).format()
         return real_ip, eui_ip
 
+    @test.idempotent_id('e5517e62-6f16-430d-a672-f80875493d4c')
     def test_dhcpv6_stateless_eui64(self):
         """When subnets configured with RAs SLAAC (AOM=100) and DHCP stateless
         (AOM=110) both for radvd and dnsmasq, port shall receive IP address
@@ -111,6 +114,7 @@
                               'ipv6_ra_mode=%s and ipv6_address_mode=%s') % (
                                  real_ip, eui_ip, ra_mode, add_mode))
 
+    @test.idempotent_id('ae2f4a5d-03ff-4c42-a3b0-ce2fcb7ea832')
     def test_dhcpv6_stateless_no_ra(self):
         """When subnets configured with dnsmasq SLAAC and DHCP stateless
         and there is no radvd, port shall receive IP address calculated
@@ -132,6 +136,7 @@
                                  ra_mode if ra_mode else "Off",
                                  add_mode if add_mode else "Off"))
 
+    @test.idempotent_id('81f18ef6-95b5-4584-9966-10d480b7496a')
     def test_dhcpv6_invalid_options(self):
         """Different configurations for radvd and dnsmasq are not allowed"""
         for ra_mode, add_mode in (
@@ -144,11 +149,12 @@
         ):
             kwargs = {'ipv6_ra_mode': ra_mode,
                       'ipv6_address_mode': add_mode}
-            self.assertRaises(exceptions.BadRequest,
+            self.assertRaises(lib_exc.BadRequest,
                               self.create_subnet,
                               self.network,
                               **kwargs)
 
+    @test.idempotent_id('21635b6f-165a-4d42-bf49-7d195e47342f')
     def test_dhcpv6_stateless_no_ra_no_dhcp(self):
         """If no radvd option and no dnsmasq option is configured
         port shall receive IP from fixed IPs list of subnet.
@@ -161,6 +167,7 @@
                              'but shall be taken from fixed IPs') % (
                                 real_ip, eui_ip))
 
+    @test.idempotent_id('4544adf7-bb5f-4bdc-b769-b3e77026cef2')
     def test_dhcpv6_two_subnets(self):
         """When one IPv6 subnet configured with dnsmasq SLAAC or DHCP stateless
         and other IPv6 is with DHCP stateful, port shall receive EUI-64 IP
@@ -214,6 +221,7 @@
                         real_dhcp_ip,
                         str(dhcp_ip)))
 
+    @test.idempotent_id('4256c61d-c538-41ea-9147-3c450c36669e')
     def test_dhcpv6_64_subnets(self):
         """When one IPv6 subnet configured with dnsmasq SLAAC or DHCP stateless
         and other IPv4 is with DHCP of IPv4, port shall receive EUI-64 IP
@@ -263,6 +271,7 @@
                         real_dhcp_ip,
                         str(dhcp_ip)))
 
+    @test.idempotent_id('4ab211a0-276f-4552-9070-51e27f58fecf')
     def test_dhcp_stateful(self):
         """With all options below, DHCPv6 shall allocate first
         address from subnet pool to port.
@@ -288,6 +297,7 @@
                     port_ip,
                     str(dhcp_ip)))
 
+    @test.idempotent_id('51a5e97f-f02e-4e4e-9a17-a69811d300e3')
     def test_dhcp_stateful_fixedips(self):
         """With all options below, port shall be able to get
         requested IP from fixed IP range not depending on
@@ -316,6 +326,7 @@
                               "port create request: %s") % (
                                  port_ip, ip))
 
+    @test.idempotent_id('98244d88-d990-4570-91d4-6b25d70d08af')
     def test_dhcp_stateful_fixedips_outrange(self):
         """When port gets IP address from fixed IP range it
         shall be checked if it's from subnets range.
@@ -327,12 +338,13 @@
                                    subnet["allocation_pools"][0]["end"])
         ip = netaddr.IPAddress(random.randrange(
             ip_range.last + 1, ip_range.last + 10)).format()
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.create_port,
                           self.network,
                           fixed_ips=[{'subnet_id': subnet['id'],
                                       'ip_address': ip}])
 
+    @test.idempotent_id('57b8302b-cba9-4fbb-8835-9168df029051')
     def test_dhcp_stateful_fixedips_duplicate(self):
         """When port gets IP address from fixed IP range it
         shall be checked if it's not duplicate.
@@ -348,7 +360,7 @@
                          fixed_ips=[
                              {'subnet_id': subnet['id'],
                               'ip_address': ip}])
-        self.assertRaisesRegexp(exceptions.Conflict,
+        self.assertRaisesRegexp(lib_exc.Conflict,
                                 "object with that identifier already exists",
                                 self.create_port,
                                 self.network,
@@ -365,6 +377,7 @@
         body = self.client.show_port(port['port_id'])
         return subnet, body['port']
 
+    @test.idempotent_id('e98f65db-68f4-4330-9fea-abd8c5192d4d')
     def test_dhcp_stateful_router(self):
         """With all options below the router interface shall
         receive DHCPv6 IP address from allocation pool.
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index 54c3cb9..bce8efe 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -19,7 +19,6 @@
 
 
 class ExtensionsTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -37,6 +36,7 @@
         super(ExtensionsTestJSON, cls).resource_setup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
     def test_list_show_extensions(self):
         # List available extensions for the tenant
         expected_alias = ['security-group', 'l3_agent_scheduler',
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index bd70323..612c20a 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -19,7 +19,6 @@
 
 
 class ExtraDHCPOptionsTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations with the Extra DHCP Options Neutron API
@@ -55,6 +54,7 @@
         ]
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d2c17063-3767-4a24-be4f-a23dbfa133c9')
     def test_create_list_port_with_extra_dhcp_options(self):
         # Create a port with Extra DHCP Options
         body = self.client.create_port(
@@ -71,6 +71,7 @@
         self._confirm_extra_dhcp_options(port[0], self.extra_dhcp_opts)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9a6aebf4-86ee-4f47-b07a-7f7232c55607')
     def test_update_show_port_with_extra_dhcp_options(self):
         # Update port with extra dhcp options
         name = data_utils.rand_name('new-port-name')
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 1151c5d..cc88852 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -24,7 +24,6 @@
 
 
 class FloatingIPTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Quantum API using the REST client for
@@ -65,6 +64,7 @@
             cls.create_port(cls.network)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
     def test_create_list_show_update_delete_floating_ip(self):
         # Creates a floating IP
         body = self.client.create_floatingip(
@@ -119,6 +119,7 @@
         self.assertIsNone(updated_floating_ip['router_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
     def test_floating_ip_delete_port(self):
         # Create a floating IP
         body = self.client.create_floatingip(
@@ -144,6 +145,7 @@
         self.assertIsNone(shown_floating_ip['router_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1bb2f731-fe5a-4b8c-8409-799ade1bed4d')
     def test_floating_ip_update_different_router(self):
         # Associate a floating IP to a port on a router
         body = self.client.create_floatingip(
@@ -170,6 +172,7 @@
         self.assertIsNotNone(updated_floating_ip['fixed_ip_address'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5')
     def test_create_floating_ip_specifying_a_fixed_ip_address(self):
         body = self.client.create_floatingip(
             floating_network_id=self.ext_net_id,
@@ -187,6 +190,7 @@
         self.assertIsNone(floating_ip['floatingip']['port_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('45c4c683-ea97-41ef-9c51-5e9802f2f3d7')
     def test_create_update_floatingip_with_port_multiple_ip_address(self):
         # Find out ips that can be used for tests
         ips = list(netaddr.IPNetwork(self.subnet['cidr']))
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index 82f0519..c4c547c 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -14,17 +14,18 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
 class FloatingIPNegativeTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
+
     """
     Test the following negative  operations for floating ips:
 
@@ -48,16 +49,18 @@
         cls.port = cls.create_port(cls.network)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('22996ea8-4a81-4b27-b6e1-fa5df92fa5e8')
     def test_create_floatingip_with_port_ext_net_unreachable(self):
-        self.assertRaises(exceptions.NotFound, self.client.create_floatingip,
+        self.assertRaises(lib_exc.NotFound, self.client.create_floatingip,
                           floating_network_id=self.ext_net_id,
                           port_id=self.port['id'],
                           fixed_ip_address=self.port['fixed_ips'][0]
                                                     ['ip_address'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('50b9aeb4-9f0b-48ee-aa31-fa955a48ff54')
     def test_create_floatingip_in_private_network(self):
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.create_floatingip,
                           floating_network_id=self.network['id'],
                           port_id=self.port['id'],
@@ -65,6 +68,7 @@
                                                     ['ip_address'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('6b3b8797-6d43-4191-985c-c48b773eb429')
     def test_associate_floatingip_port_ext_net_unreachable(self):
         # Create floating ip
         body = self.client.create_floatingip(
@@ -72,7 +76,7 @@
         floating_ip = body['floatingip']
         self.addCleanup(self.client.delete_floatingip, floating_ip['id'])
         # Associate floating IP to the other port
-        self.assertRaises(exceptions.NotFound, self.client.update_floatingip,
+        self.assertRaises(lib_exc.NotFound, self.client.update_floatingip,
                           floating_ip['id'], port_id=self.port['id'],
                           fixed_ip_address=self.port['fixed_ips'][0]
                           ['ip_address'])
diff --git a/tempest/api/network/test_fwaas_extensions.py b/tempest/api/network/test_fwaas_extensions.py
index 8104567..d97a60c 100644
--- a/tempest/api/network/test_fwaas_extensions.py
+++ b/tempest/api/network/test_fwaas_extensions.py
@@ -12,6 +12,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import config
@@ -22,7 +24,6 @@
 
 
 class FWaaSExtensionTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -63,7 +64,7 @@
         try:
             self.client.delete_firewall_policy(policy_id)
         # if policy is not found, this means it was deleted in the test
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
 
     def _try_delete_rule(self, rule_id):
@@ -71,7 +72,7 @@
         try:
             self.client.delete_firewall_rule(rule_id)
         # if rule is not found, this means it was deleted in the test
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
 
     def _try_delete_firewall(self, fw_id):
@@ -79,7 +80,7 @@
         try:
             self.client.delete_firewall(fw_id)
         # if firewall is not found, this means it was deleted in the test
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
 
         self.client.wait_for_resource_deletion('firewall', fw_id)
@@ -98,6 +99,7 @@
                  (fw_id, target_states))
             raise exceptions.TimeoutException(m)
 
+    @test.idempotent_id('1b84cf01-9c09-4ce7-bc72-b15e39076468')
     def test_list_firewall_rules(self):
         # List firewall rules
         fw_rules = self.client.list_firewall_rules()
@@ -115,6 +117,7 @@
                         m['ip_version'],
                         m['enabled']) for m in fw_rules])
 
+    @test.idempotent_id('563564f7-7077-4f5e-8cdc-51f37ae5a2b9')
     def test_create_update_delete_firewall_rule(self):
         # Create firewall rule
         body = self.client.create_firewall_rule(
@@ -135,12 +138,14 @@
         self.assertNotIn(fw_rule_id,
                          [m['id'] for m in fw_rules['firewall_rules']])
 
+    @test.idempotent_id('3ff8c08e-26ff-4034-ae48-810ed213a998')
     def test_show_firewall_rule(self):
         # show a created firewall rule
         fw_rule = self.client.show_firewall_rule(self.fw_rule['id'])
         for key, value in fw_rule['firewall_rule'].iteritems():
             self.assertEqual(self.fw_rule[key], value)
 
+    @test.idempotent_id('1086dd93-a4c0-4bbb-a1bd-6d4bc62c199f')
     def test_list_firewall_policies(self):
         fw_policies = self.client.list_firewall_policies()
         fw_policies = fw_policies['firewall_policies']
@@ -151,6 +156,7 @@
                         m['name'],
                         m['firewall_rules']) for m in fw_policies])
 
+    @test.idempotent_id('bbf37b6c-498c-421e-9c95-45897d3ed775')
     def test_create_update_delete_firewall_policy(self):
         # Create firewall policy
         body = self.client.create_firewall_policy(
@@ -173,6 +179,7 @@
         fw_policies = fw_policies['firewall_policies']
         self.assertNotIn(fw_policy_id, [m['id'] for m in fw_policies])
 
+    @test.idempotent_id('1df59b3a-517e-41d4-96f6-fc31cf4ecff2')
     def test_show_firewall_policy(self):
         # show a created firewall policy
         fw_policy = self.client.show_firewall_policy(self.fw_policy['id'])
@@ -180,6 +187,7 @@
         for key, value in fw_policy.iteritems():
             self.assertEqual(self.fw_policy[key], value)
 
+    @test.idempotent_id('02082a03-3cdd-4789-986a-1327dd80bfb7')
     def test_create_show_delete_firewall(self):
         # Create tenant network resources required for an ACTIVE firewall
         network = self.create_network()
@@ -224,6 +232,7 @@
         self.client.delete_firewall(firewall_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('53305b4b-9897-4e01-87c0-2ae386083180')
     def test_firewall_rule_insertion_position_removal_rule_from_policy(self):
         # Create firewall rule
         body = self.client.create_firewall_rule(
@@ -290,6 +299,7 @@
         return [ruleid for ruleid in fw_policy['firewall_policy']
                 ['firewall_rules']]
 
+    @test.idempotent_id('8515ca8a-0d2f-4298-b5ff-6f924e4587ca')
     def test_update_firewall_policy_audited_attribute(self):
         # Create firewall rule
         body = self.client.create_firewall_rule(
diff --git a/tempest/api/network/test_load_balancer.py b/tempest/api/network/test_load_balancer.py
index df76757..6872dfa 100644
--- a/tempest/api/network/test_load_balancer.py
+++ b/tempest/api/network/test_load_balancer.py
@@ -21,7 +21,6 @@
 
 
 class LoadBalancerTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -82,6 +81,7 @@
                 self.assertIn(value, objs)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c96dbfab-4a80-4e74-a535-e950b5bedd47')
     def test_list_vips(self):
         # Verify the vIP exists in the list of all vIPs
         body = self.client.list_vips()
@@ -89,6 +89,7 @@
         self.assertIn(self.vip['id'], [v['id'] for v in vips])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b8853f65-5089-4e69-befd-041a143427ff')
     def test_list_vips_with_filter(self):
         name = data_utils.rand_name('vip-')
         body = self.client.create_pool(name=data_utils.rand_name("pool-"),
@@ -106,6 +107,7 @@
             admin_state_up=False)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('27f56083-9af9-4a48-abe9-ca1bcc6c9035')
     def test_create_update_delete_pool_vip(self):
         # Creates a vip
         name = data_utils.rand_name('vip-')
@@ -162,6 +164,7 @@
         self.client.delete_pool(pool['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0435a95e-1d19-4d90-9e9f-3b979e9ad089')
     def test_show_vip(self):
         # Verifies the details of a vip
         body = self.client.show_vip(self.vip['id'])
@@ -172,6 +175,7 @@
                 self.assertEqual(self.vip[key], value)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6e7a7d31-8451-456d-b24a-e50479ce42a7')
     def test_show_pool(self):
         # Here we need to new pool without any dependence with vips
         body = self.client.create_pool(name=data_utils.rand_name("pool-"),
@@ -189,6 +193,7 @@
                 self.assertEqual(value, shown_pool[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d1ab1ffa-e06a-487f-911f-56418cb27727')
     def test_list_pools(self):
         # Verify the pool exists in the list of all pools
         body = self.client.list_pools()
@@ -196,6 +201,7 @@
         self.assertIn(self.pool['id'], [p['id'] for p in pools])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('27cc4c1a-caac-4273-b983-2acb4afaad4f')
     def test_list_pools_with_filters(self):
         attr_exceptions = ['status', 'vip_id', 'members', 'provider',
                            'status_description']
@@ -207,6 +213,7 @@
             admin_state_up=False)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('282d0dfd-5c3a-4c9b-b39c-c99782f39193')
     def test_list_members(self):
         # Verify the member exists in the list of all members
         body = self.client.list_members()
@@ -214,6 +221,7 @@
         self.assertIn(self.member['id'], [m['id'] for m in members])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('243b5126-24c6-4879-953e-7c7e32d8a57f')
     def test_list_members_with_filters(self):
         attr_exceptions = ['status', 'status_description']
         self._check_list_with_filter('member', attr_exceptions,
@@ -222,6 +230,7 @@
                                      pool_id=self.pool['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fb833ee8-9e69-489f-b540-a409762b78b2')
     def test_create_update_delete_member(self):
         # Creates a member
         body = self.client.create_member(address=self.member_address,
@@ -237,6 +246,7 @@
         self.client.delete_member(member['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('893cd71f-a7dd-4485-b162-f6ab9a534914')
     def test_show_member(self):
         # Verifies the details of a member
         body = self.client.show_member(self.member['id'])
@@ -247,6 +257,7 @@
                 self.assertEqual(self.member[key], value)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8e5822c5-68a4-4224-8d6c-a617741ebc2d')
     def test_list_health_monitors(self):
         # Verify the health monitor exists in the list of all health monitors
         body = self.client.list_health_monitors()
@@ -255,6 +266,7 @@
                       [h['id'] for h in health_monitors])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('49bac58a-511c-4875-b794-366698211d25')
     def test_list_health_monitors_with_filters(self):
         attr_exceptions = ['status', 'status_description', 'pools']
         self._check_list_with_filter('health_monitor', attr_exceptions,
@@ -262,6 +274,7 @@
                                      timeout=2)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e8ce05c4-d554-4d1e-a257-ad32ce134bb5')
     def test_create_update_delete_health_monitor(self):
         # Creates a health_monitor
         body = self.client.create_health_monitor(delay=4,
@@ -279,6 +292,7 @@
         body = self.client.delete_health_monitor(health_monitor['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d3e1aebc-06c2-49b3-9816-942af54012eb')
     def test_create_health_monitor_http_type(self):
         hm_type = "HTTP"
         body = self.client.create_health_monitor(delay=4,
@@ -291,6 +305,7 @@
         self.assertEqual(hm_type, health_monitor['type'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0eff9f67-90fb-4bb1-b4ed-c5fda99fff0c')
     def test_update_health_monitor_http_method(self):
         body = self.client.create_health_monitor(delay=4,
                                                  max_retries=3,
@@ -310,6 +325,7 @@
         self.assertEqual("290", updated_health_monitor['expected_codes'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('08e126ab-1407-483f-a22e-b11cc032ca7c')
     def test_show_health_monitor(self):
         # Verifies the details of a health_monitor
         body = self.client.show_health_monitor(self.health_monitor['id'])
@@ -320,6 +336,7 @@
                 self.assertEqual(self.health_monitor[key], value)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('87f7628e-8918-493d-af50-0602845dbb5b')
     def test_associate_disassociate_health_monitor_with_pool(self):
         # Verify that a health monitor can be associated with a pool
         self.client.associate_health_monitor_with_pool(
@@ -345,6 +362,7 @@
                          [p['pool_id'] for p in health_monitor['pools']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('525fc7dc-be24-408d-938d-822e9783e027')
     def test_get_lb_pool_stats(self):
         # Verify the details of pool stats
         body = self.client.list_lb_pool_stats(self.pool['id'])
@@ -355,6 +373,7 @@
         self.assertIn("bytes_out", stats)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('66236be2-5121-4047-8cde-db4b83b110a5')
     def test_update_list_of_health_monitors_associated_with_pool(self):
         (self.client.associate_health_monitor_with_pool
             (self.health_monitor['id'], self.pool['id']))
@@ -369,6 +388,7 @@
                 (self.health_monitor['id'], self.pool['id']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('44ec9b40-b501-41e2-951f-4fc673b15ac0')
     def test_update_admin_state_up_of_pool(self):
         self.client.update_pool(self.pool['id'],
                                 admin_state_up=False)
@@ -377,6 +397,7 @@
         self.assertFalse(pool['admin_state_up'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('466a9d4c-37c6-4ea2-b807-133437beb48c')
     def test_show_vip_associated_with_pool(self):
         body = self.client.show_pool(self.pool['id'])
         pool = body['pool']
@@ -386,6 +407,7 @@
         self.assertEqual(self.vip['id'], vip['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7b97694e-69d0-4151-b265-e1052a465aa8')
     def test_show_members_associated_with_pool(self):
         body = self.client.show_pool(self.pool['id'])
         members = body['pool']['members']
@@ -396,6 +418,7 @@
             self.assertIsNotNone(body['member']['admin_state_up'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('73ed6f27-595b-4b2c-969c-dbdda6b8ab34')
     def test_update_pool_related_to_member(self):
         # Create new pool
         body = self.client.create_pool(name=data_utils.rand_name("pool-"),
@@ -416,6 +439,7 @@
                                          pool_id=self.pool['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cf63f071-bbe3-40ba-97a0-a33e11923162')
     def test_update_member_weight(self):
         self.client.update_member(self.member['id'],
                                   weight=2)
diff --git a/tempest/api/network/test_metering_extensions.py b/tempest/api/network/test_metering_extensions.py
index 6ba1ea4..8e4ee87 100644
--- a/tempest/api/network/test_metering_extensions.py
+++ b/tempest/api/network/test_metering_extensions.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
 #
-# Author: Emilien Macchi <emilien.macchi@enovance.com>
-#
 # 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
@@ -24,7 +22,6 @@
 
 
 class MeteringTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -67,6 +64,7 @@
         self.assertEqual(len(rules['metering_label_rules']), 0)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e2fb2f8c-45bf-429a-9f17-171c70444612')
     def test_list_metering_labels(self):
         # Verify label filtering
         body = self.admin_client.list_metering_labels(id=33)
@@ -74,6 +72,7 @@
         self.assertEqual(0, len(metering_labels))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ec8e15ff-95d0-433b-b8a6-b466bddb1e50')
     def test_create_delete_metering_label_with_filters(self):
         # Creates a label
         name = data_utils.rand_name('metering-label-')
@@ -90,6 +89,7 @@
         self.assertEqual(len(labels['metering_labels']), 1)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('30abb445-0eea-472e-bd02-8649f54a5968')
     def test_show_metering_label(self):
         # Verifies the details of a label
         body = self.admin_client.show_metering_label(self.metering_label['id'])
@@ -102,6 +102,7 @@
                          metering_label['description'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cc832399-6681-493b-9d79-0202831a1281')
     def test_list_metering_label_rules(self):
         # Verify rule filtering
         body = self.admin_client.list_metering_label_rules(id=33)
@@ -109,6 +110,7 @@
         self.assertEqual(0, len(metering_label_rules))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f4d547cd-3aee-408f-bf36-454f8825e045')
     def test_create_delete_metering_label_rule_with_filters(self):
         # Creates a rule
         remote_ip_prefix = ("10.0.1.0/24" if self._ip_version == 4
@@ -127,6 +129,7 @@
         self.assertEqual(len(rules['metering_label_rules']), 1)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b7354489-96ea-41f3-9452-bace120fb4a7')
     def test_show_metering_label_rule(self):
         # Verifies the details of a rule
         body = (self.admin_client.show_metering_label_rule(
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 65aeb24..0801045 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -15,19 +15,18 @@
 import itertools
 
 import netaddr
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.network import base
 from tempest.common import custom_matchers
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
 class NetworksTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -178,6 +177,7 @@
         self.subnets.pop()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
     def test_create_update_delete_network_subnet(self):
         # Create a network
         name = data_utils.rand_name('network-')
@@ -200,6 +200,7 @@
         self.assertEqual(updated_subnet['name'], new_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
     def test_show_network(self):
         # Verify the details of a network
         body = self.client.show_network(self.network['id'])
@@ -208,6 +209,7 @@
             self.assertEqual(network[key], self.network[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
     def test_show_network_fields(self):
         # Verify specific fields of a network
         fields = ['id', 'name']
@@ -219,6 +221,7 @@
             self.assertEqual(network[field_name], self.network[field_name])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
     def test_list_networks(self):
         # Verify the network exists in the list of all networks
         body = self.client.list_networks()
@@ -227,6 +230,7 @@
         self.assertNotEmpty(networks, "Created network not found in the list")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
     def test_list_networks_fields(self):
         # Verify specific fields of the networks
         fields = ['id', 'name']
@@ -237,6 +241,7 @@
             self.assertEqual(sorted(network.keys()), sorted(fields))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
     def test_show_subnet(self):
         # Verify the details of a subnet
         body = self.client.show_subnet(self.subnet['id'])
@@ -247,6 +252,7 @@
             self.assertEqual(subnet[key], self.subnet[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
     def test_show_subnet_fields(self):
         # Verify specific fields of a subnet
         fields = ['id', 'network_id']
@@ -258,6 +264,7 @@
             self.assertEqual(subnet[field_name], self.subnet[field_name])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
     def test_list_subnets(self):
         # Verify the subnet exists in the list of all subnets
         body = self.client.list_subnets()
@@ -266,6 +273,7 @@
         self.assertNotEmpty(subnets, "Created subnet not found in the list")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
     def test_list_subnets_fields(self):
         # Verify specific fields of subnets
         fields = ['id', 'network_id']
@@ -280,10 +288,11 @@
         try:
             self.client.delete_network(net_id)
         # if network is not found, this means it was deleted in the test
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
     def test_delete_network_with_subnet(self):
         # Creates a network
         name = data_utils.rand_name('network-')
@@ -300,7 +309,7 @@
         body = self.client.delete_network(net_id)
 
         # Verify that the subnet got automatically deleted.
-        self.assertRaises(exceptions.NotFound, self.client.show_subnet,
+        self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
                           subnet_id)
 
         # Since create_subnet adds the subnet to the delete list, and it is
@@ -309,34 +318,41 @@
         self.subnets.pop()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
     def test_create_delete_subnet_without_gateway(self):
         self._create_verify_delete_subnet()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
     def test_create_delete_subnet_with_gw(self):
         self._create_verify_delete_subnet(
             **self.subnet_dict(['gateway']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
     def test_create_delete_subnet_with_allocation_pools(self):
         self._create_verify_delete_subnet(
             **self.subnet_dict(['allocation_pools']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
     def test_create_delete_subnet_with_gw_and_allocation_pools(self):
         self._create_verify_delete_subnet(**self.subnet_dict(
             ['gateway', 'allocation_pools']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
     def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
         self._create_verify_delete_subnet(
             **self.subnet_dict(['host_routes', 'dns_nameservers']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
     def test_create_delete_subnet_with_dhcp_enabled(self):
         self._create_verify_delete_subnet(enable_dhcp=True)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
     def test_update_subnet_gw_dns_host_routes_dhcp(self):
         network = self.create_network()
         self.addCleanup(self._delete_network, network)
@@ -370,12 +386,14 @@
         self._compare_resource_attrs(updated_subnet, kwargs)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
     def test_create_delete_subnet_all_attributes(self):
         self._create_verify_delete_subnet(
             enable_dhcp=True,
             **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
     def test_external_network_visibility(self):
         """Verifies user can see external networks but not subnets."""
         body = self.client.list_networks(**{'router:external': True})
@@ -399,7 +417,6 @@
 
 
 class BulkNetworkOpsTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -448,6 +465,7 @@
             self.assertNotIn(n['id'], ports_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
     def test_bulk_create_delete_network(self):
         # Creates 2 networks in one request
         network_names = [data_utils.rand_name('network-'),
@@ -463,23 +481,27 @@
             self.assertIn(n['id'], networks_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
     def test_bulk_create_delete_subnet(self):
         networks = [self.create_network(), self.create_network()]
         # Creates 2 subnets in one request
-        cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-        mask_bits = CONF.network.tenant_network_mask_bits
+        if self._ip_version == 4:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+            mask_bits = CONF.network.tenant_network_mask_bits
+        else:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+            mask_bits = CONF.network.tenant_network_v6_mask_bits
+
         cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
+
         names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
         subnets_list = []
-        # TODO(raies): "for IPv6, version list [4, 6] will be used.
-        # and cidr for IPv6 will be of IPv6"
-        ip_version = [4, 4]
         for i in range(len(names)):
             p1 = {
                 'network_id': networks[i]['id'],
                 'cidr': str(cidrs[(i)]),
                 'name': names[i],
-                'ip_version': ip_version[i]
+                'ip_version': self._ip_version
             }
             subnets_list.append(p1)
         del subnets_list[1]['name']
@@ -494,6 +516,7 @@
             self.assertIn(n['id'], subnets_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
     def test_bulk_create_delete_port(self):
         networks = [self.create_network(), self.create_network()]
         # Creates 2 ports in one request
@@ -519,10 +542,15 @@
             self.assertIn(n['id'], ports_list)
 
 
+class BulkNetworkOpsIpV6TestJSON(BulkNetworkOpsTestJSON):
+    _ip_version = 6
+
+
 class NetworksIpV6TestJSON(NetworksTestJSON):
     _ip_version = 6
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
     def test_create_delete_subnet_with_gw(self):
         net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
         gateway = str(netaddr.IPAddress(net.first + 2))
@@ -533,6 +561,7 @@
         self.assertEqual(subnet['gateway_ip'], gateway)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
     def test_create_delete_subnet_with_default_gw(self):
         net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
         gateway_ip = str(netaddr.IPAddress(net.first + 1))
@@ -543,6 +572,7 @@
         self.assertEqual(subnet['gateway_ip'], gateway_ip)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
     def test_create_list_subnet_with_no_gw64_one_network(self):
         name = data_utils.rand_name('network-')
         network = self.create_network(name)
@@ -581,6 +611,7 @@
         super(NetworksIpV6TestAttrs, cls).resource_setup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
     def test_create_delete_subnet_with_v6_attributes_stateful(self):
         self._create_verify_delete_subnet(
             gateway=self._subnet_data[self._ip_version]['gateway'],
@@ -588,12 +619,14 @@
             ipv6_address_mode='dhcpv6-stateful')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
     def test_create_delete_subnet_with_v6_attributes_slaac(self):
         self._create_verify_delete_subnet(
             ipv6_ra_mode='slaac',
             ipv6_address_mode='slaac')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
     def test_create_delete_subnet_with_v6_attributes_stateless(self):
         self._create_verify_delete_subnet(
             ipv6_ra_mode='dhcpv6-stateless',
@@ -614,12 +647,13 @@
         self.assertNotIn(subnet_slaac['id'], subnet_ids,
                          "Subnet wasn't deleted")
         self.assertRaisesRegexp(
-            exceptions.Conflict,
+            lib_exc.Conflict,
             "There are one or more ports still in use on the network",
             self.client.delete_network,
             slaac_network['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
     def test_create_delete_slaac_subnet_with_ports(self):
         """Test deleting subnet with SLAAC ports
 
@@ -630,6 +664,7 @@
         self._test_delete_subnet_with_ports("slaac")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
     def test_create_delete_stateless_subnet_with_ports(self):
         """Test deleting subnet with DHCPv6 stateless ports
 
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index bc3ab68..1002295 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -14,41 +14,46 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.network import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class NetworksNegativeTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
     def test_show_non_existent_network(self):
         non_exist_id = data_utils.rand_name('network')
-        self.assertRaises(exceptions.NotFound, self.client.show_network,
+        self.assertRaises(lib_exc.NotFound, self.client.show_network,
                           non_exist_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
     def test_show_non_existent_subnet(self):
         non_exist_id = data_utils.rand_name('subnet')
-        self.assertRaises(exceptions.NotFound, self.client.show_subnet,
+        self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
                           non_exist_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('a954861d-cbfd-44e8-b0a9-7fab111f235d')
     def test_show_non_existent_port(self):
         non_exist_id = data_utils.rand_name('port')
-        self.assertRaises(exceptions.NotFound, self.client.show_port,
+        self.assertRaises(lib_exc.NotFound, self.client.show_port,
                           non_exist_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('98bfe4e3-574e-4012-8b17-b2647063de87')
     def test_update_non_existent_network(self):
         non_exist_id = data_utils.rand_name('network')
-        self.assertRaises(exceptions.NotFound, self.client.update_network,
+        self.assertRaises(lib_exc.NotFound, self.client.update_network,
                           non_exist_id, name="new_name")
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('03795047-4a94-4120-a0a1-bd376e36fd4e')
     def test_delete_non_existent_network(self):
         non_exist_id = data_utils.rand_name('network')
-        self.assertRaises(exceptions.NotFound, self.client.delete_network,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_network,
                           non_exist_id)
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index bf85e90..33211fc 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -27,7 +27,6 @@
 
 
 class PortsTestJSON(sec_base.BaseSecGroupTest):
-    _interface = 'json'
 
     """
     Test the following operations for ports:
@@ -52,6 +51,7 @@
         self.assertFalse(port_id in [n['id'] for n in ports_list])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c72c1c0c-2193-4aca-aaa4-b1442640f51c')
     def test_create_update_delete_port(self):
         # Verify port creation
         body = self.client.create_port(network_id=self.network['id'])
@@ -68,6 +68,7 @@
         self.assertEqual(updated_port['name'], new_name)
         self.assertFalse(updated_port['admin_state_up'])
 
+    @test.idempotent_id('67f1b811-f8db-43e2-86bd-72c074d4a42c')
     def test_create_bulk_port(self):
         network1 = self.network
         name = data_utils.rand_name('network-')
@@ -97,6 +98,7 @@
         return netaddr.IPAddress(cidr)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0435f278-40ae-48cb-a404-b8a087bc09b1')
     def test_create_port_in_allowed_allocation_pools(self):
         network = self.create_network()
         net_id = network['id']
@@ -115,6 +117,7 @@
         self.assertIn(ip_address, ip_range)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
     def test_show_port(self):
         # Verify the details of port
         body = self.client.show_port(self.port['id'])
@@ -128,6 +131,7 @@
                         (port, excluded_keys=['extra_dhcp_opts']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd')
     def test_show_port_fields(self):
         # Verify specific fields of a port
         fields = ['id', 'mac_address']
@@ -139,6 +143,7 @@
             self.assertEqual(port[field_name], self.port[field_name])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cf95b358-3e92-4a29-a148-52445e1ac50e')
     def test_list_ports(self):
         # Verify the port exists in the list of all ports
         body = self.client.list_ports()
@@ -147,6 +152,7 @@
         self.assertNotEmpty(ports, "Created port not found in the list")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5ad01ed0-0e6e-4c5d-8194-232801b15c72')
     def test_port_list_filter_by_router_id(self):
         # Create a router
         network = self.create_network()
@@ -169,6 +175,7 @@
         self.assertEqual(ports[0]['device_id'], router['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ff7f117f-f034-4e0e-abff-ccef05c454b4')
     def test_list_ports_fields(self):
         # Verify specific fields of ports
         fields = ['id', 'mac_address']
@@ -180,6 +187,7 @@
             self.assertEqual(sorted(fields), sorted(port.keys()))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('63aeadd4-3b49-427f-a3b1-19ca81f06270')
     def test_create_update_port_with_second_ip(self):
         # Create a network with two subnets
         network = self.create_network()
@@ -260,17 +268,20 @@
             self.assertIn(security_group, port_show['security_groups'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('58091b66-4ff4-4cc1-a549-05d60c7acd1a')
     def test_update_port_with_security_group_and_extra_attributes(self):
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup')])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('edf6766d-3d40-4621-bc6e-2521a44c257d')
     def test_update_port_with_two_security_groups_and_extra_attributes(self):
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup'),
              data_utils.rand_name('secgroup')])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('13e95171-6cbd-489c-9d7c-3f9c58215c18')
     def test_create_show_delete_port_user_defined_mac(self):
         # Create a port for a legal mac
         body = self.client.create_port(network_id=self.network['id'])
@@ -288,6 +299,7 @@
                          show_port['mac_address'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4179dcb9-1382-4ced-84fe-1b91c54f5735')
     def test_create_port_with_no_securitygroups(self):
         network = self.create_network()
         self.addCleanup(self.client.delete_network, network['id'])
@@ -300,7 +312,6 @@
 
 
 class PortsAdminExtendedAttrsTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -312,6 +323,7 @@
         cls.host_id = socket.gethostname()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8e8569c1-9ac7-44db-8bc1-f5fb2814f29b')
     def test_create_port_binding_ext_attr(self):
         post_body = {"network_id": self.network['id'],
                      "binding:host_id": self.host_id}
@@ -323,6 +335,7 @@
         self.assertEqual(self.host_id, host_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6f6c412c-711f-444d-8502-0ac30fbf5dd5')
     def test_update_port_binding_ext_attr(self):
         post_body = {"network_id": self.network['id']}
         body = self.admin_client.create_port(**post_body)
@@ -336,6 +349,7 @@
         self.assertEqual(self.host_id, host_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1c82a44a-6c6e-48ff-89e1-abe7eaf8f9f8')
     def test_list_ports_binding_ext_attr(self):
         # Create a new port
         post_body = {"network_id": self.network['id']}
@@ -361,6 +375,7 @@
         self.assertEqual(self.host_id, listed_port[0]['binding:host_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b54ac0ff-35fc-4c79-9ca3-c7dbd4ea4f13')
     def test_show_port_binding_ext_attr(self):
         body = self.admin_client.create_port(network_id=self.network['id'])
         port = body['port']
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 210a8af..1388b3b 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -25,7 +25,6 @@
 
 
 class RoutersTest(base.BaseRouterTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -52,6 +51,7 @@
         return router
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f64403e2-8483-4b34-8ccd-b09a87bcc68c')
     def test_create_show_list_update_delete_router(self):
         # Create a router
         # NOTE(salv-orlando): Do not invoke self.create_router
@@ -90,6 +90,7 @@
         self.assertEqual(show_body['router']['name'], updated_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e54dd3a3-4352-4921-b09d-44369ae17397')
     def test_create_router_setting_tenant_id(self):
         # Test creating router from admin user setting tenant_id.
         test_tenant = data_utils.rand_name('test_tenant_')
@@ -106,6 +107,7 @@
                         create_body['router']['id'])
         self.assertEqual(tenant_id, create_body['router']['tenant_id'])
 
+    @test.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_create_router_with_default_snat_value(self):
@@ -117,6 +119,7 @@
             router['id'], {'network_id': CONF.network.public_network_id,
                            'enable_snat': True})
 
+    @test.idempotent_id('ea74068d-09e9-4fd7-8995-9b6a1ace920f')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_create_router_with_snat_explicit(self):
@@ -136,6 +139,7 @@
                                         exp_ext_gw_info=external_gateway_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b42e6e39-2e37-49cc-a6f4-8467e940900a')
     def test_add_remove_router_interface_with_subnet_id(self):
         network = self.create_network()
         subnet = self.create_subnet(network)
@@ -154,6 +158,7 @@
                          router['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2b7d2f37-6748-4d78-92e5-1d590234f0d5')
     def test_add_remove_router_interface_with_port_id(self):
         network = self.create_network()
         self.create_subnet(network)
@@ -198,6 +203,7 @@
                       map(lambda x: x['subnet_id'], fixed_ips))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6cc285d8-46bf-4f36-9b1a-783e3008ba79')
     def test_update_router_set_gateway(self):
         router = self._create_router(data_utils.rand_name('router-'))
         self.client.update_router(
@@ -210,6 +216,7 @@
             {'network_id': CONF.network.public_network_id})
         self._verify_gateway_port(router['id'])
 
+    @test.idempotent_id('b386c111-3b21-466d-880c-5e72b01e1a33')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_update_router_set_gateway_with_snat_explicit(self):
@@ -225,6 +232,7 @@
              'enable_snat': True})
         self._verify_gateway_port(router['id'])
 
+    @test.idempotent_id('96536bc7-8262-4fb2-9967-5c46940fa279')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_update_router_set_gateway_without_snat(self):
@@ -241,6 +249,7 @@
         self._verify_gateway_port(router['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ad81b7ee-4f81-407b-a19c-17e623f763e8')
     def test_update_router_unset_gateway(self):
         router = self._create_router(
             data_utils.rand_name('router-'),
@@ -253,6 +262,7 @@
             device_id=router['id'])
         self.assertFalse(list_body['ports'])
 
+    @test.idempotent_id('f2faf994-97f4-410b-a831-9bc977b64374')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_update_router_reset_gateway_without_snat(self):
@@ -270,6 +280,7 @@
              'enable_snat': False})
         self._verify_gateway_port(router['id'])
 
+    @test.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
     @test.requires_ext(extension='extraroute', service='network')
     @test.attr(type='smoke')
     def test_update_extra_route(self):
@@ -305,6 +316,7 @@
         self.client.delete_extra_routes(router_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a8902683-c788-4246-95c7-ad9c6d63a4d9')
     def test_update_router_admin_state(self):
         self.router = self._create_router(data_utils.rand_name('router-'))
         self.assertFalse(self.router['admin_state_up'])
@@ -316,6 +328,7 @@
         self.assertTrue(show_body['router']['admin_state_up'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('802c73c9-c937-4cef-824b-2191e24a6aab')
     def test_add_multiple_router_interfaces(self):
         network01 = self.create_network(
             network_name=data_utils.rand_name('router-network01-'))
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index d571e92..9f76dd2 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -14,18 +14,17 @@
 #    under the License.
 
 import netaddr
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.network import base_routers as base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
 class RoutersNegativeTest(base.BaseRouterTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -41,26 +40,29 @@
                            CONF.network.tenant_network_v6_cidr)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('37a94fc0-a834-45b9-bd23-9a81d2fd1e22')
     def test_router_add_gateway_invalid_network_returns_404(self):
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.update_router,
                           self.router['id'],
                           external_gateway_info={
                               'network_id': self.router['id']})
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('11836a18-0b15-4327-a50b-f0d9dc66bddd')
     def test_router_add_gateway_net_not_external_returns_400(self):
         alt_network = self.create_network(
             network_name=data_utils.rand_name('router-negative-'))
         sub_cidr = netaddr.IPNetwork(self.tenant_cidr).next()
         self.create_subnet(alt_network, cidr=sub_cidr)
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.update_router,
                           self.router['id'],
                           external_gateway_info={
                               'network_id': alt_network['id']})
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('957751a3-3c68-4fa2-93b6-eb52ea10db6e')
     def test_add_router_interfaces_on_overlapping_subnets_returns_400(self):
         network01 = self.create_network(
             network_name=data_utils.rand_name('router-network01-'))
@@ -70,35 +72,39 @@
         subnet02 = self.create_subnet(network02)
         self._add_router_interface_with_subnet_id(self.router['id'],
                                                   subnet01['id'])
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self._add_router_interface_with_subnet_id,
                           self.router['id'],
                           subnet02['id'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
     def test_router_remove_interface_in_use_returns_409(self):
         self.client.add_router_interface_with_subnet_id(
             self.router['id'], self.subnet['id'])
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.delete_router,
                           self.router['id'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('c2a70d72-8826-43a7-8208-0209e6360c47')
     def test_show_non_existent_router_returns_404(self):
         router = data_utils.rand_name('non_exist_router')
-        self.assertRaises(exceptions.NotFound, self.client.show_router,
+        self.assertRaises(lib_exc.NotFound, self.client.show_router,
                           router)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('b23d1569-8b0c-4169-8d4b-6abd34fad5c7')
     def test_update_non_existent_router_returns_404(self):
         router = data_utils.rand_name('non_exist_router')
-        self.assertRaises(exceptions.NotFound, self.client.update_router,
+        self.assertRaises(lib_exc.NotFound, self.client.update_router,
                           router, name="new_name")
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('c7edc5ad-d09d-41e6-a344-5c0c31e2e3e4')
     def test_delete_non_existent_router_returns_404(self):
         router = data_utils.rand_name('non_exist_router')
-        self.assertRaises(exceptions.NotFound, self.client.delete_router,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_router,
                           router)
 
 
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 415dedd..8479013 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -24,7 +24,7 @@
 
 
 class SecGroupTest(base.BaseSecGroupTest):
-    _interface = 'json'
+
     _tenant_network_cidr = CONF.network.tenant_network_cidr
 
     @classmethod
@@ -69,6 +69,7 @@
                              (key, value))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e30abd17-fef9-4739-8617-dc26da88e686')
     def test_list_security_groups(self):
         # Verify the that security group belonging to tenant exist in list
         body = self.client.list_security_groups()
@@ -81,6 +82,7 @@
         self.assertIsNotNone(found, msg)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bfd128e5-3c92-44b6-9d66-7fe29d22c802')
     def test_create_list_update_show_delete_security_group(self):
         group_create_body, name = self._create_security_group()
 
@@ -109,6 +111,7 @@
                          new_description)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cfb99e0e-7410-4a3d-8a0c-959a63ee77e9')
     def test_create_show_delete_security_group_rule(self):
         group_create_body, _ = self._create_security_group()
 
@@ -140,6 +143,7 @@
                           rule_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('87dfbcf9-1849-43ea-b1e4-efa3eeae9f71')
     def test_create_security_group_rule_with_additional_args(self):
         """Verify security group rule with additional arguments works.
 
@@ -158,11 +162,12 @@
                                                 port_range_max)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c9463db8-b44d-4f52-b6c0-8dbda99f26ce')
     def test_create_security_group_rule_with_icmp_type_code(self):
         """Verify security group rule for icmp protocol works.
 
         Specify icmp type (port_range_min) and icmp code
-        (port_range_max) with different values. A seperate testcase
+        (port_range_max) with different values. A separate testcase
         is added for icmp protocol as icmp validation would be
         different from tcp/udp.
         """
@@ -178,6 +183,7 @@
                                                     icmp_type, icmp_code)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b')
     def test_create_security_group_rule_with_remote_group_id(self):
         # Verify creating security group rule with remote_group_id works
         sg1_body, _ = self._create_security_group()
@@ -196,6 +202,7 @@
                                                 remote_group_id=remote_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('16459776-5da2-4634-bce4-4b55ee3ec188')
     def test_create_security_group_rule_with_remote_ip_prefix(self):
         # Verify creating security group rule with remote_ip_prefix works
         sg1_body, _ = self._create_security_group()
@@ -213,6 +220,7 @@
                                                 remote_ip_prefix=ip_prefix)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0a307599-6655-4220-bebc-fd70c64f2290')
     def test_create_security_group_rule_with_protocol_integer_value(self):
         # Verify creating security group rule with the
         # protocol as integer value
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index fb51e30..97c0592 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -15,16 +15,17 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.network import base_security_groups as base
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
 class NegativeSecGroupTest(base.BaseSecGroupTest):
-    _interface = 'json'
+
     _tenant_network_cidr = CONF.network.tenant_network_cidr
 
     @classmethod
@@ -35,38 +36,43 @@
             raise cls.skipException(msg)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('424fd5c3-9ddc-486a-b45f-39bf0c820fc6')
     def test_show_non_existent_security_group(self):
         non_exist_id = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound, self.client.show_security_group,
+        self.assertRaises(lib_exc.NotFound, self.client.show_security_group,
                           non_exist_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4c094c09-000b-4e41-8100-9617600c02a6')
     def test_show_non_existent_security_group_rule(self):
         non_exist_id = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.show_security_group_rule,
                           non_exist_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1f1bb89d-5664-4956-9fcd-83ee0fa603df')
     def test_delete_non_existent_security_group(self):
         non_exist_id = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_security_group,
                           non_exist_id
                           )
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('981bdc22-ce48-41ed-900a-73148b583958')
     def test_create_security_group_rule_with_bad_protocol(self):
         group_create_body, _ = self._create_security_group()
 
         # Create rule with bad protocol name
         pname = 'bad_protocol_name'
         self.assertRaises(
-            exceptions.BadRequest, self.client.create_security_group_rule,
+            lib_exc.BadRequest, self.client.create_security_group_rule,
             security_group_id=group_create_body['security_group']['id'],
             protocol=pname, direction='ingress', ethertype=self.ethertype)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5f8daf69-3c5f-4aaa-88c9-db1d66f68679')
     def test_create_security_group_rule_with_bad_remote_ip_prefix(self):
         group_create_body, _ = self._create_security_group()
 
@@ -74,12 +80,13 @@
         prefix = ['192.168.1./24', '192.168.1.1/33', 'bad_prefix', '256']
         for remote_ip_prefix in prefix:
             self.assertRaises(
-                exceptions.BadRequest, self.client.create_security_group_rule,
+                lib_exc.BadRequest, self.client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='tcp', direction='ingress', ethertype=self.ethertype,
                 remote_ip_prefix=remote_ip_prefix)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4bf786fd-2f02-443c-9716-5b98e159a49a')
     def test_create_security_group_rule_with_non_existent_remote_groupid(self):
         group_create_body, _ = self._create_security_group()
         non_exist_id = str(uuid.uuid4())
@@ -88,12 +95,13 @@
         group_ids = ['bad_group_id', non_exist_id]
         for remote_group_id in group_ids:
             self.assertRaises(
-                exceptions.NotFound, self.client.create_security_group_rule,
+                lib_exc.NotFound, self.client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='tcp', direction='ingress', ethertype=self.ethertype,
                 remote_group_id=remote_group_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b5c4b247-6b02-435b-b088-d10d45650881')
     def test_create_security_group_rule_with_remote_ip_and_group(self):
         sg1_body, _ = self._create_security_group()
         sg2_body, _ = self._create_security_group()
@@ -101,24 +109,26 @@
         # Create rule specifying both remote_ip_prefix and remote_group_id
         prefix = self._tenant_network_cidr
         self.assertRaises(
-            exceptions.BadRequest, self.client.create_security_group_rule,
+            lib_exc.BadRequest, self.client.create_security_group_rule,
             security_group_id=sg1_body['security_group']['id'],
             protocol='tcp', direction='ingress',
             ethertype=self.ethertype, remote_ip_prefix=prefix,
             remote_group_id=sg2_body['security_group']['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5666968c-fff3-40d6-9efc-df1c8bd01abb')
     def test_create_security_group_rule_with_bad_ethertype(self):
         group_create_body, _ = self._create_security_group()
 
         # Create rule with bad ethertype
         ethertype = 'bad_ethertype'
         self.assertRaises(
-            exceptions.BadRequest, self.client.create_security_group_rule,
+            lib_exc.BadRequest, self.client.create_security_group_rule,
             security_group_id=group_create_body['security_group']['id'],
             protocol='udp', direction='ingress', ethertype=ethertype)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d')
     def test_create_security_group_rule_with_invalid_ports(self):
         group_create_body, _ = self._create_security_group()
 
@@ -130,7 +140,7 @@
                   (-16, 65536, 'Invalid value for port')]
         for pmin, pmax, msg in states:
             ex = self.assertRaises(
-                exceptions.BadRequest, self.client.create_security_group_rule,
+                lib_exc.BadRequest, self.client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='tcp', port_range_min=pmin, port_range_max=pmax,
                 direction='ingress', ethertype=self.ethertype)
@@ -142,21 +152,23 @@
                   (300, 1, 'Invalid value for ICMP type')]
         for pmin, pmax, msg in states:
             ex = self.assertRaises(
-                exceptions.BadRequest, self.client.create_security_group_rule,
+                lib_exc.BadRequest, self.client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='icmp', port_range_min=pmin, port_range_max=pmax,
                 direction='ingress', ethertype=self.ethertype)
             self.assertIn(msg, str(ex))
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('2323061e-9fbf-4eb0-b547-7e8fafc90849')
     def test_create_additional_default_security_group_fails(self):
         # Create security group named 'default', it should be failed.
         name = 'default'
-        self.assertRaises(exceptions.Conflict,
+        self.assertRaises(lib_exc.Conflict,
                           self.client.create_security_group,
                           name=name)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('8fde898f-ce88-493b-adc9-4e4692879fc5')
     def test_create_duplicate_security_group_rule_fails(self):
         # Create duplicate security group rule, it should fail.
         body, _ = self._create_security_group()
@@ -175,16 +187,17 @@
 
         # Try creating the same security group rule, it should fail
         self.assertRaises(
-            exceptions.Conflict, self.client.create_security_group_rule,
+            lib_exc.Conflict, self.client.create_security_group_rule,
             security_group_id=body['security_group']['id'],
             protocol='tcp', direction='ingress', ethertype=self.ethertype,
             port_range_min=min_port, port_range_max=max_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('be308db6-a7cf-4d5c-9baf-71bafd73f35e')
     def test_create_security_group_rule_with_non_existent_security_group(self):
         # Create security group rules with not existing security group.
         non_existent_sg = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.create_security_group_rule,
                           security_group_id=non_existent_sg,
                           direction='ingress', ethertype=self.ethertype)
@@ -195,6 +208,7 @@
     _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7607439c-af73-499e-bf64-f687fd12a842')
     def test_create_security_group_rule_wrong_ip_prefix_version(self):
         group_create_body, _ = self._create_security_group()
 
@@ -205,7 +219,7 @@
                   'ip_prefix': CONF.network.tenant_network_v6_cidr})
         for pair in pairs:
             self.assertRaisesRegexp(
-                exceptions.BadRequest,
+                lib_exc.BadRequest,
                 "Conflicting value ethertype",
                 self.client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
diff --git a/tempest/api/network/test_service_type_management.py b/tempest/api/network/test_service_type_management.py
index 0492fe3..a1e4136 100644
--- a/tempest/api/network/test_service_type_management.py
+++ b/tempest/api/network/test_service_type_management.py
@@ -17,7 +17,6 @@
 
 
 class ServiceTypeManagementTestJSON(base.BaseNetworkTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -28,6 +27,7 @@
 
     @decorators.skip_because(bug="1400370")
     @test.attr(type='smoke')
+    @test.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
     def test_service_provider_list(self):
         body = self.client.list_service_providers()
         self.assertIsInstance(body['service_providers'], list)
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
index 56e1a05..ebf31d3 100644
--- a/tempest/api/network/test_vpnaas_extensions.py
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -13,17 +13,17 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
 class VPNaaSTestJSON(base.BaseAdminNetworkTest):
-    _interface = 'json'
 
     """
     Tests the following operations in the Neutron API using the REST client for
@@ -74,7 +74,7 @@
         try:
             self.client.delete_ipsecpolicy(ipsec_policy_id)
 
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             pass
 
     def _assertExpected(self, expected, actual):
@@ -101,6 +101,7 @@
         return body['network']['tenant_id']
 
     @test.attr(type='smoke')
+    @test.idempotent_id('14311574-0737-4e53-ac05-f7ae27742eed')
     def test_admin_create_ipsec_policy_for_tenant(self):
         tenant_id = self._get_tenant_id()
         # Create IPSec policy for the newly created tenant
@@ -118,6 +119,7 @@
         self.assertIn(ipsecpolicy['id'], ipsecpolicies)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b62acdc6-0c53-4d84-84aa-859b22b79799')
     def test_admin_create_vpn_service_for_tenant(self):
         tenant_id = self._get_tenant_id()
 
@@ -143,6 +145,7 @@
         self.assertIn(vpnservice['id'], vpn_services)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('58cc4a1c-443b-4f39-8fb6-c19d39f343ab')
     def test_admin_create_ike_policy_for_tenant(self):
         tenant_id = self._get_tenant_id()
 
@@ -163,6 +166,7 @@
         self.assertIn(ikepolicy['id'], ikepolicies)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('de5bb04c-3a1f-46b1-b329-7a8abba5c7f1')
     def test_list_vpn_services(self):
         # Verify the VPN service exists in the list of all VPN services
         body = self.client.list_vpnservices()
@@ -170,6 +174,7 @@
         self.assertIn(self.vpnservice['id'], [v['id'] for v in vpnservices])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aacb13b1-fdc7-41fd-bab2-32621aee1878')
     def test_create_update_delete_vpn_service(self):
         # Creates a VPN service and sets up deletion
         network1 = self.create_network()
@@ -196,6 +201,7 @@
         # should be "ACTIVE" not "PENDING*"
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0dedfc1d-f8ee-4e2a-bfd4-7997b9dc17ff')
     def test_show_vpn_service(self):
         # Verifies the details of a vpn service
         body = self.client.show_vpnservice(self.vpnservice['id'])
@@ -212,6 +218,7 @@
         self.assertIn(vpnservice['status'], valid_status)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e0fb6200-da3d-4869-8340-a8c1956ca618')
     def test_list_ike_policies(self):
         # Verify the ike policy exists in the list of all IKE policies
         body = self.client.list_ikepolicies()
@@ -219,6 +226,7 @@
         self.assertIn(self.ikepolicy['id'], [i['id'] for i in ikepolicies])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d61f29a5-160c-487d-bc0d-22e32e731b44')
     def test_create_update_delete_ike_policy(self):
         # Creates a IKE policy
         name = data_utils.rand_name('ike-policy')
@@ -253,6 +261,7 @@
         self.assertNotIn(ike_policy['id'], ikepolicies)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b5fcf3a3-9407-452d-b8a8-e7c6c32baea8')
     def test_show_ike_policy(self):
         # Verifies the details of a ike policy
         body = self.client.show_ikepolicy(self.ikepolicy['id'])
@@ -275,6 +284,7 @@
                          ikepolicy['ike_version'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('19ea0a2f-add9-44be-b732-ffd8a7b42f37')
     def test_list_ipsec_policies(self):
         # Verify the ipsec policy exists in the list of all ipsec policies
         body = self.client.list_ipsecpolicies()
@@ -282,6 +292,7 @@
         self.assertIn(self.ipsecpolicy['id'], [i['id'] for i in ipsecpolicies])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9c1701c9-329a-4e5d-930a-1ead1b3f86ad')
     def test_create_update_delete_ipsec_policy(self):
         # Creates an ipsec policy
         ipsec_policy_body = {'name': data_utils.rand_name('ipsec-policy'),
@@ -304,10 +315,11 @@
         self._assertExpected(new_ipsec, updated_ipsec_policy)
         # Verification of ipsec policy delete
         self.client.delete_ipsecpolicy(ipsecpolicy['id'])
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.delete_ipsecpolicy, ipsecpolicy['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('601f8a05-9d3c-4539-a400-1c4b3a21b03b')
     def test_show_ipsec_policy(self):
         # Verifies the details of an ipsec policy
         body = self.client.show_ipsecpolicy(self.ipsecpolicy['id'])
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 36c9f5a..6a025d9 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -13,13 +13,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.identity import base
 from tempest import clients
 from tempest.common import credentials
 from tempest.common import custom_matchers
 from tempest import config
-from tempest import exceptions
 import tempest.test
 
 CONF = config.CONF
@@ -28,21 +28,31 @@
 class BaseObjectTest(tempest.test.BaseTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        cls.set_network_resources()
-        super(BaseObjectTest, cls).resource_setup()
+    def skip_checks(cls):
+        super(BaseObjectTest, cls).skip_checks()
         if not CONF.service_available.swift:
             skip_msg = ("%s skipped as swift is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
+
+    @classmethod
+    def setup_credentials(cls):
+        cls.set_network_resources()
+        super(BaseObjectTest, cls).setup_credentials()
+
         cls.isolated_creds = credentials.get_isolated_credentials(
             cls.__name__, network_resources=cls.network_resources)
         # Get isolated creds for normal user
         cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
         # Get isolated creds for admin user
         cls.os_admin = clients.Manager(cls.isolated_creds.get_admin_creds())
+        cls.data = SwiftDataGenerator(cls.os_admin.identity_client)
         # Get isolated creds for alt user
         cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
 
+    @classmethod
+    def setup_clients(cls):
+        super(BaseObjectTest, cls).setup_clients()
+
         cls.object_client = cls.os.object_client
         cls.container_client = cls.os.container_client
         cls.account_client = cls.os.account_client
@@ -52,6 +62,10 @@
         cls.container_client_alt = cls.os_alt.container_client
         cls.identity_client_alt = cls.os_alt.identity_client
 
+    @classmethod
+    def resource_setup(cls):
+        super(BaseObjectTest, cls).resource_setup()
+
         # Make sure we get fresh auth data after assigning swift role
         cls.object_client.auth_provider.clear_auth()
         cls.container_client.auth_provider.clear_auth()
@@ -59,8 +73,6 @@
         cls.object_client_alt.auth_provider.clear_auth()
         cls.container_client_alt.auth_provider.clear_auth()
 
-        cls.data = SwiftDataGenerator(cls.identity_admin_client)
-
     @classmethod
     def resource_cleanup(cls):
         cls.data.teardown_all()
@@ -93,10 +105,10 @@
                 for obj in objlist:
                     try:
                         object_client.delete_object(cont, obj['name'])
-                    except exceptions.NotFound:
+                    except lib_exc.NotFound:
                         pass
                 container_client.delete_container(cont)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
 
     def assertHeaders(self, resp, target, method):
@@ -126,7 +138,7 @@
             return next(r['id'] for r in roles if r['name'] == role_name)
         except StopIteration:
             msg = "Role name '%s' is not found" % role_name
-            raise exceptions.NotFound(msg)
+            raise lib_exc.NotFound(msg)
 
     def _assign_role(self, role_id):
         self.client.assign_user_role(self.tenant['id'],
diff --git a/tempest/api/object_storage/test_account_bulk.py b/tempest/api/object_storage/test_account_bulk.py
index 31a80cf..54c87d7 100644
--- a/tempest/api/object_storage/test_account_bulk.py
+++ b/tempest/api/object_storage/test_account_bulk.py
@@ -66,6 +66,7 @@
         self.assertNotIn(container_name, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a407de51-1983-47cc-9f14-47c2b059413c')
     @test.requires_ext(extension='bulk', service='object')
     def test_extract_archive(self):
         # Test bulk operation of file upload with an archived file
@@ -102,6 +103,7 @@
         self.assertIn(object_name, [c['name'] for c in contents_list])
 
     @test.attr(type='gate')
+    @test.idempotent_id('c075e682-0d2a-43b2-808d-4116200d736d')
     @test.requires_ext(extension='bulk', service='object')
     def test_bulk_delete(self):
         # Test bulk operation of deleting multiple files
@@ -129,6 +131,7 @@
         self._check_contents_deleted(container_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('dbea2bcb-efbb-4674-ac8a-a5a0e33d1d79')
     @test.requires_ext(extension='bulk', service='object')
     def test_bulk_delete_by_POST(self):
         # Test bulk operation of deleting multiple files
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index 1832b37..9b379f4 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
@@ -26,15 +24,17 @@
 class AccountQuotasTest(base.BaseObjectTest):
 
     @classmethod
+    def setup_credentials(cls):
+        super(AccountQuotasTest, cls).setup_credentials()
+        cls.data.setup_test_user(reseller=True)
+        cls.os_reselleradmin = clients.Manager(cls.data.test_credentials)
+
+    @classmethod
     def resource_setup(cls):
         super(AccountQuotasTest, cls).resource_setup()
         cls.container_name = data_utils.rand_name(name="TestContainer")
         cls.container_client.create_container(cls.container_name)
 
-        cls.data.setup_test_user(reseller=True)
-
-        cls.os_reselleradmin = clients.Manager(cls.data.test_credentials)
-
         # Retrieve a ResellerAdmin auth data and use it to set a quota
         # on the client's account
         cls.reselleradmin_auth_data = \
@@ -76,6 +76,7 @@
         super(AccountQuotasTest, cls).resource_cleanup()
 
     @test.attr(type="smoke")
+    @test.idempotent_id('a22ef352-a342-4587-8f47-3bbdb5b039c4')
     @test.requires_ext(extension='account_quotas', service='object')
     def test_upload_valid_object(self):
         object_name = data_utils.rand_name(name="TestObject")
@@ -86,6 +87,7 @@
         self.assertHeaders(resp, 'Object', 'PUT')
 
     @test.attr(type=["smoke"])
+    @test.idempotent_id('63f51f9f-5f1d-4fc6-b5be-d454d70949d6')
     @test.requires_ext(extension='account_quotas', service='object')
     def test_admin_modify_quota(self):
         """Test that the ResellerAdmin is able to modify and remove the quota
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index 5a0be54..7d4008c 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
@@ -15,12 +13,12 @@
 # under the License.
 
 from tempest_lib import decorators
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.object_storage import base
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -29,15 +27,17 @@
 class AccountQuotasNegativeTest(base.BaseObjectTest):
 
     @classmethod
+    def setup_credentials(cls):
+        super(AccountQuotasNegativeTest, cls).setup_credentials()
+        cls.data.setup_test_user(reseller=True)
+        cls.os_reselleradmin = clients.Manager(cls.data.test_credentials)
+
+    @classmethod
     def resource_setup(cls):
         super(AccountQuotasNegativeTest, cls).resource_setup()
         cls.container_name = data_utils.rand_name(name="TestContainer")
         cls.container_client.create_container(cls.container_name)
 
-        cls.data.setup_test_user(reseller=True)
-
-        cls.os_reselleradmin = clients.Manager(cls.data.test_credentials)
-
         # Retrieve a ResellerAdmin auth data and use it to set a quota
         # on the client's account
         cls.reselleradmin_auth_data = \
@@ -78,6 +78,7 @@
         super(AccountQuotasNegativeTest, cls).resource_cleanup()
 
     @test.attr(type=["negative", "smoke"])
+    @test.idempotent_id('d1dc5076-555e-4e6d-9697-28f1fe976324')
     @test.requires_ext(extension='account_quotas', service='object')
     def test_user_modify_quota(self):
         """Test that a user is not able to modify or remove a quota on
@@ -85,21 +86,22 @@
         """
 
         # Not able to remove quota
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.account_client.create_account_metadata,
                           {"Quota-Bytes": ""})
 
         # Not able to modify quota
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.account_client.create_account_metadata,
                           {"Quota-Bytes": "100"})
 
     @test.attr(type=["negative", "smoke"])
     @decorators.skip_because(bug="1310597")
+    @test.idempotent_id('cf9e21f5-3aa4-41b1-9462-28ac550d8d3f')
     @test.requires_ext(extension='account_quotas', service='object')
     def test_upload_large_object(self):
         object_name = data_utils.rand_name(name="TestObject")
         data = data_utils.arbitrary_string(30)
-        self.assertRaises(exceptions.OverLimit,
+        self.assertRaises(lib_exc.OverLimit,
                           self.object_client.create_object,
                           self.container_name, object_name, data)
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 2bc4f59..63d0425 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -46,6 +46,7 @@
         super(AccountTest, cls).resource_cleanup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3499406a-ae53-4f8c-b43a-133d4dc6fe3f')
     def test_list_containers(self):
         # list of all containers should not be empty
         resp, container_list = self.account_client.list_account_containers()
@@ -56,6 +57,7 @@
             self.assertIn(container_name, container_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('884ec421-fbad-4fcc-916b-0580f2699565')
     def test_list_no_containers(self):
         # List request to empty account
 
@@ -87,6 +89,7 @@
         self.assertEqual(len(container_list), 0)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1c7efa35-e8a2-4b0b-b5ff-862c7fd83704')
     def test_list_containers_with_format_json(self):
         # list containers setting format parameter to 'json'
         params = {'format': 'json'}
@@ -99,6 +102,7 @@
         self.assertTrue([c['bytes'] for c in container_list])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4477b609-1ca6-4d4b-b25d-ad3f01086089')
     def test_list_containers_with_format_xml(self):
         # list containers setting format parameter to 'xml'
         params = {'format': 'xml'}
@@ -114,6 +118,7 @@
         self.assertEqual(container_list.find(".//bytes").tag, 'bytes')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6eb04a6a-4860-4e31-ba91-ea3347d76b58')
     @testtools.skipIf(
         not CONF.object_storage_feature_enabled.discoverability,
         'Discoverability function is disabled')
@@ -123,6 +128,7 @@
         self.assertThat(resp, custom_matchers.AreAllWellFormatted())
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5cfa4ab2-4373-48dd-a41f-a532b12b08b2')
     def test_list_containers_with_limit(self):
         # list containers one of them, half of them then all of them
         for limit in (1, self.containers_count / 2, self.containers_count):
@@ -134,6 +140,7 @@
             self.assertEqual(len(container_list), limit)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('638f876d-6a43-482a-bbb3-0840bca101c6')
     def test_list_containers_with_marker(self):
         # list containers using marker param
         # first expect to get 0 container as we specified last
@@ -154,6 +161,7 @@
         self.assertEqual(len(container_list), self.containers_count / 2 - 1)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
     def test_list_containers_with_end_marker(self):
         # list containers using end_marker param
         # first expect to get 0 container as we specified first container as
@@ -172,6 +180,7 @@
         self.assertEqual(len(container_list), self.containers_count / 2)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
     def test_list_containers_with_marker_and_end_marker(self):
         # list containers combining marker and end_marker param
         params = {'marker': self.containers[0],
@@ -182,6 +191,7 @@
         self.assertEqual(len(container_list), self.containers_count - 2)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f7064ae8-dbcc-48da-b594-82feef6ea5af')
     def test_list_containers_with_limit_and_marker(self):
         # list containers combining marker and limit param
         # result are always limitated by the limit whatever the marker
@@ -196,6 +206,7 @@
             self.assertTrue(len(container_list) <= limit, str(container_list))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('888a3f0e-7214-4806-8e50-5e0c9a69bb5e')
     def test_list_containers_with_limit_and_end_marker(self):
         # list containers combining limit and end_marker param
         limit = random.randint(1, self.containers_count)
@@ -208,6 +219,7 @@
                          min(limit, self.containers_count / 2))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
     def test_list_containers_with_limit_and_marker_and_end_marker(self):
         # list containers combining limit, marker and end_marker param
         limit = random.randint(1, self.containers_count)
@@ -221,6 +233,7 @@
                          min(limit, self.containers_count - 2))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4894c312-6056-4587-8d6f-86ffbf861f80')
     def test_list_account_metadata(self):
         # list all account metadata
 
@@ -236,6 +249,7 @@
         self.account_client.delete_account_metadata(metadata)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b904c2e3-24c2-4dba-ad7d-04e90a761be5')
     def test_list_no_account_metadata(self):
         # list no account metadata
         resp, _ = self.account_client.list_account_metadata()
@@ -243,6 +257,7 @@
         self.assertNotIn('x-account-meta-', str(resp))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e2a08b5f-3115-4768-a3ee-d4287acd6c08')
     def test_update_account_metadata_with_create_metadata(self):
         # add metadata to account
         metadata = {'test-account-meta1': 'Meta1'}
@@ -257,6 +272,7 @@
         self.account_client.delete_account_metadata(metadata)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9f60348d-c46f-4465-ae06-d51dbd470953')
     def test_update_account_metadata_with_delete_matadata(self):
         # delete metadata from account
         metadata = {'test-account-meta1': 'Meta1'}
@@ -268,6 +284,7 @@
         self.assertNotIn('x-account-meta-test-account-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('64fd53f3-adbd-4639-af54-436e4982dbfb')
     def test_update_account_metadata_with_create_matadata_key(self):
         # if the value of metadata is not set, the metadata is not
         # registered at a server
@@ -279,6 +296,7 @@
         self.assertNotIn('x-account-meta-test-account-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d4d884d3-4696-4b85-bc98-4f57c4dd2bf1')
     def test_update_account_metadata_with_delete_matadata_key(self):
         # Although the value of metadata is not set, the feature of
         # deleting metadata is valid
@@ -292,6 +310,7 @@
         self.assertNotIn('x-account-meta-test-account-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8e5fc073-59b9-42ee-984a-29ed11b2c749')
     def test_update_account_metadata_with_create_and_delete_metadata(self):
         # Send a request adding and deleting metadata requests simultaneously
         metadata_1 = {'test-account-meta1': 'Meta1'}
diff --git a/tempest/api/object_storage/test_account_services_negative.py b/tempest/api/object_storage/test_account_services_negative.py
index ef04387..f329675 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 #    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
@@ -14,15 +12,17 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.object_storage import base
 from tempest import clients
-from tempest import exceptions
 from tempest import test
 
 
 class AccountNegativeTest(base.BaseObjectTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('070e6aca-6152-4867-868d-1118d68fb38c')
     def test_list_containers_with_non_authorized_user(self):
         # list containers using non-authorized user
 
@@ -44,6 +44,6 @@
 
         params = {'format': 'json'}
         # list containers with non-authorized user token
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.account_client.list_account_containers,
                           params=params)
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index 205bc91..6368bec 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -20,12 +20,17 @@
 
 
 class ObjectTestACLs(base.BaseObjectTest):
+
+    @classmethod
+    def setup_credentials(cls):
+        super(ObjectTestACLs, cls).setup_credentials()
+        cls.data.setup_test_user()
+        cls.test_os = clients.Manager(cls.data.test_credentials)
+
     @classmethod
     def resource_setup(cls):
         super(ObjectTestACLs, cls).resource_setup()
-        cls.data.setup_test_user()
-        test_os = clients.Manager(cls.data.test_credentials)
-        cls.test_auth_data = test_os.auth_provider.auth_data
+        cls.test_auth_data = cls.test_os.auth_provider.auth_data
 
     def setUp(self):
         super(ObjectTestACLs, self).setUp()
@@ -37,6 +42,7 @@
         super(ObjectTestACLs, self).tearDown()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a3270f3f-7640-4944-8448-c7ea783ea5b6')
     def test_read_object_with_rights(self):
         # attempt to read object using authorized user
         # update X-Container-Read metadata ACL
@@ -61,6 +67,7 @@
         self.assertHeaders(resp, 'Object', 'GET')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aa58bfa5-40d9-4bc3-82b4-d07f4a9e392a')
     def test_write_object_with_rights(self):
         # attempt to write object using authorized user
         # update X-Container-Write metadata ACL
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index 138d25a..5892340 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 #    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
@@ -14,20 +12,26 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.object_storage import base
 from tempest import clients
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class ObjectACLsNegativeTest(base.BaseObjectTest):
+
+    @classmethod
+    def setup_credentials(cls):
+        super(ObjectACLsNegativeTest, cls).setup_credentials()
+        cls.data.setup_test_user()
+        cls.test_os = clients.Manager(cls.data.test_credentials)
+
     @classmethod
     def resource_setup(cls):
         super(ObjectACLsNegativeTest, cls).resource_setup()
-        cls.data.setup_test_user()
-        test_os = clients.Manager(cls.data.test_credentials)
-        cls.test_auth_data = test_os.auth_provider.auth_data
+        cls.test_auth_data = cls.test_os.auth_provider.auth_data
 
     def setUp(self):
         super(ObjectACLsNegativeTest, self).setUp()
@@ -39,6 +43,7 @@
         super(ObjectACLsNegativeTest, self).tearDown()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('af587587-0c24-4e15-9822-8352ce711013')
     def test_write_object_without_using_creds(self):
         # trying to create object with empty headers
         # X-Auth-Token is not provided
@@ -47,11 +52,12 @@
             request_part='headers',
             auth_data=None
         )
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.create_object,
                           self.container_name, object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('af85af0b-a025-4e72-a90e-121babf55720')
     def test_delete_object_without_using_creds(self):
         # create object
         object_name = data_utils.rand_name(name='Object')
@@ -63,11 +69,12 @@
             request_part='headers',
             auth_data=None
         )
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.delete_object,
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('63d84e37-55a6-42e2-9e5f-276e60e26a00')
     def test_write_object_with_non_authorized_user(self):
         # attempt to upload another file using non-authorized user
         # User provided token is forbidden. ACL are not set
@@ -77,11 +84,12 @@
             request_part='headers',
             auth_data=self.test_auth_data
         )
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.create_object,
                           self.container_name, object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('abf63359-be52-4feb-87dd-447689fc77fd')
     def test_read_object_with_non_authorized_user(self):
         # attempt to read object using non-authorized user
         # User provided token is forbidden. ACL are not set
@@ -94,11 +102,12 @@
             request_part='headers',
             auth_data=self.test_auth_data
         )
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.get_object,
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7343ac3d-cfed-4198-9bb0-00149741a492')
     def test_delete_object_with_non_authorized_user(self):
         # attempt to delete object using non-authorized user
         # User provided token is forbidden. ACL are not set
@@ -111,11 +120,12 @@
             request_part='headers',
             auth_data=self.test_auth_data
         )
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.delete_object,
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('9ed01334-01e9-41ea-87ea-e6f465582823')
     def test_read_object_without_rights(self):
         # attempt to read object using non-authorized user
         # update X-Container-Read metadata ACL
@@ -134,11 +144,12 @@
             request_part='headers',
             auth_data=self.test_auth_data
         )
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.get_object,
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('a3a585a7-d8cf-4b65-a1a0-edc2b1204f85')
     def test_write_object_without_rights(self):
         # attempt to write object using non-authorized user
         # update X-Container-Write metadata ACL
@@ -153,12 +164,13 @@
             auth_data=self.test_auth_data
         )
         object_name = data_utils.rand_name(name='Object')
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.create_object,
                           self.container_name,
                           object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('8ba512ad-aa6e-444e-b882-2906a0ea2052')
     def test_write_object_without_write_rights(self):
         # attempt to write object using non-authorized user
         # update X-Container-Read and X-Container-Write metadata ACL
@@ -175,12 +187,13 @@
             auth_data=self.test_auth_data
         )
         object_name = data_utils.rand_name(name='Object')
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.create_object,
                           self.container_name,
                           object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('b4e366f8-f185-47ab-b789-df4416f9ecdb')
     def test_delete_object_without_write_rights(self):
         # attempt to delete object using non-authorized user
         # update X-Container-Read and X-Container-Write metadata ACL
@@ -201,7 +214,7 @@
             request_part='headers',
             auth_data=self.test_auth_data
         )
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.delete_object,
                           self.container_name,
                           object_name)
diff --git a/tempest/api/object_storage/test_container_quotas.py b/tempest/api/object_storage/test_container_quotas.py
index 46944ed..c78b4c3 100644
--- a/tempest/api/object_storage/test_container_quotas.py
+++ b/tempest/api/object_storage/test_container_quotas.py
@@ -13,10 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.object_storage import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -50,6 +51,7 @@
         self.delete_containers([self.container_name])
         super(ContainerQuotasTest, self).tearDown()
 
+    @test.idempotent_id('9a0fb034-86af-4df0-86fa-f8bd7db21ae0')
     @test.requires_ext(extension='container_quotas', service='object')
     @test.attr(type="smoke")
     def test_upload_valid_object(self):
@@ -66,6 +68,7 @@
         nafter = self._get_bytes_used()
         self.assertEqual(nbefore + len(data), nafter)
 
+    @test.idempotent_id('22eeeb2b-3668-4160-baef-44790f65a5a0')
     @test.requires_ext(extension='container_quotas', service='object')
     @test.attr(type="smoke")
     def test_upload_large_object(self):
@@ -75,13 +78,14 @@
 
         nbefore = self._get_bytes_used()
 
-        self.assertRaises(exceptions.OverLimit,
+        self.assertRaises(lib_exc.OverLimit,
                           self.object_client.create_object,
                           self.container_name, object_name, data)
 
         nafter = self._get_bytes_used()
         self.assertEqual(nbefore, nafter)
 
+    @test.idempotent_id('3a387039-697a-44fc-a9c0-935de31f426b')
     @test.requires_ext(extension='container_quotas', service='object')
     @test.attr(type="smoke")
     def test_upload_too_many_objects(self):
@@ -93,7 +97,7 @@
         nbefore = self._get_object_count()
         self.assertEqual(nbefore, QUOTA_COUNT)
 
-        self.assertRaises(exceptions.OverLimit,
+        self.assertRaises(lib_exc.OverLimit,
                           self.object_client.create_object,
                           self.container_name, "OverQuotaObject", "")
 
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index fe06fd0..54da0d1 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -47,6 +47,7 @@
         return object_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('92139d73-7819-4db1-85f8-3f2f22a8d91f')
     def test_create_container(self):
         container_name = data_utils.rand_name(name='TestContainer')
         resp, body = self.container_client.create_container(container_name)
@@ -54,6 +55,7 @@
         self.assertHeaders(resp, 'Container', 'PUT')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('49f866ed-d6af-4395-93e7-4187eb56d322')
     def test_create_container_overwrite(self):
         # overwrite container with the same name
         container_name = data_utils.rand_name(name='TestContainer')
@@ -64,6 +66,7 @@
         self.assertHeaders(resp, 'Container', 'PUT')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c2ac4d59-d0f5-40d5-ba19-0635056d48cd')
     def test_create_container_with_metadata_key(self):
         # create container with the blank value of metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -81,6 +84,7 @@
         self.assertNotIn('x-container-meta-test-container-meta', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e1e8df32-7b22-44e1-aa08-ccfd8d446b58')
     def test_create_container_with_metadata_value(self):
         # create container with metadata value
         container_name = data_utils.rand_name(name='TestContainer')
@@ -99,6 +103,7 @@
                          metadata['test-container-meta'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('24d16451-1c0c-4e4f-b59c-9840a3aba40e')
     def test_create_container_with_remove_metadata_key(self):
         # create container with the blank value of remove metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -119,6 +124,7 @@
         self.assertNotIn('x-container-meta-test-container-meta', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8a21ebad-a5c7-4e29-b428-384edc8cd156')
     def test_create_container_with_remove_metadata_value(self):
         # create container with remove metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -137,6 +143,7 @@
         self.assertNotIn('x-container-meta-test-container-meta', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('95d3a249-b702-4082-a2c4-14bb860cf06a')
     def test_delete_container(self):
         # create a container
         container_name = self._create_container()
@@ -146,6 +153,7 @@
         self.containers.remove(container_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('312ff6bd-5290-497f-bda1-7c5fec6697ab')
     def test_list_container_contents(self):
         # get container contents list
         container_name = self._create_container()
@@ -157,6 +165,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4646ac2d-9bfb-4c7d-a3c5-0f527402b3df')
     def test_list_container_contents_with_no_object(self):
         # get empty container contents list
         container_name = self._create_container()
@@ -167,6 +176,7 @@
         self.assertEqual('', object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fe323a32-57b9-4704-a996-2e68f83b09bc')
     def test_list_container_contents_with_delimiter(self):
         # get container contents list using delimiter param
         container_name = self._create_container()
@@ -181,6 +191,7 @@
         self.assertEqual(object_name.split('/')[0], object_list.strip('/\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('55b4fa5c-e12e-4ca9-8fcf-a79afe118522')
     def test_list_container_contents_with_end_marker(self):
         # get container contents list using end_marker param
         container_name = self._create_container()
@@ -194,6 +205,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('196f5034-6ab0-4032-9da9-a937bbb9fba9')
     def test_list_container_contents_with_format_json(self):
         # get container contents list using format_json param
         container_name = self._create_container()
@@ -213,6 +225,7 @@
         self.assertTrue([c['last_modified'] for c in object_list])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('655a53ca-4d15-408c-a377-f4c6dbd0a1fa')
     def test_list_container_contents_with_format_xml(self):
         # get container contents list using format_xml param
         container_name = self._create_container()
@@ -237,6 +250,7 @@
                          'last_modified')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('297ec38b-2b61-4ff4-bcd1-7fa055e97b61')
     def test_list_container_contents_with_limit(self):
         # get container contents list using limit param
         container_name = self._create_container()
@@ -250,6 +264,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c31ddc63-2a58-4f6b-b25c-94d2937e6867')
     def test_list_container_contents_with_marker(self):
         # get container contents list using marker param
         container_name = self._create_container()
@@ -263,6 +278,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('58ca6cc9-6af0-408d-aaec-2a6a7b2f0df9')
     def test_list_container_contents_with_path(self):
         # get container contents list using path param
         container_name = self._create_container()
@@ -277,6 +293,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('77e742c7-caf2-4ec9-8aa4-f7d509a3344c')
     def test_list_container_contents_with_prefix(self):
         # get container contents list using prefix param
         container_name = self._create_container()
@@ -291,6 +308,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('96e68f0e-19ec-4aa2-86f3-adc6a45e14dd')
     def test_list_container_metadata(self):
         # List container metadata
         container_name = self._create_container()
@@ -307,6 +325,7 @@
         self.assertEqual(resp['x-container-meta-name'], metadata['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a2faf936-6b13-4f8d-92a2-c2278355821e')
     def test_list_no_container_metadata(self):
         # HEAD container without metadata
         container_name = self._create_container()
@@ -317,6 +336,7 @@
         self.assertNotIn('x-container-meta-', str(resp))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cf19bc0b-7e16-4a5a-aaed-cb0c2fe8deef')
     def test_update_container_metadata_with_create_and_delete_matadata(self):
         # Send one request of adding and deleting metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -340,6 +360,7 @@
                          metadata_2['test-container-meta2'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2ae5f295-4bf1-4e04-bfad-21e54b62cec5')
     def test_update_container_metadata_with_create_metadata(self):
         # update container metadata using add metadata
         container_name = self._create_container()
@@ -357,6 +378,7 @@
                          metadata['test-container-meta1'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3a5ce7d4-6e4b-47d0-9d87-7cd42c325094')
     def test_update_container_metadata_with_delete_metadata(self):
         # update container metadata using delete metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -375,6 +397,7 @@
         self.assertNotIn('x-container-meta-test-container-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('31f40a5f-6a52-4314-8794-cd89baed3040')
     def test_update_container_metadata_with_create_matadata_key(self):
         # update container metadata with a blenk value of metadata
         container_name = self._create_container()
@@ -390,6 +413,7 @@
         self.assertNotIn('x-container-meta-test-container-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a2e36378-6f1f-43f4-840a-ffd9cfd61914')
     def test_update_container_metadata_with_delete_metadata_key(self):
         # update container metadata with a blank value of matadata
         container_name = data_utils.rand_name(name='TestContainer')
diff --git a/tempest/api/object_storage/test_container_staticweb.py b/tempest/api/object_storage/test_container_staticweb.py
index a8e5f9a..45ecfec 100644
--- a/tempest/api/object_storage/test_container_staticweb.py
+++ b/tempest/api/object_storage/test_container_staticweb.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
@@ -14,10 +12,11 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.object_storage import base
 from tempest.common import custom_matchers
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -50,6 +49,7 @@
             cls.delete_containers([cls.container_name])
         super(StaticWebTest, cls).resource_cleanup()
 
+    @test.idempotent_id('c1f055ab-621d-4a6a-831f-846fcb578b8b')
     @test.requires_ext(extension='staticweb', service='object')
     @test.attr('gate')
     def test_web_index(self):
@@ -81,6 +81,7 @@
             self.container_name)
         self.assertNotIn('x-container-meta-web-index', body)
 
+    @test.idempotent_id('941814cf-db9e-4b21-8112-2b6d0af10ee5')
     @test.requires_ext(extension='staticweb', service='object')
     @test.attr('gate')
     def test_web_listing(self):
@@ -113,6 +114,7 @@
             self.container_name)
         self.assertNotIn('x-container-meta-web-listings', body)
 
+    @test.idempotent_id('bc37ec94-43c8-4990-842e-0e5e02fc8926')
     @test.requires_ext(extension='staticweb', service='object')
     @test.attr('gate')
     def test_web_listing_css(self):
@@ -137,6 +139,7 @@
         css = '<link rel="stylesheet" type="text/css" href="listings.css" />'
         self.assertIn(css, body)
 
+    @test.idempotent_id('f18b4bef-212e-45e7-b3ca-59af3a465f82')
     @test.requires_ext(extension='staticweb', service='object')
     @test.attr('gate')
     def test_web_error(self):
@@ -161,5 +164,5 @@
 
         # Request non-existing object
         self.assertRaises(
-            exceptions.NotFound, self.object_client.get_object,
+            lib_exc.NotFound, self.object_client.get_object,
             self.container_name, "notexisting")
diff --git a/tempest/api/object_storage/test_container_sync.py b/tempest/api/object_storage/test_container_sync.py
index 09b0ce0..71f1275 100644
--- a/tempest/api/object_storage/test_container_sync.py
+++ b/tempest/api/object_storage/test_container_sync.py
@@ -114,6 +114,7 @@
 
     @test.attr(type='slow')
     @decorators.skip_because(bug='1317133')
+    @test.idempotent_id('be008325-1bba-4925-b7dd-93b58f22ce9b')
     @testtools.skipIf(
         not CONF.object_storage_feature_enabled.container_sync,
         'Old-style container sync function is disabled')
diff --git a/tempest/api/object_storage/test_container_sync_middleware.py b/tempest/api/object_storage/test_container_sync_middleware.py
index 41509a0..4491a84 100644
--- a/tempest/api/object_storage/test_container_sync_middleware.py
+++ b/tempest/api/object_storage/test_container_sync_middleware.py
@@ -37,6 +37,7 @@
         cls.cluster_name = CONF.object_storage.cluster_name
 
     @test.attr(type='slow')
+    @test.idempotent_id('ea4645a1-d147-4976-82f7-e5a7a3065f80')
     @test.requires_ext(extension='container_sync', service='object')
     def test_container_synchronization(self):
         def make_headers(cont, cont_client):
diff --git a/tempest/api/object_storage/test_crossdomain.py b/tempest/api/object_storage/test_crossdomain.py
index 66e8176..9d49a73 100644
--- a/tempest/api/object_storage/test_crossdomain.py
+++ b/tempest/api/object_storage/test_crossdomain.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
@@ -39,6 +37,7 @@
         self.account_client.skip_path()
 
     @test.attr('gate')
+    @test.idempotent_id('d1b8b031-b622-4010-82f9-ff78a9e915c7')
     @test.requires_ext(extension='crossdomain', service='object')
     def test_get_crossdomain_policy(self):
         resp, body = self.account_client.get("crossdomain.xml", {})
diff --git a/tempest/api/object_storage/test_healthcheck.py b/tempest/api/object_storage/test_healthcheck.py
index 53c0347..2ca0a9f 100644
--- a/tempest/api/object_storage/test_healthcheck.py
+++ b/tempest/api/object_storage/test_healthcheck.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
@@ -22,16 +20,13 @@
 
 class HealthcheckTest(base.BaseObjectTest):
 
-    @classmethod
-    def resource_setup(cls):
-        super(HealthcheckTest, cls).resource_setup()
-
     def setUp(self):
         super(HealthcheckTest, self).setUp()
         # Turning http://.../v1/foobar into http://.../
         self.account_client.skip_path()
 
     @test.attr('gate')
+    @test.idempotent_id('db5723b1-f25c-49a9-bfeb-7b5640caf337')
     def test_get_healthcheck(self):
 
         resp, _ = self.account_client.get("healthcheck", {})
diff --git a/tempest/api/object_storage/test_object_expiry.py b/tempest/api/object_storage/test_object_expiry.py
index 5fa209d..ac6f49a 100644
--- a/tempest/api/object_storage/test_object_expiry.py
+++ b/tempest/api/object_storage/test_object_expiry.py
@@ -13,11 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
 import time
 
 from tempest.api.object_storage import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -66,10 +66,11 @@
         time.sleep(sleepy_time + 3)
 
         # object should not be there anymore
-        self.assertRaises(exceptions.NotFound, self.object_client.get_object,
+        self.assertRaises(lib_exc.NotFound, self.object_client.get_object,
                           self.container_name, self.object_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fb024a42-37f3-4ba5-9684-4f40a7910b41')
     def test_get_object_after_expiry_time(self):
         # the 10s is important, because the get calls can take 3s each
         # some times
@@ -77,6 +78,7 @@
         self._test_object_expiry(metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e592f18d-679c-48fe-9e36-4be5f47102c5')
     def test_get_object_at_expiry_time(self):
         metadata = {'X-Delete-At': str(int(time.time()) + 10)}
         self._test_object_expiry(metadata)
diff --git a/tempest/api/object_storage/test_object_formpost.py b/tempest/api/object_storage/test_object_formpost.py
index 7a9fcf6..3e0fc7b 100644
--- a/tempest/api/object_storage/test_object_formpost.py
+++ b/tempest/api/object_storage/test_object_formpost.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Christian Schwede <christian.schwede@enovance.com>
-#
 # 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
@@ -106,6 +104,7 @@
         content_type = 'multipart/form-data; boundary=%s' % boundary
         return body, content_type
 
+    @test.idempotent_id('80fac02b-6e54-4f7b-be0d-a965b5cbef76')
     @test.requires_ext(extension='formpost', service='object')
     @test.attr(type='gate')
     def test_post_object_using_form(self):
diff --git a/tempest/api/object_storage/test_object_formpost_negative.py b/tempest/api/object_storage/test_object_formpost_negative.py
index 32f5917..d92a2e5 100644
--- a/tempest/api/object_storage/test_object_formpost_negative.py
+++ b/tempest/api/object_storage/test_object_formpost_negative.py
@@ -1,5 +1,4 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
 #
 # 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
@@ -18,9 +17,10 @@
 import time
 import urlparse
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.object_storage import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -106,6 +106,7 @@
         content_type = 'multipart/form-data; boundary=%s' % boundary
         return body, content_type
 
+    @test.idempotent_id('d3fb3c4d-e627-48ce-9379-a1631f21336d')
     @test.requires_ext(extension='formpost', service='object')
     @test.attr(type=['gate', 'negative'])
     def test_post_object_using_form_expired(self):
@@ -117,11 +118,12 @@
 
         url = "%s/%s" % (self.container_name, self.object_name)
         exc = self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.object_client.post,
             url, body, headers=headers)
         self.assertIn('FormPost: Form Expired', str(exc))
 
+    @test.idempotent_id('b277257f-113c-4499-b8d1-5fead79f7360')
     @test.requires_ext(extension='formpost', service='object')
     @test.attr(type='gate')
     def test_post_object_using_form_invalid_signature(self):
@@ -133,7 +135,7 @@
 
         url = "%s/%s" % (self.container_name, self.object_name)
         exc = self.assertRaises(
-            exceptions.Unauthorized,
+            lib_exc.Unauthorized,
             self.object_client.post,
             url, body, headers=headers)
         self.assertIn('FormPost: Invalid Signature', str(exc))
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index cbca5e8..a4d0377 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -85,6 +85,7 @@
                 self.assertNotIn('x-object-meta-' + meta_key, resp)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5b4ce26f-3545-46c9-a2ba-5754358a4c62')
     def test_create_object(self):
         # create object
         object_name = data_utils.rand_name(name='TestObject')
@@ -104,6 +105,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5daebb1d-f0d5-4dc9-b541-69672eff00b0')
     def test_create_object_with_content_disposition(self):
         # create object with content_disposition
         object_name = data_utils.rand_name(name='TestObject')
@@ -126,6 +128,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='gate')
+    @test.idempotent_id('605f8317-f945-4bee-ae91-013f1da8f0a0')
     def test_create_object_with_content_encoding(self):
         # create object with content_encoding
         object_name = data_utils.rand_name(name='TestObject')
@@ -153,6 +156,7 @@
         self.assertEqual(body, data_before)
 
     @test.attr(type='gate')
+    @test.idempotent_id('73820093-0503-40b1-a478-edf0e69c7d1f')
     def test_create_object_with_etag(self):
         # create object with etag
         object_name = data_utils.rand_name(name='TestObject')
@@ -172,6 +176,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('84dafe57-9666-4f6d-84c8-0814d37923b8')
     def test_create_object_with_expect_continue(self):
         # create object with expect_continue
         object_name = data_utils.rand_name(name='TestObject')
@@ -198,6 +203,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4f84422a-e2f2-4403-b601-726a4220b54e')
     def test_create_object_with_transfer_encoding(self):
         # create object with transfer_encoding
         object_name = data_utils.rand_name(name='TestObject')
@@ -215,6 +221,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('0f3d62a6-47e3-4554-b0e5-1a5dc372d501')
     def test_create_object_with_x_fresh_metadata(self):
         # create object with x_fresh_metadata
         object_name_base = data_utils.rand_name(name='TestObject')
@@ -241,6 +248,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('1c7ed3e4-2099-406b-b843-5301d4811baf')
     def test_create_object_with_x_object_meta(self):
         # create object with object_meta
         object_name = data_utils.rand_name(name='TestObject')
@@ -260,6 +268,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e4183917-33db-4153-85cc-4dacbb938865')
     def test_create_object_with_x_object_metakey(self):
         # create object with the blank value of metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -279,6 +288,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ce798afc-b278-45de-a5ce-2ea124b98b99')
     def test_create_object_with_x_remove_object_meta(self):
         # create object with x_remove_object_meta
         object_name = data_utils.rand_name(name='TestObject')
@@ -302,6 +312,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ad21e342-7916-4f9e-ab62-a1f885f2aaf9')
     def test_create_object_with_x_remove_object_metakey(self):
         # create object with the blank value of remove metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -325,6 +336,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('17738d45-03bd-4d45-9e0b-7b2f58f98687')
     def test_delete_object(self):
         # create object
         object_name = data_utils.rand_name(name='TestObject')
@@ -337,6 +349,7 @@
         self.assertHeaders(resp, 'Object', 'DELETE')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7a94c25d-66e6-434c-9c38-97d4e2c29945')
     def test_update_object_metadata(self):
         # update object metadata
         object_name, data = self._create_object()
@@ -355,6 +368,7 @@
         self.assertIn('x-object-meta-test-meta', resp)
         self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
 
+    @test.idempotent_id('48650ed0-c189-4e1e-ad6b-1d4770c6e134')
     def test_update_object_metadata_with_remove_metadata(self):
         # update object metadata with remove metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -379,6 +393,7 @@
         self.assertNotIn('x-object-meta-test-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f726174b-2ded-4708-bff7-729d12ce1f84')
     def test_update_object_metadata_with_create_and_remove_metadata(self):
         # creation and deletion of metadata with one request
         object_name = data_utils.rand_name(name='TestObject')
@@ -406,6 +421,7 @@
         self.assertEqual(resp['x-object-meta-test-meta2'], 'Meta2')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('08854588-6449-4bb7-8cca-f2e1040f5e6f')
     def test_update_object_metadata_with_x_object_manifest(self):
         # update object metadata with x_object_manifest
 
@@ -432,6 +448,7 @@
         self.assertIn('x-object-manifest', resp)
         self.assertNotEqual(len(resp['x-object-manifest']), 0)
 
+    @test.idempotent_id('0dbbe89c-6811-4d84-a2df-eca2bdd40c0e')
     def test_update_object_metadata_with_x_object_metakey(self):
         # update object metadata with a blenk value of metadata
         object_name, data = self._create_object()
@@ -451,6 +468,7 @@
         self.assertEqual(resp['x-object-meta-test-meta'], '')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9a88dca4-b684-425b-806f-306cd0e57e42')
     def test_update_object_metadata_with_x_remove_object_metakey(self):
         # update object metadata with a blank value of remove metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -475,6 +493,7 @@
         self.assertNotIn('x-object-meta-test-meta', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9a447cf6-de06-48de-8226-a8c6ed31caf2')
     def test_list_object_metadata(self):
         # get object metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -493,6 +512,7 @@
         self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('170fb90e-f5c3-4b1f-ae1b-a18810821172')
     def test_list_no_object_metadata(self):
         # get empty list of object metadata
         object_name, data = self._create_object()
@@ -504,6 +524,7 @@
         self.assertNotIn('x-object-meta-', str(resp))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('23a3674c-d6de-46c3-86af-ff92bfc8a3da')
     def test_list_object_metadata_with_x_object_manifest(self):
         # get object metadata with x_object_manifest
 
@@ -544,6 +565,7 @@
                          '%s/%s' % (self.container_name, object_name))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('02610ba7-86b7-4272-9ed8-aa8d417cb3cd')
     def test_get_object(self):
         # retrieve object's data (in response body)
 
@@ -557,6 +579,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('005f9bf6-e06d-41ec-968e-96c78e0b1d82')
     def test_get_object_with_metadata(self):
         # get object with metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -576,6 +599,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('05a1890e-7db9-4a6c-90a8-ce998a2bddfa')
     def test_get_object_with_range(self):
         # get object with range
         object_name = data_utils.rand_name(name='TestObject')
@@ -594,6 +618,7 @@
         self.assertEqual(body, data[rand_num - 3: rand_num])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('11b4515b-7ba7-4ca8-8838-357ded86fc10')
     def test_get_object_with_x_object_manifest(self):
         # get object with x_object_manifest
 
@@ -637,6 +662,7 @@
         self.assertEqual(''.join(data_segments), body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c05b4013-e4de-47af-be84-e598062b16fc')
     def test_get_object_with_if_match(self):
         # get object with if_match
         object_name = data_utils.rand_name(name='TestObject')
@@ -657,6 +683,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('be133639-e5d2-4313-9b1f-2d59fc054a16')
     def test_get_object_with_if_modified_since(self):
         # get object with if_modified_since
         object_name = data_utils.rand_name(name='TestObject')
@@ -676,6 +703,7 @@
         self.assertHeaders(resp, 'Object', 'GET')
         self.assertEqual(body, data)
 
+    @test.idempotent_id('641500d5-1612-4042-a04d-01fc4528bc30')
     def test_get_object_with_if_none_match(self):
         # get object with if_none_match
         object_name = data_utils.rand_name(name='TestObject')
@@ -698,6 +726,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0aa1201c-10aa-467a-bee7-63cbdd463152')
     def test_get_object_with_if_unmodified_since(self):
         # get object with if_unmodified_since
         object_name, data = self._create_object()
@@ -713,6 +742,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('94587078-475f-48f9-a40f-389c246e31cd')
     def test_get_object_with_x_newest(self):
         # get object with x_newest
         object_name, data = self._create_object()
@@ -726,6 +756,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1a9ab572-1b66-4981-8c21-416e2a5e6011')
     def test_copy_object_in_same_container(self):
         # create source object
         src_object_name = data_utils.rand_name(name='SrcObject')
@@ -752,6 +783,7 @@
         self.assertEqual(body, src_data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2248abba-415d-410b-9c30-22dff9cd6e67')
     def test_copy_object_to_itself(self):
         # change the content type of an existing object
 
@@ -773,6 +805,7 @@
         self.assertEqual(resp['content-type'], metadata['content-type'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('06f90388-2d0e-40aa-934c-e9a8833e958a')
     def test_copy_object_2d_way(self):
         # create source object
         src_object_name = data_utils.rand_name(name='SrcObject')
@@ -799,6 +832,7 @@
         self._check_copied_obj(dst_object_name, src_data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aa467252-44f3-472a-b5ae-5b57c3c9c147')
     def test_copy_object_across_containers(self):
         # create a container to use as  asource container
         src_container_name = data_utils.rand_name(name='TestSourceContainer')
@@ -839,6 +873,7 @@
         self.assertEqual(resp[actual_meta_key], meta_value)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5a9e2cc6-85b6-46fc-916d-0cbb7a88e5fd')
     def test_copy_object_with_x_fresh_metadata(self):
         # create source object
         metadata = {'x-object-meta-src': 'src_value'}
@@ -859,6 +894,7 @@
         self._check_copied_obj(dst_object_name, data, not_in_meta=["src"])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a28a8b99-e701-4d7e-9d84-3b66f121460b')
     def test_copy_object_with_x_object_metakey(self):
         # create source object
         metadata = {'x-object-meta-src': 'src_value'}
@@ -881,6 +917,7 @@
         self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('edabedca-24c3-4322-9b70-d6d9f942a074')
     def test_copy_object_with_x_object_meta(self):
         # create source object
         metadata = {'x-object-meta-src': 'src_value'}
@@ -903,6 +940,7 @@
         self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
 
     @test.attr(type='gate')
+    @test.idempotent_id('e3e6a64a-9f50-4955-b987-6ce6767c97fb')
     def test_object_upload_in_segments(self):
         # create object
         object_name = data_utils.rand_name(name='LObject')
@@ -945,6 +983,7 @@
         self.assertEqual(''.join(data_segments), body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('50d01f12-526f-4360-9ac2-75dd508d7b68')
     def test_get_object_if_different(self):
         # http://en.wikipedia.org/wiki/HTTP_ETag
         # Make a conditional request for an object using the If-None-Match
@@ -987,6 +1026,7 @@
         super(PublicObjectTest, self).tearDown()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('07c9cf95-c0d4-4b49-b9c8-0ef2c9b27193')
     def test_access_public_container_object_without_using_creds(self):
         # make container public-readable and access an object in it object
         # anonymously, without using credentials
@@ -1025,6 +1065,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('54e2a2fe-42dc-491b-8270-8e4217dd4cdc')
     def test_access_public_object_with_another_user_creds(self):
         # make container public-readable and access an object in it using
         # another user's credentials
diff --git a/tempest/api/object_storage/test_object_slo.py b/tempest/api/object_storage/test_object_slo.py
index 6622349..b013752 100644
--- a/tempest/api/object_storage/test_object_slo.py
+++ b/tempest/api/object_storage/test_object_slo.py
@@ -15,10 +15,11 @@
 import hashlib
 import json
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.object_storage import base
 from tempest.common import custom_matchers
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 # Each segment, except for the final one, must be at least 1 megabyte
@@ -39,7 +40,7 @@
                 self.object_client.delete_object(
                     self.container_name,
                     obj)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
         self.container_client.delete_container(self.container_name)
         super(ObjectSloTest, self).tearDown()
@@ -109,6 +110,7 @@
         self.assertHeaders(resp, 'Object', method)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2c3f24a6-36e8-4711-9aa2-800ee1fc7b5b')
     def test_upload_manifest(self):
         # create static large object from multipart manifest
         manifest = self._create_manifest()
@@ -123,6 +125,7 @@
         self._assertHeadersSLO(resp, 'PUT')
 
     @test.attr(type='gate')
+    @test.idempotent_id('e69ad766-e1aa-44a2-bdd2-bf62c09c1456')
     def test_list_large_object_metadata(self):
         # list static large object metadata using multipart manifest
         object_name = self._create_large_object()
@@ -134,6 +137,7 @@
         self._assertHeadersSLO(resp, 'HEAD')
 
     @test.attr(type='gate')
+    @test.idempotent_id('49bc49bc-dd1b-4c0f-904e-d9f10b830ee8')
     def test_retrieve_large_object(self):
         # list static large object using multipart manifest
         object_name = self._create_large_object()
@@ -148,6 +152,7 @@
         self.assertEqual(body, sum_data)
 
     @test.attr(type='gate')
+    @test.idempotent_id('87b6dfa1-abe9-404d-8bf0-6c3751e6aa77')
     def test_delete_large_object(self):
         # delete static large object using multipart manifest
         object_name = self._create_large_object()
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index dd4fd17..e6b0b05 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
@@ -94,6 +92,7 @@
         return url
 
     @test.attr(type='gate')
+    @test.idempotent_id('f91c96d4-1230-4bba-8eb9-84476d18d991')
     @test.requires_ext(extension='tempurl', service='object')
     def test_get_object_using_temp_url(self):
         expires = self._get_expiry_date()
@@ -113,6 +112,7 @@
         self.assertHeaders(resp, 'Object', 'HEAD')
 
     @test.attr(type='gate')
+    @test.idempotent_id('671f9583-86bd-4128-a034-be282a68c5d8')
     @test.requires_ext(extension='tempurl', service='object')
     def test_get_object_using_temp_url_key_2(self):
         key2 = 'Meta2-'
@@ -137,6 +137,7 @@
         self.assertEqual(body, self.content)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9b08dade-3571-4152-8a4f-a4f2a873a735')
     @test.requires_ext(extension='tempurl', service='object')
     def test_put_object_using_temp_url(self):
         new_data = data_utils.arbitrary_string(
@@ -165,6 +166,7 @@
         self.assertEqual(body, new_data)
 
     @test.attr(type='gate')
+    @test.idempotent_id('249a0111-5ad3-4534-86a7-1993d55f9185')
     @test.requires_ext(extension='tempurl', service='object')
     def test_head_object_using_temp_url(self):
         expires = self._get_expiry_date()
@@ -179,6 +181,7 @@
         self.assertHeaders(resp, 'Object', 'HEAD')
 
     @test.attr(type='gate')
+    @test.idempotent_id('9d9cfd90-708b-465d-802c-e4a8090b823d')
     @test.requires_ext(extension='tempurl', service='object')
     def test_get_object_using_temp_url_with_inline_query_parameter(self):
         expires = self._get_expiry_date()
diff --git a/tempest/api/object_storage/test_object_temp_url_negative.py b/tempest/api/object_storage/test_object_temp_url_negative.py
index b752348..343749e 100644
--- a/tempest/api/object_storage/test_object_temp_url_negative.py
+++ b/tempest/api/object_storage/test_object_temp_url_negative.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
@@ -19,9 +17,10 @@
 import time
 import urlparse
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.object_storage import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
@@ -92,6 +91,7 @@
         return url
 
     @test.attr(type=['gate', 'negative'])
+    @test.idempotent_id('5a583aca-c804-41ba-9d9a-e7be132bdf0b')
     @test.requires_ext(extension='tempurl', service='object')
     def test_get_object_after_expiration_time(self):
 
@@ -104,5 +104,5 @@
         # temp URL is valid for 1 seconds, let's wait 2
         time.sleep(2)
 
-        self.assertRaises(exceptions.Unauthorized,
+        self.assertRaises(lib_exc.Unauthorized,
                           self.object_client.get, url)
diff --git a/tempest/api/object_storage/test_object_version.py b/tempest/api/object_storage/test_object_version.py
index da40e5a..225159f 100644
--- a/tempest/api/object_storage/test_object_version.py
+++ b/tempest/api/object_storage/test_object_version.py
@@ -45,6 +45,7 @@
         self.assertEqual(header_value, versioned)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a151e158-dcbf-4a1f-a1e7-46cd65895a6f')
     @testtools.skipIf(
         not CONF.object_storage_feature_enabled.object_versioning,
         'Object-versioning is disabled')
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 97777db..b8b0562 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -12,12 +12,12 @@
 
 import os.path
 
+from tempest_lib import exceptions as lib_exc
 import yaml
 
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import log as logging
 import tempest.test
 
@@ -30,14 +30,19 @@
     """Base test case class for all Orchestration API tests."""
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseOrchestrationTest, cls).resource_setup()
-        cls.os = clients.Manager()
+    def skip_checks(cls):
+        super(BaseOrchestrationTest, cls).skip_checks()
         if not CONF.service_available.heat:
             raise cls.skipException("Heat support is required")
-        cls.build_timeout = CONF.orchestration.build_timeout
-        cls.build_interval = CONF.orchestration.build_interval
 
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseOrchestrationTest, cls).setup_credentials()
+        cls.os = clients.Manager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseOrchestrationTest, cls).setup_clients()
         cls.orchestration_client = cls.os.orchestration_client
         cls.client = cls.orchestration_client
         cls.servers_client = cls.os.servers_client
@@ -45,6 +50,12 @@
         cls.network_client = cls.os.network_client
         cls.volumes_client = cls.os.volumes_client
         cls.images_v2_client = cls.os.image_client_v2
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaseOrchestrationTest, cls).resource_setup()
+        cls.build_timeout = CONF.orchestration.build_timeout
+        cls.build_interval = CONF.orchestration.build_interval
         cls.stacks = []
         cls.keypairs = []
         cls.images = []
@@ -59,7 +70,7 @@
     @classmethod
     def _get_identity_admin_client(cls):
         """Returns an instance of the Identity Admin API client."""
-        manager = clients.AdminManager(interface=cls._interface)
+        manager = clients.AdminManager()
         admin_client = manager.identity_client
         return admin_client
 
@@ -84,14 +95,14 @@
         for stack_identifier in cls.stacks:
             try:
                 cls.client.delete_stack(stack_identifier)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
 
         for stack_identifier in cls.stacks:
             try:
                 cls.client.wait_for_stack_status(
                     stack_identifier, 'DELETE_COMPLETE')
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
 
     @classmethod
@@ -125,7 +136,7 @@
         for image_id in cls.images:
             try:
                 cls.images_v2_client.delete_image(image_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
 
     @classmethod
diff --git a/tempest/api/orchestration/stacks/test_environment.py b/tempest/api/orchestration/stacks/test_environment.py
index 96e1c50..2989709 100644
--- a/tempest/api/orchestration/stacks/test_environment.py
+++ b/tempest/api/orchestration/stacks/test_environment.py
@@ -25,6 +25,7 @@
 class StackEnvironmentTest(base.BaseOrchestrationTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('37d4346b-1abd-4442-b7b1-2a4e5749a1e3')
     def test_environment_parameter(self):
         """Test passing a stack parameter via the environment."""
         stack_name = data_utils.rand_name('heat')
@@ -42,6 +43,7 @@
         self.assertEqual(20, len(random_value))
 
     @test.attr(type='gate')
+    @test.idempotent_id('73bce717-ad22-4853-bbef-6ed89b632701')
     def test_environment_provider_resource(self):
         """Test passing resource_registry defining a provider resource."""
         stack_name = data_utils.rand_name('heat')
@@ -71,6 +73,7 @@
         self.assertEqual(expected_length, len(random_value))
 
     @test.attr(type='gate')
+    @test.idempotent_id('9d682e5a-f4bb-47d5-8472-9d3cacb855df')
     def test_files_provider_resource(self):
         """Test untyped defining of a provider resource via "files"."""
         # It's also possible to specify the filename directly in the template.
diff --git a/tempest/api/orchestration/stacks/test_limits.py b/tempest/api/orchestration/stacks/test_limits.py
index 8ee62ab..833fb28 100644
--- a/tempest/api/orchestration/stacks/test_limits.py
+++ b/tempest/api/orchestration/stacks/test_limits.py
@@ -11,11 +11,11 @@
 #    under the License.
 
 import logging
+from tempest_lib import exceptions as lib_exc
 
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -26,6 +26,7 @@
 class TestServerStackLimits(base.BaseOrchestrationTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('ec9bed71-c460-45c9-ab98-295caa9fd76b')
     def test_exceed_max_template_size_fails(self):
         stack_name = data_utils.rand_name('heat')
         fill = 'A' * CONF.orchestration.max_template_size
@@ -34,11 +35,12 @@
 Description: '%s'
 Outputs:
   Foo: bar''' % fill
-        ex = self.assertRaises(exceptions.BadRequest, self.create_stack,
+        ex = self.assertRaises(lib_exc.BadRequest, self.create_stack,
                                stack_name, template)
         self.assertIn('Template exceeds maximum allowed size', str(ex))
 
     @test.attr(type='gate')
+    @test.idempotent_id('d1b83e73-7cad-4a22-9839-036548c5387c')
     def test_exceed_max_resources_per_stack(self):
         stack_name = data_utils.rand_name('heat')
         # Create a big template, one resource more than the limit
@@ -48,6 +50,6 @@
         for i in range(num_resources):
             template += rsrc_snippet % i
 
-        ex = self.assertRaises(exceptions.BadRequest, self.create_stack,
+        ex = self.assertRaises(lib_exc.BadRequest, self.create_stack,
                                stack_name, template)
         self.assertIn('Maximum resources per stack exceeded', str(ex))
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index ea6d4be..253d197 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -30,15 +30,27 @@
 class NeutronResourcesTestJSON(base.BaseOrchestrationTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(NeutronResourcesTestJSON, cls).resource_setup()
+    def skip_checks(cls):
+        super(NeutronResourcesTestJSON, cls).skip_checks()
         if not CONF.orchestration.image_ref:
             raise cls.skipException("No image available to test")
-        os = clients.Manager()
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron support is required")
+
+    @classmethod
+    def setup_credentials(cls):
+        super(NeutronResourcesTestJSON, cls).setup_credentials()
+        cls.os = clients.Manager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(NeutronResourcesTestJSON, cls).setup_clients()
+        cls.network_client = cls.os.network_client
+
+    @classmethod
+    def resource_setup(cls):
+        super(NeutronResourcesTestJSON, cls).resource_setup()
         cls.neutron_basic_template = cls.load_template('neutron_basic')
-        cls.network_client = os.network_client
         cls.stack_name = data_utils.rand_name('heat')
         template = cls.read_template('neutron_basic')
         cls.keypair_name = (CONF.orchestration.keypair_name or
@@ -75,8 +87,8 @@
                                                'Server')
                 server_id = body['physical_resource_id']
                 LOG.debug('Console output for %s', server_id)
-                _, output = cls.servers_client.get_console_output(
-                    server_id, None)
+                output = cls.servers_client.get_console_output(
+                    server_id, None).data
                 LOG.debug(output)
             raise e
 
@@ -85,6 +97,7 @@
             cls.test_resources[resource['logical_resource_id']] = resource
 
     @test.attr(type='slow')
+    @test.idempotent_id('f9e2664c-bc44-4eef-98b6-495e4f9d74b3')
     def test_created_resources(self):
         """Verifies created neutron resources."""
         resources = [('Network', self.neutron_basic_template['resources'][
@@ -103,6 +116,7 @@
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
     @test.attr(type='slow')
+    @test.idempotent_id('c572b915-edb1-4e90-b196-c7199a6848c0')
     @test.services('network')
     def test_created_network(self):
         """Verifies created network."""
@@ -115,6 +129,7 @@
             'Network']['properties']['name'], network['name'])
 
     @test.attr(type='slow')
+    @test.idempotent_id('e8f84b96-f9d7-4684-ad5f-340203e9f2c2')
     @test.services('network')
     def test_created_subnet(self):
         """Verifies created subnet."""
@@ -133,6 +148,7 @@
         self.assertEqual(str(self.subnet_cidr), subnet['cidr'])
 
     @test.attr(type='slow')
+    @test.idempotent_id('96af4c7f-5069-44bc-bdcf-c0390f8a67d1')
     @test.services('network')
     def test_created_router(self):
         """Verifies created router."""
@@ -146,6 +162,7 @@
         self.assertEqual(True, router['admin_state_up'])
 
     @test.attr(type='slow')
+    @test.idempotent_id('89f605bd-153e-43ee-a0ed-9919b63423c5')
     @test.services('network')
     def test_created_router_interface(self):
         """Verifies created router interface."""
@@ -169,11 +186,12 @@
                          router_interface_ip)
 
     @test.attr(type='slow')
+    @test.idempotent_id('75d85316-4ac2-4c0e-a1a9-edd2148fc10e')
     @test.services('compute', 'network')
     def test_created_server(self):
         """Verifies created sever."""
         server_id = self.test_resources.get('Server')['physical_resource_id']
-        _, server = self.servers_client.get_server(server_id)
+        server = self.servers_client.get_server(server_id)
         self.assertEqual(self.keypair_name, server['key_name'])
         self.assertEqual('ACTIVE', server['status'])
         network = server['addresses'][self.neutron_basic_template['resources'][
diff --git a/tempest/api/orchestration/stacks/test_non_empty_stack.py b/tempest/api/orchestration/stacks/test_non_empty_stack.py
index db1ac9a..e8f3522 100644
--- a/tempest/api/orchestration/stacks/test_non_empty_stack.py
+++ b/tempest/api/orchestration/stacks/test_non_empty_stack.py
@@ -54,6 +54,7 @@
         return stacks
 
     @test.attr(type='gate')
+    @test.idempotent_id('065c652a-720d-4760-9132-06aedeb8e3ab')
     def test_stack_list(self):
         """Created stack should be in the list of existing stacks."""
         stacks = self._list_stacks()
@@ -61,6 +62,7 @@
         self.assertIn(self.stack_name, stacks_names)
 
     @test.attr(type='gate')
+    @test.idempotent_id('992f96e3-41ee-4ff6-91c7-bcfb670c0919')
     def test_stack_show(self):
         """Getting details about created stack should be possible."""
         stack = self.client.get_stack(self.stack_name)
@@ -80,6 +82,7 @@
         self.assertEqual('fluffy', stack['outputs'][0]['output_key'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('fe719f7a-305a-44d8-bbb5-c91e93d9da17')
     def test_suspend_resume_stack(self):
         """Suspend and resume a stack."""
         self.client.suspend_stack(self.stack_identifier)
@@ -90,6 +93,7 @@
                                           'RESUME_COMPLETE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('c951d55e-7cce-4c1f-83a0-bad735437fa6')
     def test_list_resources(self):
         """Getting list of created resources for the stack should be possible.
         """
@@ -97,6 +101,7 @@
         self.assertEqual({self.resource_name: self.resource_type}, resources)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2aba03b3-392f-4237-900b-1f5a5e9bd962')
     def test_show_resource(self):
         """Getting details about created resource should be possible."""
         resource = self.client.get_resource(self.stack_identifier,
@@ -111,6 +116,7 @@
         self.assertEqual(self.resource_type, resource['resource_type'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('898070a9-eba5-4fae-b7d6-cf3ffa03090f')
     def test_resource_metadata(self):
         """Getting metadata for created resources should be possible."""
         metadata = self.client.show_resource_metadata(
@@ -120,6 +126,7 @@
         self.assertEqual(['Tom', 'Stinky'], metadata.get('kittens', None))
 
     @test.attr(type='gate')
+    @test.idempotent_id('46567533-0a7f-483b-8942-fa19e0f17839')
     def test_list_events(self):
         """Getting list of created events for the stack should be possible."""
         events = self.client.list_events(self.stack_identifier)
@@ -135,6 +142,7 @@
         self.assertIn('CREATE_COMPLETE', resource_statuses)
 
     @test.attr(type='gate')
+    @test.idempotent_id('92465723-1673-400a-909d-4773757a3f21')
     def test_show_event(self):
         """Getting details about an event should be possible."""
         events = self.client.list_resource_events(self.stack_identifier,
diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
index 772bab3..6d2dcc7 100644
--- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -49,6 +49,7 @@
             cls.test_resources[resource['logical_resource_id']] = resource
 
     @test.attr(type='gate')
+    @test.idempotent_id('b476eac2-a302-4815-961f-18c410a2a537')
     def test_created_resources(self):
         """Verifies created keypair resource."""
 
@@ -69,6 +70,7 @@
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('8d77dec7-91fd-45a6-943d-5abd45e338a4')
     def test_stack_keypairs_output(self):
         stack = self.client.get_stack(self.stack_name)
         self.assertIsInstance(stack, dict)
diff --git a/tempest/api/orchestration/stacks/test_resource_types.py b/tempest/api/orchestration/stacks/test_resource_types.py
index e204894..32b0b8e 100644
--- a/tempest/api/orchestration/stacks/test_resource_types.py
+++ b/tempest/api/orchestration/stacks/test_resource_types.py
@@ -17,6 +17,7 @@
 class ResourceTypesTest(base.BaseOrchestrationTest):
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7123d082-3577-4a30-8f00-f805327c4ffd')
     def test_resource_type_list(self):
         """Verify it is possible to list resource types."""
         resource_types = self.client.list_resource_types()
@@ -24,6 +25,7 @@
         self.assertIn('OS::Nova::Server', resource_types)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0e85a483-828b-4a28-a0e3-f0a21809192b')
     def test_resource_type_show(self):
         """Verify it is possible to get schema about resource types."""
         resource_types = self.client.list_resource_types()
@@ -36,9 +38,12 @@
             self.assertEqual(resource_type, type_schema['resource_type'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8401821d-65fe-4d43-9fa3-57d5ce3a35c7')
     def test_resource_type_template(self):
         """Verify it is possible to get template about resource types."""
         type_template = self.client.get_resource_type_template(
             'OS::Nova::Server')
-        self.assert_fields_in_dict(type_template, 'Outputs',
-            'Parameters', 'Resources')
\ No newline at end of file
+        self.assert_fields_in_dict(
+            type_template,
+            'Outputs',
+            'Parameters', 'Resources')
diff --git a/tempest/api/orchestration/stacks/test_soft_conf.py b/tempest/api/orchestration/stacks/test_soft_conf.py
index 8903d4c..7387c62 100644
--- a/tempest/api/orchestration/stacks/test_soft_conf.py
+++ b/tempest/api/orchestration/stacks/test_soft_conf.py
@@ -10,10 +10,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest import test
 
@@ -70,16 +71,17 @@
         self.client.delete_software_deploy(deploy_id)
         # Testing that it is really gone
         self.assertRaises(
-            exceptions.NotFound, self.client.get_software_deploy,
+            lib_exc.NotFound, self.client.get_software_deploy,
             self.deployment_id)
 
     def _config_delete(self, config_id):
         self.client.delete_software_config(config_id)
         # Testing that it is really gone
         self.assertRaises(
-            exceptions.NotFound, self.client.get_software_config, config_id)
+            lib_exc.NotFound, self.client.get_software_config, config_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('136162ed-9445-4b9c-b7fc-306af8b5da99')
     def test_get_software_config(self):
         """Testing software config get."""
         for conf in self.configs:
@@ -87,6 +89,7 @@
             self._validate_config(conf, api_config)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1275c835-c967-4a2c-8d5d-ad533447ed91')
     def test_get_deployment_list(self):
         """Getting a list of all deployments"""
         deploy_list = self.client.get_software_deploy_list()
@@ -95,6 +98,7 @@
         self.assertIn(self.deployment_id, deploy_ids)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fe7cd9f9-54b1-429c-a3b7-7df8451db913')
     def test_get_deployment_metadata(self):
         """Testing deployment metadata get"""
         metadata = self.client.get_software_deploy_meta(self.server_id)
@@ -111,6 +115,7 @@
                          deployment['software_deployment']['config_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f29d21f3-ed75-47cf-8cdc-ef1bdeb4c674')
     def test_software_deployment_create_validate(self):
         """Testing software deployment was created as expected."""
         # Asserting that all fields were created
@@ -123,6 +128,7 @@
                                   self.status_reason, self.configs[0]['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2ac43ab3-34f2-415d-be2e-eabb4d14ee32')
     def test_software_deployment_update_no_metadata_change(self):
         """Testing software deployment update without metadata change."""
         metadata = self.client.get_software_deploy_meta(self.server_id)
@@ -146,6 +152,7 @@
                 test_metadata['metadata'][0][key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('92c48944-d79d-4595-a840-8e1a581c1a72')
     def test_software_deployment_update_with_metadata_change(self):
         """Testing software deployment update with metadata change."""
         metadata = self.client.get_software_deploy_meta(self.server_id)
diff --git a/tempest/api/orchestration/stacks/test_stacks.py b/tempest/api/orchestration/stacks/test_stacks.py
index 5cdd8b4..a9b3a6b 100644
--- a/tempest/api/orchestration/stacks/test_stacks.py
+++ b/tempest/api/orchestration/stacks/test_stacks.py
@@ -27,11 +27,13 @@
         super(StacksTestJSON, cls).resource_setup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d35d628c-07f6-4674-85a1-74db9919e986')
     def test_stack_list_responds(self):
         stacks = self.client.list_stacks()
         self.assertIsInstance(stacks, list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('10498bd5-a83e-4b62-a817-ce24afe938fe')
     def test_stack_crud_no_resources(self):
         stack_name = data_utils.rand_name('heat')
 
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
index 0288fd4..1290dfe 100644
--- a/tempest/api/orchestration/stacks/test_swift_resources.py
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -1,8 +1,6 @@
 # -*- coding: utf-8 -*-
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Chmouel Boudjnah <chmouel@enovance.com>
-#
 # 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
@@ -26,15 +24,27 @@
 
 class SwiftResourcesTestJSON(base.BaseOrchestrationTest):
     @classmethod
+    def skip_checks(cls):
+        super(SwiftResourcesTestJSON, cls).skip_checks()
+        if not CONF.service_available.swift:
+            raise cls.skipException("Swift support is required")
+
+    @classmethod
+    def setup_credentials(cls):
+        super(SwiftResourcesTestJSON, cls).setup_credentials()
+        cls.os = clients.Manager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(SwiftResourcesTestJSON, cls).setup_clients()
+        cls.account_client = cls.os.account_client
+        cls.container_client = cls.os.container_client
+
+    @classmethod
     def resource_setup(cls):
         super(SwiftResourcesTestJSON, cls).resource_setup()
         cls.stack_name = data_utils.rand_name('heat')
         template = cls.read_template('swift_basic')
-        os = clients.Manager()
-        if not CONF.service_available.swift:
-            raise cls.skipException("Swift support is required")
-        cls.account_client = os.account_client
-        cls.container_client = os.container_client
         # create the stack
         cls.stack_identifier = cls.create_stack(
             cls.stack_name,
@@ -46,6 +56,7 @@
         for resource in resources:
             cls.test_resources[resource['logical_resource_id']] = resource
 
+    @test.idempotent_id('1a6fe69e-4be4-4990-9a7a-84b6f18019cb')
     def test_created_resources(self):
         """Created stack should be in the list of existing stacks."""
         swift_basic_template = self.load_template('swift_basic')
@@ -60,6 +71,7 @@
             self.assertEqual(resource_name, resource['logical_resource_id'])
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
+    @test.idempotent_id('bd438b18-5494-4d5a-9ce6-d2a942ec5060')
     @test.services('object_storage')
     def test_created_containers(self):
         params = {'format': 'json'}
@@ -69,6 +81,7 @@
                               if cont['name'].startswith(self.stack_name)]
         self.assertEqual(2, len(created_containers))
 
+    @test.idempotent_id('73d0c093-9922-44a0-8b1d-1fc092dee367')
     @test.services('object_storage')
     def test_acl(self):
         acl_headers = ('x-container-meta-web-index', 'x-container-read')
@@ -86,6 +99,7 @@
         for h in acl_headers:
             self.assertIn(h, headers)
 
+    @test.idempotent_id('fda06135-6777-4594-aefa-0f6107169698')
     @test.services('object_storage')
     def test_metadata(self):
         swift_basic_template = self.load_template('swift_basic')
diff --git a/tempest/api/orchestration/stacks/test_templates.py b/tempest/api/orchestration/stacks/test_templates.py
index 6113cab..d0fc1cf 100644
--- a/tempest/api/orchestration/stacks/test_templates.py
+++ b/tempest/api/orchestration/stacks/test_templates.py
@@ -36,11 +36,13 @@
         cls.parameters = {}
 
     @test.attr(type='gate')
+    @test.idempotent_id('47430699-c368-495e-a1db-64c26fd967d7')
     def test_show_template(self):
         """Getting template used to create the stack."""
         self.client.show_template(self.stack_identifier)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ed53debe-8727-46c5-ab58-eba6090ec4de')
     def test_validate_template(self):
         """Validating template passing it content."""
         self.client.validate_template(self.template,
diff --git a/tempest/api/orchestration/stacks/test_templates_negative.py b/tempest/api/orchestration/stacks/test_templates_negative.py
index 9082107..ebba694 100644
--- a/tempest/api/orchestration/stacks/test_templates_negative.py
+++ b/tempest/api/orchestration/stacks/test_templates_negative.py
@@ -12,8 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.orchestration import base
-from tempest import exceptions
 from tempest import test
 
 
@@ -35,9 +36,10 @@
         cls.parameters = {}
 
     @test.attr(type=['gate', 'negative'])
+    @test.idempotent_id('5586cbca-ddc4-4152-9db8-fa1ce5fc1876')
     def test_validate_template_url(self):
         """Validating template passing url to it."""
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.validate_template_url,
                           template_url=self.invalid_template_url,
                           parameters=self.parameters)
diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py
index 6fddb21..5a1a6d7 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -12,10 +12,11 @@
 
 import logging
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 
@@ -26,8 +27,8 @@
 class CinderResourcesTest(base.BaseOrchestrationTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(CinderResourcesTest, cls).resource_setup()
+    def skip_checks(cls):
+        super(CinderResourcesTest, cls).skip_checks()
         if not CONF.service_available.cinder:
             raise cls.skipException('Cinder support is required')
 
@@ -54,6 +55,7 @@
             'name'], self.get_stack_output(stack_identifier, 'display_name'))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c3243329-7bdd-4730-b402-4d19d50c41d8')
     @test.services('volume')
     def test_cinder_volume_create_delete(self):
         """Create and delete a volume via OS::Cinder::Volume."""
@@ -73,7 +75,7 @@
         # Delete the stack and ensure the volume is gone
         self.client.delete_stack(stack_identifier)
         self.client.wait_for_stack_status(stack_identifier, 'DELETE_COMPLETE')
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.volumes_client.get_volume,
                           volume_id)
 
@@ -83,6 +85,7 @@
         self.volumes_client.wait_for_resource_deletion(volume_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ea8b3a46-b932-4c18-907a-fe23f00b33f8')
     @test.services('volume')
     def test_cinder_volume_create_delete_retain(self):
         """Ensure the 'Retain' deletion policy is respected."""
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index 8885187..c521b37 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -12,6 +12,8 @@
 
 import time
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -26,18 +28,29 @@
     """Base test case class for all Telemetry API tests."""
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
+        super(BaseTelemetryTest, cls).skip_checks()
         if not CONF.service_available.ceilometer:
             raise cls.skipException("Ceilometer support is required")
-        cls.set_network_resources()
-        super(BaseTelemetryTest, cls).resource_setup()
-        os = cls.get_client_manager()
-        cls.telemetry_client = os.telemetry_client
-        cls.servers_client = os.servers_client
-        cls.flavors_client = os.flavors_client
-        cls.image_client = os.image_client
-        cls.image_client_v2 = os.image_client_v2
 
+    @classmethod
+    def setup_credentials(cls):
+        cls.set_network_resources()
+        super(BaseTelemetryTest, cls).setup_credentials()
+        cls.os = cls.get_client_manager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseTelemetryTest, cls).setup_clients()
+        cls.telemetry_client = cls.os.telemetry_client
+        cls.servers_client = cls.os.servers_client
+        cls.flavors_client = cls.os.flavors_client
+        cls.image_client = cls.os.image_client
+        cls.image_client_v2 = cls.os.image_client_v2
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaseTelemetryTest, cls).resource_setup()
         cls.nova_notifications = ['memory', 'vcpus', 'disk.root.size',
                                   'disk.ephemeral.size']
 
@@ -60,12 +73,12 @@
 
     @classmethod
     def create_server(cls):
-        resp, body = cls.servers_client.create_server(
+        body = cls.servers_client.create_server(
             data_utils.rand_name('ceilometer-instance'),
             CONF.compute.image_ref, CONF.compute.flavor_ref,
             wait_until='ACTIVE')
         cls.server_ids.append(body['id'])
-        return resp, body
+        return body
 
     @classmethod
     def create_image(cls, client):
@@ -80,7 +93,7 @@
         for resource_id in list_of_ids:
             try:
                 method(resource_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
 
     @classmethod
diff --git a/tempest/api/telemetry/test_telemetry_alarming_api.py b/tempest/api/telemetry/test_telemetry_alarming_api.py
index 97eb4eb..768b6ea 100644
--- a/tempest/api/telemetry/test_telemetry_alarming_api.py
+++ b/tempest/api/telemetry/test_telemetry_alarming_api.py
@@ -10,14 +10,14 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.telemetry import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class TelemetryAlarmingAPITestJSON(base.BaseTelemetryTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -30,6 +30,7 @@
             cls.create_alarm(threshold_rule=cls.rule)
 
     @test.attr(type="gate")
+    @test.idempotent_id('1c918e06-210b-41eb-bd45-14676dd77cd6')
     def test_alarm_list(self):
         # List alarms
         alarm_list = self.telemetry_client.list_alarms()
@@ -43,6 +44,7 @@
                          ', '.join(str(a) for a in missing_alarms))
 
     @test.attr(type="gate")
+    @test.idempotent_id('1297b095-39c1-4e74-8a1f-4ae998cedd67')
     def test_create_update_get_delete_alarm(self):
         # Create an alarm
         alarm_name = data_utils.rand_name('telemetry_alarm')
@@ -70,24 +72,26 @@
         self.assertDictContainsSubset(new_rule, body['threshold_rule'])
         # Delete alarm and verify if deleted
         self.telemetry_client.delete_alarm(alarm_id)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.telemetry_client.get_alarm, alarm_id)
 
     @test.attr(type="gate")
+    @test.idempotent_id('aca49486-70bb-4016-87e0-f6131374f741')
     def test_set_get_alarm_state(self):
         alarm_states = ['ok', 'alarm', 'insufficient data']
         alarm = self.create_alarm(threshold_rule=self.rule)
         # Set alarm state and verify
         new_state =\
             [elem for elem in alarm_states if elem != alarm['state']][0]
-        _, state = self.telemetry_client.alarm_set_state(alarm['alarm_id'],
-                                                         new_state)
-        self.assertEqual(new_state, state)
+        state = self.telemetry_client.alarm_set_state(alarm['alarm_id'],
+                                                      new_state)
+        self.assertEqual(new_state, state.data)
         # Get alarm state and verify
-        _, state = self.telemetry_client.alarm_get_state(alarm['alarm_id'])
-        self.assertEqual(new_state, state)
+        state = self.telemetry_client.alarm_get_state(alarm['alarm_id'])
+        self.assertEqual(new_state, state.data)
 
     @test.attr(type="gate")
+    @test.idempotent_id('08d7e45a-1344-4e5c-ba6f-f6cbb77f55b9')
     def test_create_delete_alarm_with_combination_rule(self):
         rule = {"alarm_ids": self.alarm_ids,
                 "operator": "or"}
@@ -101,5 +105,5 @@
         self.assertDictContainsSubset(rule, body['combination_rule'])
         # Verify alarm delete
         self.telemetry_client.delete_alarm(alarm_id)
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.telemetry_client.get_alarm, alarm_id)
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index 7e5d6ee..6862401 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -21,22 +21,21 @@
 
 
 class TelemetryNotificationAPITestJSON(base.BaseTelemetryTest):
-    _interface = 'json'
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
+        super(TelemetryNotificationAPITestJSON, cls).skip_checks()
         if CONF.telemetry.too_slow_to_test:
             raise cls.skipException("Ceilometer feature for fast work mysql "
                                     "is disabled")
-        super(TelemetryNotificationAPITestJSON, cls).resource_setup()
 
     @test.attr(type="gate")
+    @test.idempotent_id('d7f8c1c8-d470-4731-8604-315d3956caad')
     @testtools.skipIf(not CONF.service_available.nova,
                       "Nova is not available.")
     def test_check_nova_notification(self):
 
-        resp, body = self.create_server()
-        self.assertEqual(resp.status, 202)
+        body = self.create_server()
 
         query = ('resource', 'eq', body['id'])
 
@@ -44,6 +43,7 @@
             self.await_samples(metric, query)
 
     @test.attr(type="smoke")
+    @test.idempotent_id('04b10bfe-a5dc-47af-b22f-0460426bf498')
     @test.services("image")
     @testtools.skipIf(not CONF.image_feature_enabled.api_v1,
                       "Glance api v1 is disabled")
@@ -60,6 +60,7 @@
             self.await_samples(metric, query)
 
     @test.attr(type="smoke")
+    @test.idempotent_id('c240457d-d943-439b-8aea-85e26d64fe8e')
     @test.services("image")
     @testtools.skipIf(not CONF.image_feature_enabled.api_v2,
                       "Glance api v2 is disabled")
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 65c4bd3..97dd104 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -22,13 +22,17 @@
 
 
 class VolumeMultiBackendV2Test(base.BaseVolumeAdminTest):
-    _interface = "json"
+
+    @classmethod
+    def skip_checks(cls):
+        super(VolumeMultiBackendV2Test, cls).skip_checks()
+
+        if not CONF.volume_feature_enabled.multi_backend:
+            raise cls.skipException("Cinder multi-backend feature disabled")
 
     @classmethod
     def resource_setup(cls):
         super(VolumeMultiBackendV2Test, cls).resource_setup()
-        if not CONF.volume_feature_enabled.multi_backend:
-            raise cls.skipException("Cinder multi-backend feature disabled")
 
         cls.backend1_name = CONF.volume.backend1_name
         cls.backend2_name = CONF.volume.backend2_name
@@ -97,18 +101,21 @@
         super(VolumeMultiBackendV2Test, cls).resource_cleanup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c1a41f3f-9dad-493e-9f09-3ff197d477cc')
     def test_backend_name_reporting(self):
         # get volume id which created by type without prefix
         volume_id = self.volume_id_list_without_prefix[0]
         self._test_backend_name_reporting_by_volume_id(volume_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f38e647f-ab42-4a31-a2e7-ca86a6485215')
     def test_backend_name_reporting_with_prefix(self):
         # get volume id which created by type with prefix
         volume_id = self.volume_id_list_with_prefix[0]
         self._test_backend_name_reporting_by_volume_id(volume_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('46435ab1-a0af-4401-8373-f14e66b0dd58')
     def test_backend_name_distinction(self):
         if self.backend1_name == self.backend2_name:
             raise self.skipException("backends configured with same name")
@@ -118,6 +125,7 @@
         self._test_backend_name_distinction(volume1_id, volume2_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4236305b-b65a-4bfc-a9d2-69cb5b2bf2ed')
     def test_backend_name_distinction_with_prefix(self):
         if self.backend1_name == self.backend2_name:
             raise self.skipException("backends configured with same name")
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 6c64298..469f13e 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -19,12 +19,15 @@
 
 
 class SnapshotsActionsV2Test(base.BaseVolumeAdminTest):
-    _interface = "json"
+
+    @classmethod
+    def setup_clients(cls):
+        super(SnapshotsActionsV2Test, cls).setup_clients()
+        cls.client = cls.snapshots_client
 
     @classmethod
     def resource_setup(cls):
         super(SnapshotsActionsV2Test, cls).resource_setup()
-        cls.client = cls.snapshots_client
 
         # Create a test shared volume for tests
         vol_name = data_utils.rand_name(cls.__name__ + '-Volume-')
@@ -78,6 +81,7 @@
         return 'os-extended-snapshot-attributes:progress'
 
     @test.attr(type='gate')
+    @test.idempotent_id('3e13ca2f-48ea-49f3-ae1a-488e9180d535')
     def test_reset_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
@@ -88,6 +92,7 @@
         self.assertEqual(status, snapshot_get['status'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('41288afd-d463-485e-8f6e-4eea159413eb')
     def test_update_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
@@ -106,21 +111,25 @@
         self.assertEqual(progress, snapshot_get[progress_alias])
 
     @test.attr(type='gate')
+    @test.idempotent_id('05f711b6-e629-4895-8103-7ca069f2073a')
     def test_snapshot_force_delete_when_snapshot_is_creating(self):
         # test force delete when status of snapshot is creating
         self._create_reset_and_force_delete_temp_snapshot('creating')
 
     @test.attr(type='gate')
+    @test.idempotent_id('92ce8597-b992-43a1-8868-6316b22a969e')
     def test_snapshot_force_delete_when_snapshot_is_deleting(self):
         # test force delete when status of snapshot is deleting
         self._create_reset_and_force_delete_temp_snapshot('deleting')
 
     @test.attr(type='gate')
+    @test.idempotent_id('645a4a67-a1eb-4e8e-a547-600abac1525d')
     def test_snapshot_force_delete_when_snapshot_is_error(self):
         # test force delete when status of snapshot is error
         self._create_reset_and_force_delete_temp_snapshot('error')
 
     @test.attr(type='gate')
+    @test.idempotent_id('bf89080f-8129-465e-9327-b2f922666ba5')
     def test_snapshot_force_delete_when_snapshot_is_error_deleting(self):
         # test force delete when status of snapshot is error_deleting
         self._create_reset_and_force_delete_temp_snapshot('error_deleting')
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index a214edf..551dc6f 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -18,9 +18,9 @@
 
 
 class VolumeHostsAdminV2TestsJSON(base.BaseVolumeAdminTest):
-    _interface = "json"
 
     @test.attr(type='gate')
+    @test.idempotent_id('d5f3efa2-6684-4190-9ced-1c2f526352ad')
     def test_list_hosts(self):
         hosts = self.hosts_client.list_hosts()
         self.assertTrue(len(hosts) >= 2, "No. of hosts are < 2,"
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 52f2d90..27375de 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
 #
-# Author: Sylvain Baubeau <sylvain.baubeau@enovance.com>
-#
 #    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
@@ -23,21 +21,22 @@
 
 
 class BaseVolumeQuotasAdminV2TestJSON(base.BaseVolumeAdminTest):
-    _interface = "json"
     force_tenant_isolation = True
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseVolumeQuotasAdminV2TestJSON, cls).resource_setup()
+    def setup_credentials(cls):
+        super(BaseVolumeQuotasAdminV2TestJSON, cls).setup_credentials()
         cls.demo_tenant_id = cls.isolated_creds.get_primary_creds().tenant_id
 
     @test.attr(type='gate')
+    @test.idempotent_id('59eada70-403c-4cef-a2a3-a8ce2f1b07a0')
     def test_list_quotas(self):
         quotas = self.quotas_client.get_quota_set(self.demo_tenant_id)
         for key in QUOTA_KEYS:
             self.assertIn(key, quotas)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2be020a2-5fdd-423d-8d35-a7ffbc36e9f7')
     def test_list_default_quotas(self):
         quotas = self.quotas_client.get_default_quota_set(
             self.demo_tenant_id)
@@ -45,6 +44,7 @@
             self.assertIn(key, quotas)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3d45c99e-cc42-4424-a56e-5cbd212b63a6')
     def test_update_all_quota_resources_for_tenant(self):
         # Admin can update all the resource quota limits for a tenant
         default_quota_set = self.quotas_client.get_default_quota_set(
@@ -69,6 +69,7 @@
         self.assertDictContainsSubset(new_quota_set, quota_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('18c51ae9-cb03-48fc-b234-14a19374dbed')
     def test_show_quota_usage(self):
         quota_usage = self.quotas_client.get_quota_usage(
             self.os_adm.credentials.tenant_id)
@@ -78,6 +79,7 @@
                 self.assertIn(usage_key, quota_usage[key])
 
     @test.attr(type='gate')
+    @test.idempotent_id('ae8b6091-48ad-4bfa-a188-bbf5cc02115f')
     def test_quota_usage(self):
         quota_usage = self.quotas_client.get_quota_usage(
             self.demo_tenant_id)
@@ -96,6 +98,7 @@
                          new_quota_usage['gigabytes']['in_use'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('874b35a9-51f1-4258-bec5-cd561b6690d3')
     def test_delete_quota(self):
         # Admin can delete the resource quota set for a tenant
         tenant_name = data_utils.rand_name('quota_tenant_')
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index 5cf6af0..67edd09 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -13,20 +13,24 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.volume import base
-from tempest import exceptions
 from tempest import test
 
 
 class BaseVolumeQuotasNegativeV2TestJSON(base.BaseVolumeAdminTest):
-    _interface = "json"
     force_tenant_isolation = True
 
     @classmethod
+    def setup_credentials(cls):
+        super(BaseVolumeQuotasNegativeV2TestJSON, cls).setup_credentials()
+        cls.demo_user = cls.isolated_creds.get_primary_creds()
+        cls.demo_tenant_id = cls.demo_user.tenant_id
+
+    @classmethod
     def resource_setup(cls):
         super(BaseVolumeQuotasNegativeV2TestJSON, cls).resource_setup()
-        demo_user = cls.isolated_creds.get_primary_creds()
-        cls.demo_tenant_id = demo_user.tenant_id
         cls.shared_quota_set = {'gigabytes': 3, 'volumes': 1, 'snapshots': 1}
 
         # NOTE(gfidente): no need to restore original quota set
@@ -41,18 +45,21 @@
         cls.snapshot = cls.create_snapshot(cls.volume['id'])
 
     @test.attr(type='negative')
+    @test.idempotent_id('bf544854-d62a-47f2-a681-90f7a47d86b6')
     def test_quota_volumes(self):
-        self.assertRaises(exceptions.OverLimit,
+        self.assertRaises(lib_exc.OverLimit,
                           self.volumes_client.create_volume,
                           size=1)
 
     @test.attr(type='negative')
+    @test.idempotent_id('02bbf63f-6c05-4357-9d98-2926a94064ff')
     def test_quota_volume_snapshots(self):
-        self.assertRaises(exceptions.OverLimit,
+        self.assertRaises(lib_exc.OverLimit,
                           self.snapshots_client.create_snapshot,
                           self.volume['id'])
 
     @test.attr(type='negative')
+    @test.idempotent_id('2dc27eee-8659-4298-b900-169d71a91374')
     def test_quota_volume_gigabytes(self):
         # NOTE(gfidente): quota set needs to be changed for this test
         # or we may be limited by the volumes or snaps quota number, not by
@@ -65,7 +72,7 @@
         self.quotas_client.update_quota_set(
             self.demo_tenant_id,
             **new_quota_set)
-        self.assertRaises(exceptions.OverLimit,
+        self.assertRaises(lib_exc.OverLimit,
                           self.volumes_client.create_volume,
                           size=1)
 
@@ -73,7 +80,7 @@
         self.quotas_client.update_quota_set(
             self.demo_tenant_id,
             **self.shared_quota_set)
-        self.assertRaises(exceptions.OverLimit,
+        self.assertRaises(lib_exc.OverLimit,
                           self.snapshots_client.create_snapshot,
                           self.volume['id'])
 
diff --git a/tempest/api/volume/admin/test_volume_services.py b/tempest/api/volume/admin/test_volume_services.py
index 46db70f..cc4f1a0 100644
--- a/tempest/api/volume/admin/test_volume_services.py
+++ b/tempest/api/volume/admin/test_volume_services.py
@@ -22,7 +22,6 @@
     Tests Volume Services API.
     volume service list requires admin privileges.
     """
-    _interface = "json"
 
     @classmethod
     def resource_setup(cls):
@@ -32,11 +31,13 @@
         cls.binary_name = cls.services[0]['binary']
 
     @test.attr(type='gate')
+    @test.idempotent_id('e0218299-0a59-4f43-8b2b-f1c035b3d26d')
     def test_list_services(self):
         services = self.admin_volume_services_client.list_services()
         self.assertNotEqual(0, len(services))
 
     @test.attr(type='gate')
+    @test.idempotent_id('63a3e1ca-37ee-4983-826d-83276a370d25')
     def test_get_service_by_service_binary_name(self):
         params = {'binary': self.binary_name}
         services = self.admin_volume_services_client.list_services(params)
@@ -45,6 +46,7 @@
             self.assertEqual(self.binary_name, service['binary'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('178710e4-7596-4e08-9333-745cb8bc4f8d')
     def test_get_service_by_host_name(self):
         services_on_host = [service for service in self.services if
                             service['host'] == self.host_name]
@@ -61,6 +63,7 @@
         self.assertEqual(sorted(s1), sorted(s2))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ffa6167c-4497-4944-a464-226bbdb53908')
     def test_get_service_by_service_and_host_name(self):
         params = {'host': self.host_name, 'binary': self.binary_name}
 
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 58f1551..8705f6f 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -22,7 +22,6 @@
 
 
 class VolumeTypesV2Test(base.BaseVolumeAdminTest):
-    _interface = "json"
 
     def _delete_volume(self, volume_id):
         self.volumes_client.delete_volume(volume_id)
@@ -32,53 +31,65 @@
         self.volume_types_client.delete_volume_type(volume_type_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9d9b28e3-1b2e-4483-a2cc-24aa0ea1de54')
     def test_volume_type_list(self):
         # List Volume types.
         body = self.volume_types_client.list_volume_types()
         self.assertIsInstance(body, list)
 
     @test.attr(type='smoke')
-    def test_create_get_delete_volume_with_volume_type_and_extra_specs(self):
-        # Create/get/delete volume with volume_type and extra spec.
-        volume = {}
+    @test.idempotent_id('c03cc62c-f4e9-4623-91ec-64ce2f9c1260')
+    def test_volume_crud_with_volume_type_and_extra_specs(self):
+        # Create/update/get/delete volume with volume_type and extra spec.
+        volume_types = list()
         vol_name = data_utils.rand_name("volume-")
-        vol_type_name = data_utils.rand_name("volume-type-")
         self.name_field = self.special_fields['name_field']
         proto = CONF.volume.storage_protocol
         vendor = CONF.volume.vendor_name
         extra_specs = {"storage_protocol": proto,
                        "vendor_name": vendor}
-        body = {}
-        body = self.volume_types_client.create_volume_type(
-            vol_type_name,
-            extra_specs=extra_specs)
-        self.assertIn('id', body)
-        self.addCleanup(self._delete_volume_type, body['id'])
-        self.assertIn('name', body)
-        params = {self.name_field: vol_name, 'volume_type': vol_type_name}
-        volume = self.volumes_client.create_volume(
-            size=1, **params)
-        self.assertIn('id', volume)
+        # Create two volume_types
+        for i in range(2):
+            vol_type_name = data_utils.rand_name("volume-type-")
+            vol_type = self.volume_types_client.create_volume_type(
+                vol_type_name,
+                extra_specs=extra_specs)
+            volume_types.append(vol_type)
+            self.addCleanup(self._delete_volume_type, vol_type['id'])
+        params = {self.name_field: vol_name,
+                  'volume_type': volume_types[0]['id']}
+
+        # Create volume
+        volume = self.volumes_client.create_volume(size=1, **params)
         self.addCleanup(self._delete_volume, volume['id'])
-        self.assertIn(self.name_field, volume)
+        self.assertEqual(volume_types[0]['name'], volume["volume_type"])
         self.assertEqual(volume[self.name_field], vol_name,
                          "The created volume name is not equal "
                          "to the requested name")
-        self.assertTrue(volume['id'] is not None,
-                        "Field volume id is empty or not found.")
+        self.assertIsNotNone(volume['id'],
+                             "Field volume id is empty or not found.")
         self.volumes_client.wait_for_volume_status(volume['id'], 'available')
+
+        # Update volume with new volume_type
+        self.volumes_client.retype_volume(volume['id'],
+                                          volume_type=volume_types[1]['id'])
+        self.volumes_client.wait_for_volume_status(volume['id'], 'available')
+
+        # Get volume details and Verify
         fetched_volume = self.volumes_client.get_volume(volume['id'])
+        self.assertEqual(volume_types[1]['name'],
+                         fetched_volume['volume_type'],
+                         'The fetched Volume type is different '
+                         'from updated volume type')
         self.assertEqual(vol_name, fetched_volume[self.name_field],
                          'The fetched Volume is different '
                          'from the created Volume')
         self.assertEqual(volume['id'], fetched_volume['id'],
                          'The fetched Volume is different '
                          'from the created Volume')
-        self.assertEqual(vol_type_name, fetched_volume['volume_type'],
-                         'The fetched Volume is different '
-                         'from the created Volume')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4e955c3b-49db-4515-9590-0c99f8e471ad')
     def test_volume_type_create_get_delete(self):
         # Create/get volume type.
         body = {}
@@ -111,6 +122,7 @@
                          'from the created Volume_type')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7830abd0-ff99-4793-a265-405684a54d46')
     def test_volume_type_encryption_create_get_delete(self):
         # Create/get/delete encryption type.
         provider = "LuksEncryptor"
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 460a6c3..5ca838e 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -19,7 +19,6 @@
 
 
 class VolumeTypesExtraSpecsV2Test(base.BaseVolumeAdminTest):
-    _interface = "json"
 
     @classmethod
     def resource_setup(cls):
@@ -34,6 +33,7 @@
         super(VolumeTypesExtraSpecsV2Test, cls).resource_cleanup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b42923e9-0452-4945-be5b-d362ae533e60')
     def test_volume_type_extra_specs_list(self):
         # List Volume types extra specs.
         extra_specs = {"spec1": "val1"}
@@ -47,6 +47,7 @@
         self.assertIn('spec1', body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('0806db36-b4a0-47a1-b6f3-c2e7f194d017')
     def test_volume_type_extra_specs_update(self):
         # Update volume type extra specs
         extra_specs = {"spec2": "val1"}
@@ -65,6 +66,7 @@
                          "Volume type extra spec incorrectly updated")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d4772798-601f-408a-b2a5-29e8a59d1220')
     def test_volume_type_extra_spec_create_get_delete(self):
         # Create/Get/Delete volume type extra spec.
         extra_specs = {"spec3": "val1"}
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index fff0199..6d2c4fb 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -15,14 +15,14 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class ExtraSpecsNegativeV2Test(base.BaseVolumeAdminTest):
-    _interface = 'json'
 
     @classmethod
     def resource_setup(cls):
@@ -39,103 +39,114 @@
         super(ExtraSpecsNegativeV2Test, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('08961d20-5cbb-4910-ac0f-89ad6dbb2da1')
     def test_update_no_body(self):
         # Should not update volume type extra specs with no body
         extra_spec = {"spec1": "val2"}
         self.assertRaises(
-            exceptions.BadRequest,
+            lib_exc.BadRequest,
             self.volume_types_client.update_volume_type_extra_specs,
             self.volume_type['id'], extra_spec.keys()[0], None)
 
     @test.attr(type='gate')
+    @test.idempotent_id('25e5a0ee-89b3-4c53-8310-236f76c75365')
     def test_update_nonexistent_extra_spec_id(self):
         # Should not update volume type extra specs with nonexistent id.
         extra_spec = {"spec1": "val2"}
         self.assertRaises(
-            exceptions.BadRequest,
+            lib_exc.BadRequest,
             self.volume_types_client.update_volume_type_extra_specs,
             self.volume_type['id'], str(uuid.uuid4()),
             extra_spec)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9bf7a657-b011-4aec-866d-81c496fbe5c8')
     def test_update_none_extra_spec_id(self):
         # Should not update volume type extra specs with none id.
         extra_spec = {"spec1": "val2"}
         self.assertRaises(
-            exceptions.BadRequest,
+            lib_exc.BadRequest,
             self.volume_types_client.update_volume_type_extra_specs,
             self.volume_type['id'], None, extra_spec)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a77dfda2-9100-448e-9076-ed1711f4bdfc')
     def test_update_multiple_extra_spec(self):
         # Should not update volume type extra specs with multiple specs as
             # body.
         extra_spec = {"spec1": "val2", 'spec2': 'val1'}
         self.assertRaises(
-            exceptions.BadRequest,
+            lib_exc.BadRequest,
             self.volume_types_client.update_volume_type_extra_specs,
             self.volume_type['id'], extra_spec.keys()[0],
             extra_spec)
 
     @test.attr(type='gate')
+    @test.idempotent_id('49d5472c-a53d-4eab-a4d3-450c4db1c545')
     def test_create_nonexistent_type_id(self):
         # Should not create volume type extra spec for nonexistent volume
             # type id.
         extra_specs = {"spec2": "val1"}
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.volume_types_client.create_volume_type_extra_specs,
             str(uuid.uuid4()), extra_specs)
 
     @test.attr(type='gate')
+    @test.idempotent_id('c821bdc8-43a4-4bf4-86c8-82f3858d5f7d')
     def test_create_none_body(self):
         # Should not create volume type extra spec for none POST body.
         self.assertRaises(
-            exceptions.BadRequest,
+            lib_exc.BadRequest,
             self.volume_types_client.create_volume_type_extra_specs,
             self.volume_type['id'], None)
 
     @test.attr(type='gate')
+    @test.idempotent_id('bc772c71-1ed4-4716-b945-8b5ed0f15e87')
     def test_create_invalid_body(self):
         # Should not create volume type extra spec for invalid POST body.
         self.assertRaises(
-            exceptions.BadRequest,
+            lib_exc.BadRequest,
             self.volume_types_client.create_volume_type_extra_specs,
             self.volume_type['id'], ['invalid'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('031cda8b-7d23-4246-8bf6-bbe73fd67074')
     def test_delete_nonexistent_volume_type_id(self):
         # Should not delete volume type extra spec for nonexistent
             # type id.
         extra_specs = {"spec1": "val1"}
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.volume_types_client.delete_volume_type_extra_specs,
             str(uuid.uuid4()), extra_specs.keys()[0])
 
     @test.attr(type='gate')
+    @test.idempotent_id('dee5cf0c-cdd6-4353-b70c-e847050d71fb')
     def test_list_nonexistent_volume_type_id(self):
         # Should not list volume type extra spec for nonexistent type id.
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.volume_types_client.list_volume_types_extra_specs,
             str(uuid.uuid4()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('9f402cbd-1838-4eb4-9554-126a6b1908c9')
     def test_get_nonexistent_volume_type_id(self):
         # Should not get volume type extra spec for nonexistent type id.
         extra_specs = {"spec1": "val1"}
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.volume_types_client.get_volume_type_extra_specs,
             str(uuid.uuid4()), extra_specs.keys()[0])
 
     @test.attr(type='gate')
+    @test.idempotent_id('c881797d-12ff-4f1a-b09d-9f6212159753')
     def test_get_nonexistent_extra_spec_id(self):
         # Should not get volume type extra spec for nonexistent extra spec
             # id.
         self.assertRaises(
-            exceptions.NotFound,
+            lib_exc.NotFound,
             self.volume_types_client.get_volume_type_extra_specs,
             self.volume_type['id'], str(uuid.uuid4()))
 
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index 4144270..eb46a54 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -15,41 +15,45 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.volume import base
-from tempest import exceptions
 from tempest import test
 
 
 class VolumeTypesNegativeV2Test(base.BaseVolumeAdminTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
+    @test.idempotent_id('b48c98f2-e662-4885-9b71-032256906314')
     def test_create_with_nonexistent_volume_type(self):
         # Should not be able to create volume with nonexistent volume_type.
         self.name_field = self.special_fields['name_field']
         params = {self.name_field: str(uuid.uuid4()),
                   'volume_type': str(uuid.uuid4())}
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.volumes_client.create_volume, size=1,
                           **params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('878b4e57-faa2-4659-b0d1-ce740a06ae81')
     def test_create_with_empty_name(self):
         # Should not be able to create volume type with an empty name.
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.volume_types_client.create_volume_type, '')
 
     @test.attr(type='gate')
+    @test.idempotent_id('994610d6-0476-4018-a644-a2602ef5d4aa')
     def test_get_nonexistent_type_id(self):
         # Should not be able to get volume type with nonexistent type id.
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.volume_types_client.get_volume_type,
                           str(uuid.uuid4()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('6b3926d2-7d73-4896-bc3d-e42dfd11a9f6')
     def test_delete_nonexistent_type_id(self):
         # Should not be able to delete volume type with nonexistent type id.
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.volume_types_client.delete_volume_type,
                           str(uuid.uuid4()))
 
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 4feba73..b0013e6 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -19,12 +19,15 @@
 
 
 class VolumesActionsV2Test(base.BaseVolumeAdminTest):
-    _interface = "json"
+
+    @classmethod
+    def setup_clients(cls):
+        super(VolumesActionsV2Test, cls).setup_clients()
+        cls.client = cls.volumes_client
 
     @classmethod
     def resource_setup(cls):
         super(VolumesActionsV2Test, cls).resource_setup()
-        cls.client = cls.volumes_client
 
         # Create a test shared volume for tests
         vol_name = utils.rand_name(cls.__name__ + '-Volume-')
@@ -73,6 +76,7 @@
         self.client.wait_for_resource_deletion(temp_volume['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d063f96e-a2e0-4f34-8b8a-395c42de1845')
     def test_volume_reset_status(self):
         # test volume reset status : available->error->available
         self._reset_volume_status(self.volume['id'], 'error')
@@ -80,15 +84,18 @@
             self.volume['id'])
         self.assertEqual('error', volume_get['status'])
 
+    @test.idempotent_id('21737d5a-92f2-46d7-b009-a0cc0ee7a570')
     def test_volume_force_delete_when_volume_is_creating(self):
         # test force delete when status of volume is creating
         self._create_reset_and_force_delete_temp_volume('creating')
 
+    @test.idempotent_id('db8d607a-aa2e-4beb-b51d-d4005c232011')
     def test_volume_force_delete_when_volume_is_attaching(self):
         # test force delete when status of volume is attaching
         self._create_reset_and_force_delete_temp_volume('attaching')
 
     @test.attr(type='gate')
+    @test.idempotent_id('3e33a8a8-afd4-4d64-a86b-c27a185c5a4a')
     def test_volume_force_delete_when_volume_is_error(self):
         # test force delete when status of volume is error
         self._create_reset_and_force_delete_temp_volume('error')
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index 0739480..6b0580f 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -24,18 +24,21 @@
 
 
 class VolumesBackupsV2Test(base.BaseVolumeAdminTest):
-    _interface = "json"
+
+    @classmethod
+    def skip_checks(cls):
+        super(VolumesBackupsV2Test, cls).skip_checks()
+        if not CONF.volume_feature_enabled.backup:
+            raise cls.skipException("Cinder backup feature disabled")
 
     @classmethod
     def resource_setup(cls):
         super(VolumesBackupsV2Test, cls).resource_setup()
 
-        if not CONF.volume_feature_enabled.backup:
-            raise cls.skipException("Cinder backup feature disabled")
-
         cls.volume = cls.create_volume()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a66eb488-8ee1-47d4-8e9f-575a095728c6')
     def test_volume_backup_create_get_detailed_list_restore_delete(self):
         # Create backup
         backup_name = data_utils.rand_name('Backup')
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 127a216..c672607 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
@@ -29,31 +31,39 @@
     """Base test case class for all Cinder API tests."""
 
     _api_version = 2
-    _interface = 'json'
 
     @classmethod
-    def resource_setup(cls):
-        cls.set_network_resources()
-        super(BaseVolumeTest, cls).resource_setup()
+    def skip_checks(cls):
+        super(BaseVolumeTest, cls).skip_checks()
 
         if not CONF.service_available.cinder:
             skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
-
-        cls.os = cls.get_client_manager()
-
-        cls.servers_client = cls.os.servers_client
-        cls.image_ref = CONF.compute.image_ref
-        cls.flavor_ref = CONF.compute.flavor_ref
-        cls.build_interval = CONF.volume.build_interval
-        cls.build_timeout = CONF.volume.build_timeout
-        cls.snapshots = []
-        cls.volumes = []
-
         if cls._api_version == 1:
             if not CONF.volume_feature_enabled.api_v1:
                 msg = "Volume API v1 is disabled"
                 raise cls.skipException(msg)
+        elif cls._api_version == 2:
+            if not CONF.volume_feature_enabled.api_v2:
+                msg = "Volume API v2 is disabled"
+                raise cls.skipException(msg)
+        else:
+            msg = ("Invalid Cinder API version (%s)" % cls._api_version)
+            raise exceptions.InvalidConfiguration(message=msg)
+
+    @classmethod
+    def setup_credentials(cls):
+        cls.set_network_resources()
+        super(BaseVolumeTest, cls).setup_credentials()
+        cls.os = cls.get_client_manager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseVolumeTest, cls).setup_clients()
+
+        cls.servers_client = cls.os.servers_client
+
+        if cls._api_version == 1:
             cls.snapshots_client = cls.os.snapshots_client
             cls.volumes_client = cls.os.volumes_client
             cls.backups_client = cls.os.backups_client
@@ -61,27 +71,33 @@
             cls.volumes_extension_client = cls.os.volumes_extension_client
             cls.availability_zone_client = (
                 cls.os.volume_availability_zone_client)
-            # Special fields and resp code for cinder v1
-            cls.special_fields = {'name_field': 'display_name',
-                                  'descrip_field': 'display_description'}
-
-        elif cls._api_version == 2:
-            if not CONF.volume_feature_enabled.api_v2:
-                msg = "Volume API v2 is disabled"
-                raise cls.skipException(msg)
+        else:
             cls.snapshots_client = cls.os.snapshots_v2_client
             cls.volumes_client = cls.os.volumes_v2_client
             cls.volumes_extension_client = cls.os.volumes_v2_extension_client
             cls.availability_zone_client = (
                 cls.os.volume_v2_availability_zone_client)
+
+    @classmethod
+    def resource_setup(cls):
+        super(BaseVolumeTest, cls).resource_setup()
+
+        cls.snapshots = []
+        cls.volumes = []
+        cls.image_ref = CONF.compute.image_ref
+        cls.flavor_ref = CONF.compute.flavor_ref
+        cls.build_interval = CONF.volume.build_interval
+        cls.build_timeout = CONF.volume.build_timeout
+
+        if cls._api_version == 1:
+            # Special fields and resp code for cinder v1
+            cls.special_fields = {'name_field': 'display_name',
+                                  'descrip_field': 'display_description'}
+        else:
             # Special fields and resp code for cinder v2
             cls.special_fields = {'name_field': 'name',
                                   'descrip_field': 'description'}
 
-        else:
-            msg = ("Invalid Cinder API version (%s)" % cls._api_version)
-            raise exceptions.InvalidConfiguration(message=msg)
-
     @classmethod
     def resource_cleanup(cls):
         cls.clear_snapshots()
@@ -147,24 +163,22 @@
 
 class BaseVolumeAdminTest(BaseVolumeTest):
     """Base test case class for all Volume Admin API tests."""
-    @classmethod
-    def resource_setup(cls):
-        super(BaseVolumeAdminTest, cls).resource_setup()
 
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseVolumeAdminTest, cls).setup_credentials()
         try:
             cls.adm_creds = cls.isolated_creds.get_admin_creds()
-            cls.os_adm = clients.Manager(
-                credentials=cls.adm_creds, interface=cls._interface)
+            cls.os_adm = clients.Manager(credentials=cls.adm_creds)
         except NotImplementedError:
             msg = "Missing Volume Admin API credentials in configuration."
             raise cls.skipException(msg)
 
-        cls.qos_specs = []
+    @classmethod
+    def setup_clients(cls):
+        super(BaseVolumeAdminTest, cls).setup_clients()
 
         if cls._api_version == 1:
-            if not CONF.volume_feature_enabled.api_v1:
-                msg = "Volume API v1 is disabled"
-                raise cls.skipException(msg)
             cls.volume_qos_client = cls.os_adm.volume_qos_client
             cls.admin_volume_services_client = \
                 cls.os_adm.volume_services_client
@@ -175,9 +189,6 @@
             cls.backups_adm_client = cls.os_adm.backups_client
             cls.quotas_client = cls.os_adm.volume_quotas_client
         elif cls._api_version == 2:
-            if not CONF.volume_feature_enabled.api_v2:
-                msg = "Volume API v2 is disabled"
-                raise cls.skipException(msg)
             cls.volume_qos_client = cls.os_adm.volume_qos_v2_client
             cls.admin_volume_services_client = \
                 cls.os_adm.volume_services_v2_client
@@ -189,6 +200,12 @@
             cls.quotas_client = cls.os_adm.volume_quotas_v2_client
 
     @classmethod
+    def resource_setup(cls):
+        super(BaseVolumeAdminTest, cls).resource_setup()
+
+        cls.qos_specs = []
+
+    @classmethod
     def resource_cleanup(cls):
         cls.clear_qos_specs()
         super(BaseVolumeAdminTest, cls).resource_cleanup()
@@ -208,13 +225,13 @@
         for qos_id in cls.qos_specs:
             try:
                 cls.volume_qos_client.delete_qos(qos_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 # The qos_specs may have already been deleted which is OK.
                 pass
 
         for qos_id in cls.qos_specs:
             try:
                 cls.volume_qos_client.wait_for_resource_deletion(qos_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 # The qos_specs may have already been deleted which is OK.
                 pass
diff --git a/tempest/api/volume/test_availability_zone.py b/tempest/api/volume/test_availability_zone.py
index bd3d2a1..e63cfcd 100644
--- a/tempest/api/volume/test_availability_zone.py
+++ b/tempest/api/volume/test_availability_zone.py
@@ -24,11 +24,12 @@
     """
 
     @classmethod
-    def resource_setup(cls):
-        super(AvailabilityZoneV2TestJSON, cls).resource_setup()
+    def setup_clients(cls):
+        super(AvailabilityZoneV2TestJSON, cls).setup_clients()
         cls.client = cls.availability_zone_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('01f1ae88-eba9-4c6b-a011-6f7ace06b725')
     def test_get_availability_zone_list(self):
         # List of availability zone
         availability_zone = self.client.get_availability_zone_list()
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
index dbbdea4..e5fe3c8 100644
--- a/tempest/api/volume/test_extensions.py
+++ b/tempest/api/volume/test_extensions.py
@@ -28,6 +28,7 @@
 class ExtensionsV2TestJSON(base.BaseVolumeTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('94607eb0-43a5-47ca-82aa-736b41bd2e2c')
     def test_list_extensions(self):
         # List of all extensions
         extensions = self.volumes_extension_client.list_extensions()
diff --git a/tempest/api/volume/test_qos.py b/tempest/api/volume/test_qos.py
index 60c327b..b08a019 100644
--- a/tempest/api/volume/test_qos.py
+++ b/tempest/api/volume/test_qos.py
@@ -72,6 +72,7 @@
 
         return associations
 
+    @test.idempotent_id('7e15f883-4bef-49a9-95eb-f94209a1ced1')
     def test_create_delete_qos_with_front_end_consumer(self):
         """Tests the creation and deletion of QoS specs
 
@@ -79,6 +80,7 @@
         """
         self._create_delete_test_qos_with_given_consumer('front-end')
 
+    @test.idempotent_id('b115cded-8f58-4ee4-aab5-9192cfada08f')
     def test_create_delete_qos_with_back_end_consumer(self):
         """Tests the creation and deletion of QoS specs
 
@@ -87,6 +89,7 @@
         self._create_delete_test_qos_with_given_consumer('back-end')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f88d65eb-ea0d-487d-af8d-71f4011575a4')
     def test_create_delete_qos_with_both_consumer(self):
         """Tests the creation and deletion of QoS specs
 
@@ -95,6 +98,7 @@
         self._create_delete_test_qos_with_given_consumer('both')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7aa214cc-ac1a-4397-931f-3bb2e83bb0fd')
     def test_get_qos(self):
         """Tests the detail of a given qos-specs"""
         body = self.volume_qos_client.get_qos(self.created_qos['id'])
@@ -102,12 +106,14 @@
         self.assertEqual(self.qos_consumer, body['consumer'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('75e04226-bcf7-4595-a34b-fdf0736f38fc')
     def test_list_qos(self):
         """Tests the list of all qos-specs"""
         body = self.volume_qos_client.list_qos()
         self.assertIn(self.created_qos, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ed00fd85-4494-45f2-8ceb-9e2048919aed')
     def test_set_unset_qos_key(self):
         """Test the addition of a specs key to qos-specs"""
         args = {'iops_bytes': '500'}
@@ -127,6 +133,7 @@
         self.assertNotIn(keys[0], body['specs'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1dd93c76-6420-485d-a771-874044c416ac')
     def test_associate_disassociate_qos(self):
         """Test the following operations :
 
diff --git a/tempest/api/volume/test_snapshot_metadata.py b/tempest/api/volume/test_snapshot_metadata.py
index 03474ba..d4efc2a 100644
--- a/tempest/api/volume/test_snapshot_metadata.py
+++ b/tempest/api/volume/test_snapshot_metadata.py
@@ -20,9 +20,13 @@
 class SnapshotV2MetadataTestJSON(base.BaseVolumeTest):
 
     @classmethod
+    def setup_clients(cls):
+        super(SnapshotV2MetadataTestJSON, cls).setup_clients()
+        cls.client = cls.snapshots_client
+
+    @classmethod
     def resource_setup(cls):
         super(SnapshotV2MetadataTestJSON, cls).resource_setup()
-        cls.client = cls.snapshots_client
         # Create a volume
         cls.volume = cls.create_volume()
         # Create a snapshot
@@ -35,6 +39,7 @@
         super(SnapshotV2MetadataTestJSON, self).tearDown()
 
     @test.attr(type='gate')
+    @test.idempotent_id('a2f20f99-e363-4584-be97-bc33afb1a56c')
     def test_create_get_delete_snapshot_metadata(self):
         # Create metadata for the snapshot
         metadata = {"key1": "value1",
@@ -54,6 +59,7 @@
         self.assertEqual(expected, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('bd2363bc-de92-48a4-bc98-28943c6e4be1')
     def test_update_snapshot_metadata(self):
         # Update metadata for the snapshot
         metadata = {"key1": "value1",
@@ -75,6 +81,7 @@
         self.assertEqual(update, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e8ff85c5-8f97-477f-806a-3ac364a949ed')
     def test_update_snapshot_metadata_item(self):
         # Update metadata item for the snapshot
         metadata = {"key1": "value1",
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index 4739fd2..e601349 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -34,6 +34,7 @@
         super(VolumesV2MetadataTest, self).tearDown()
 
     @test.attr(type='gate')
+    @test.idempotent_id('6f5b125b-f664-44bf-910f-751591fe5769')
     def test_create_get_delete_volume_metadata(self):
         # Create metadata for the volume
         metadata = {"key1": "value1",
@@ -55,6 +56,7 @@
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('774d2918-9beb-4f30-b3d1-2a4e8179ec0a')
     def test_update_volume_metadata(self):
         # Update metadata for the volume
         metadata = {"key1": "value1",
@@ -78,6 +80,7 @@
         self.assertThat(body.items(), matchers.ContainsAll(update.items()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('862261c5-8df4-475a-8c21-946e50e36a20')
     def test_update_volume_metadata_item(self):
         # Update metadata item for the volume
         metadata = {"key1": "value1",
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index b2961bd..40947df 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -17,6 +17,7 @@
 
 from tempest.api.volume import base
 from tempest import clients
+from tempest.common import credentials
 from tempest import config
 from tempest import test
 
@@ -26,21 +27,25 @@
 class VolumesV2TransfersTest(base.BaseVolumeTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(VolumesV2TransfersTest, cls).resource_setup()
-
-        # Add another tenant to test volume-transfer
-        cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds(),
-                                     interface=cls._interface)
-        # Add admin tenant to cleanup resources
-        try:
-            creds = cls.isolated_creds.get_admin_creds()
-            cls.os_adm = clients.Manager(
-                credentials=creds, interface=cls._interface)
-        except NotImplementedError:
+    def skip_checks(cls):
+        super(VolumesV2TransfersTest, cls).skip_checks()
+        if not credentials.is_admin_available():
             msg = "Missing Volume Admin API credentials in configuration."
             raise cls.skipException(msg)
 
+    @classmethod
+    def setup_credentials(cls):
+        super(VolumesV2TransfersTest, cls).setup_credentials()
+        # Add another tenant to test volume-transfer
+        cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
+        # Add admin tenant to cleanup resources
+        creds = cls.isolated_creds.get_admin_creds()
+        cls.os_adm = clients.Manager(credentials=creds)
+
+    @classmethod
+    def setup_clients(cls):
+        super(VolumesV2TransfersTest, cls).setup_clients()
+
         cls.client = cls.volumes_client
         cls.alt_client = cls.os_alt.volumes_client
         cls.alt_tenant_id = cls.alt_client.tenant_id
@@ -52,6 +57,7 @@
         self.adm_client.wait_for_resource_deletion(volume_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4d75b645-a478-48b1-97c8-503f64242f1a')
     def test_create_get_list_accept_volume_transfer(self):
         # Create a volume first
         volume = self.create_volume()
@@ -78,6 +84,7 @@
                                                       auth_key)
         self.alt_client.wait_for_volume_status(volume['id'], 'available')
 
+    @test.idempotent_id('ab526943-b725-4c07-b875-8e8ef87a2c30')
     def test_create_list_delete_volume_transfer(self):
         # Create a volume first
         volume = self.create_volume()
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index ceabb1c..5cad6b4 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -24,20 +24,25 @@
 class VolumesV2ActionsTest(base.BaseVolumeTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(VolumesV2ActionsTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(VolumesV2ActionsTest, cls).setup_clients()
         cls.client = cls.volumes_client
         cls.image_client = cls.os.image_client
 
+    @classmethod
+    def resource_setup(cls):
+        super(VolumesV2ActionsTest, cls).resource_setup()
+
         # Create a test shared instance
         srv_name = data_utils.rand_name(cls.__name__ + '-Instance-')
-        resp, cls.server = cls.servers_client.create_server(srv_name,
-                                                            cls.image_ref,
-                                                            cls.flavor_ref)
+        cls.server = cls.servers_client.create_server(srv_name,
+                                                      cls.image_ref,
+                                                      cls.flavor_ref)
         cls.servers_client.wait_for_server_status(cls.server['id'], 'ACTIVE')
 
         # Create a test shared volume for attach/detach tests
         cls.volume = cls.create_volume()
+        cls.client.wait_for_volume_status(cls.volume['id'], 'available')
 
     def _delete_image_with_wait(self, image_id):
         self.image_client.delete_image(image_id)
@@ -51,6 +56,7 @@
 
         super(VolumesV2ActionsTest, cls).resource_cleanup()
 
+    @test.idempotent_id('fff42874-7db5-4487-a8e1-ddda5fb5288d')
     @test.stresstest(class_setup_per='process')
     @test.attr(type='smoke')
     @test.services('compute')
@@ -64,6 +70,7 @@
         self.client.detach_volume(self.volume['id'])
         self.client.wait_for_volume_status(self.volume['id'], 'available')
 
+    @test.idempotent_id('9516a2c8-9135-488c-8dd6-5677a7e5f371')
     @test.stresstest(class_setup_per='process')
     @test.attr(type='gate')
     @test.services('compute')
@@ -89,6 +96,7 @@
         self.assertEqual(self.volume['id'], attachment['volume_id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d8f1ca95-3d5b-44a3-b8ca-909691c9532d')
     @test.services('image')
     def test_volume_upload(self):
         # NOTE(gfidente): the volume uploaded in Glance comes from setUpClass,
@@ -105,6 +113,7 @@
         self.client.wait_for_volume_status(self.volume['id'], 'available')
 
     @test.attr(type='gate')
+    @test.idempotent_id('92c4ef64-51b2-40c0-9f7e-4749fbaaba33')
     def test_reserve_unreserve_volume(self):
         # Mark volume as reserved.
         body = self.client.reserve_volume(self.volume['id'])
@@ -121,6 +130,7 @@
         return val in ['true', 'True', True]
 
     @test.attr(type='gate')
+    @test.idempotent_id('fff74e1e-5bd3-4b33-9ea9-24c103bc3f59')
     def test_volume_readonly_update(self):
         # Update volume readonly true
         readonly = True
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index ebe6084..35c12bc 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -23,11 +23,12 @@
 class VolumesV2ExtendTest(base.BaseVolumeTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(VolumesV2ExtendTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(VolumesV2ExtendTest, cls).setup_clients()
         cls.client = cls.volumes_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('9a36df71-a257-43a5-9555-dc7c88e66e0e')
     def test_volume_extend(self):
         # Extend Volume Test.
         self.volume = self.create_volume()
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 6d9c438..007b0db 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -26,9 +26,13 @@
 class VolumesV2GetTest(base.BaseVolumeTest):
 
     @classmethod
+    def setup_clients(cls):
+        super(VolumesV2GetTest, cls).setup_clients()
+        cls.client = cls.volumes_client
+
+    @classmethod
     def resource_setup(cls):
         super(VolumesV2GetTest, cls).resource_setup()
-        cls.client = cls.volumes_client
 
         cls.name_field = cls.special_fields['name_field']
         cls.descrip_field = cls.special_fields['descrip_field']
@@ -37,15 +41,6 @@
         self.client.delete_volume(volume_id)
         self.client.wait_for_resource_deletion(volume_id)
 
-    def _is_true(self, val):
-        # NOTE(jdg): Temporary conversion method to get cinder patch
-        # merged.  Then we'll make this strict again and
-        # specifically check "true" or "false"
-        if val in ['true', 'True', True]:
-            return True
-        else:
-            return False
-
     def _volume_create_get_update_delete(self, **kwargs):
         # Create a volume, Get it's details and Delete the volume
         volume = {}
@@ -79,13 +74,10 @@
                         'The fetched Volume metadata misses data '
                         'from the created Volume')
 
-        # NOTE(jdg): Revert back to strict true/false checking
-        # after fix for bug #1227837 merges
-        boot_flag = self._is_true(fetched_volume['bootable'])
         if 'imageRef' in kwargs:
-            self.assertEqual(boot_flag, True)
+            self.assertEqual('true', fetched_volume['bootable'])
         if 'imageRef' not in kwargs:
-            self.assertEqual(boot_flag, False)
+            self.assertEqual('false', fetched_volume['bootable'])
 
         # Update Volume
         # Test volume update when display_name is same with original value
@@ -125,24 +117,24 @@
                   self.descrip_field: volume[self.descrip_field]}
         self.client.update_volume(new_volume['id'], **params)
 
-        # NOTE(jdg): Revert back to strict true/false checking
-        # after fix for bug #1227837 merges
-        boot_flag = self._is_true(updated_volume['bootable'])
         if 'imageRef' in kwargs:
-            self.assertEqual(boot_flag, True)
+            self.assertEqual('true', updated_volume['bootable'])
         if 'imageRef' not in kwargs:
-            self.assertEqual(boot_flag, False)
+            self.assertEqual('false', updated_volume['bootable'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51')
     def test_volume_create_get_update_delete(self):
         self._volume_create_get_update_delete()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('54a01030-c7fc-447c-86ee-c1182beae638')
     @test.services('image')
     def test_volume_create_get_update_delete_from_image(self):
         self._volume_create_get_update_delete(imageRef=CONF.compute.image_ref)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3f591b4a-7dc6-444c-bd51-77469506b3a1')
     def test_volume_create_get_update_delete_as_clone(self):
         origin = self.create_volume()
         self._volume_create_get_update_delete(source_volid=origin['id'])
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 91beae9..ef7cebb 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -55,9 +55,13 @@
                              [str_vol(v) for v in fetched_list]))
 
     @classmethod
+    def setup_clients(cls):
+        super(VolumesV2ListTestJSON, cls).setup_clients()
+        cls.client = cls.volumes_client
+
+    @classmethod
     def resource_setup(cls):
         super(VolumesV2ListTestJSON, cls).resource_setup()
-        cls.client = cls.volumes_client
         cls.name = cls.VOLUME_FIELDS[1]
 
         # Create 3 test volumes
@@ -108,6 +112,7 @@
                         self.assertEqual(params[key], volume[key], msg)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0b6ddd39-b948-471f-8038-4787978747c4')
     def test_volume_list(self):
         # Get a list of Volumes
         # Fetch all volumes
@@ -116,6 +121,7 @@
                              fields=self.VOLUME_FIELDS)
 
     @test.attr(type='gate')
+    @test.idempotent_id('adcbb5a7-5ad8-4b61-bd10-5380e111a877')
     def test_volume_list_with_details(self):
         # Get a list of Volumes with details
         # Fetch all Volumes
@@ -123,6 +129,7 @@
         self.assertVolumesIn(fetched_list, self.volume_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a28e8da4-0b56-472f-87a8-0f4d3f819c02')
     def test_volume_list_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {self.name: volume[self.name]}
@@ -132,6 +139,7 @@
                          volume[self.name])
 
     @test.attr(type='gate')
+    @test.idempotent_id('2de3a6d4-12aa-403b-a8f2-fdeb42a89623')
     def test_volume_list_details_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {self.name: volume[self.name]}
@@ -141,6 +149,7 @@
                          volume[self.name])
 
     @test.attr(type='gate')
+    @test.idempotent_id('39654e13-734c-4dab-95ce-7613bf8407ce')
     def test_volumes_list_by_status(self):
         params = {'status': 'available'}
         fetched_list = self.client.list_volumes(params)
@@ -149,6 +158,7 @@
                              fields=self.VOLUME_FIELDS)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2943f712-71ec-482a-bf49-d5ca06216b9f')
     def test_volumes_list_details_by_status(self):
         params = {'status': 'available'}
         fetched_list = self.client.list_volumes_with_detail(params)
@@ -157,6 +167,7 @@
         self.assertVolumesIn(fetched_list, self.volume_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('c0cfa863-3020-40d7-b587-e35f597d5d87')
     def test_volumes_list_by_availability_zone(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
@@ -167,6 +178,7 @@
                              fields=self.VOLUME_FIELDS)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e1b80d13-94f0-4ba2-a40e-386af29f8db1')
     def test_volumes_list_details_by_availability_zone(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
@@ -177,18 +189,21 @@
         self.assertVolumesIn(fetched_list, self.volume_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('b5ebea1b-0603-40a0-bb41-15fcd0a53214')
     def test_volume_list_with_param_metadata(self):
         # Test to list volumes when metadata param is given
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d')
     def test_volume_list_with_detail_param_metadata(self):
         # Test to list volumes details when metadata param is given
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
     @test.attr(type='gate')
+    @test.idempotent_id('777c87c1-2fc4-4883-8b8e-5c0b951d1ec8')
     def test_volume_list_param_display_name_and_status(self):
         # Test to list volume when display name and status param is given
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
@@ -197,6 +212,7 @@
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('856ab8ca-6009-4c37-b691-be1065528ad4')
     def test_volume_list_with_detail_param_display_name_and_status(self):
         # Test to list volume when name and status param is given
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index dc8d8e2..27fd495 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -15,18 +15,23 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class VolumesV2NegativeTest(base.BaseVolumeTest):
 
     @classmethod
+    def setup_clients(cls):
+        super(VolumesV2NegativeTest, cls).setup_clients()
+        cls.client = cls.volumes_client
+
+    @classmethod
     def resource_setup(cls):
         super(VolumesV2NegativeTest, cls).resource_setup()
-        cls.client = cls.volumes_client
 
         cls.name_field = cls.special_fields['name_field']
 
@@ -35,204 +40,231 @@
         cls.mountpoint = "/dev/vdc"
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f131c586-9448-44a4-a8b0-54ca838aa43e')
     def test_volume_get_nonexistent_volume_id(self):
         # Should not be able to get a non-existent volume
-        self.assertRaises(exceptions.NotFound, self.client.get_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.get_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('555efa6e-efcd-44ef-8a3b-4a7ca4837a29')
     def test_volume_delete_nonexistent_volume_id(self):
         # Should not be able to delete a non-existent Volume
-        self.assertRaises(exceptions.NotFound, self.client.delete_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1ed83a8a-682d-4dfb-a30e-ee63ffd6c049')
     def test_create_volume_with_invalid_size(self):
         # Should not be able to create volume with invalid size
         # in request
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_volume,
                           size='#$%', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9387686f-334f-4d31-a439-33494b9e2683')
     def test_create_volume_with_out_passing_size(self):
         # Should not be able to create volume without passing size
         # in request
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_volume,
                           size='', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('41331caa-eaf4-4001-869d-bc18c1869360')
     def test_create_volume_with_size_zero(self):
         # Should not be able to create volume with size zero
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_volume,
                           size='0', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8b472729-9eba-446e-a83b-916bdb34bef7')
     def test_create_volume_with_size_negative(self):
         # Should not be able to create volume with size negative
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.create_volume,
                           size='-1', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('10254ed8-3849-454e-862e-3ab8e6aa01d2')
     def test_create_volume_with_nonexistent_volume_type(self):
         # Should not be able to create volume with non-existent volume type
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.NotFound, self.client.create_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.create_volume,
                           size='1', volume_type=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0c36f6ae-4604-4017-b0a9-34fdc63096f9')
     def test_create_volume_with_nonexistent_snapshot_id(self):
         # Should not be able to create volume with non-existent snapshot
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.NotFound, self.client.create_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.create_volume,
                           size='1', snapshot_id=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('47c73e08-4be8-45bb-bfdf-0c4e79b88344')
     def test_create_volume_with_nonexistent_source_volid(self):
         # Should not be able to create volume with non-existent source volume
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.NotFound, self.client.create_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.create_volume,
                           size='1', source_volid=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0186422c-999a-480e-a026-6a665744c30c')
     def test_update_volume_with_nonexistent_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.update_volume,
                           volume_id=str(uuid.uuid4()), display_name=v_name,
                           metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e66e40d6-65e6-4e75-bdc7-636792fa152d')
     def test_update_volume_with_invalid_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.update_volume,
                           volume_id='#$%%&^&^', display_name=v_name,
                           metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('72aeca85-57a5-4c1f-9057-f320f9ea575b')
     def test_update_volume_with_empty_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
-        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.update_volume,
                           volume_id='', display_name=v_name,
                           metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('30799cfd-7ee4-446c-b66c-45b383ed211b')
     def test_get_invalid_volume_id(self):
         # Should not be able to get volume with invalid id
-        self.assertRaises(exceptions.NotFound, self.client.get_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.get_volume,
                           '#$%%&^&^')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c6c3db06-29ad-4e91-beb0-2ab195fe49e3')
     def test_get_volume_without_passing_volume_id(self):
         # Should not be able to get volume when empty ID is passed
-        self.assertRaises(exceptions.NotFound, self.client.get_volume, '')
+        self.assertRaises(lib_exc.NotFound, self.client.get_volume, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1f035827-7c32-4019-9240-b4ec2dbd9dfd')
     def test_delete_invalid_volume_id(self):
         # Should not be able to delete volume when invalid ID is passed
-        self.assertRaises(exceptions.NotFound, self.client.delete_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.delete_volume,
                           '!@#$%^&*()')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('441a1550-5d44-4b30-af0f-a6d402f52026')
     def test_delete_volume_without_passing_volume_id(self):
         # Should not be able to delete volume when empty ID is passed
-        self.assertRaises(exceptions.NotFound, self.client.delete_volume, '')
+        self.assertRaises(lib_exc.NotFound, self.client.delete_volume, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f5e56b0a-5d02-43c1-a2a7-c9b792c2e3f6')
     @test.services('compute')
     def test_attach_volumes_with_nonexistent_volume_id(self):
         srv_name = data_utils.rand_name('Instance-')
-        resp, server = self.servers_client.create_server(srv_name,
-                                                         self.image_ref,
-                                                         self.flavor_ref)
+        server = self.servers_client.create_server(srv_name,
+                                                   self.image_ref,
+                                                   self.flavor_ref)
         self.addCleanup(self.servers_client.delete_server, server['id'])
         self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.attach_volume,
                           str(uuid.uuid4()),
                           server['id'],
                           self.mountpoint)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9f9c24e4-011d-46b5-b992-952140ce237a')
     def test_detach_volumes_with_invalid_volume_id(self):
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.detach_volume,
                           'xxx')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e0c75c74-ee34-41a9-9288-2a2051452854')
     def test_volume_extend_with_size_smaller_than_original_size(self):
         # Extend volume with smaller size than original size.
         extend_size = 0
-        self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5d0b480d-e833-439f-8a5a-96ad2ed6f22f')
     def test_volume_extend_with_non_number_size(self):
         # Extend volume when size is non number.
         extend_size = 'abc'
-        self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('355218f1-8991-400a-a6bb-971239287d92')
     def test_volume_extend_with_None_size(self):
         # Extend volume with None size.
         extend_size = None
-        self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
+        self.assertRaises(lib_exc.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8f05a943-013c-4063-ac71-7baf561e82eb')
     def test_volume_extend_with_nonexistent_volume_id(self):
         # Extend volume size when volume is nonexistent.
         extend_size = int(self.volume['size']) + 1
-        self.assertRaises(exceptions.NotFound, self.client.extend_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.extend_volume,
                           str(uuid.uuid4()), extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('aff8ba64-6d6f-4f2e-bc33-41a08ee9f115')
     def test_volume_extend_without_passing_volume_id(self):
         # Extend volume size when passing volume id is None.
         extend_size = int(self.volume['size']) + 1
-        self.assertRaises(exceptions.NotFound, self.client.extend_volume,
+        self.assertRaises(lib_exc.NotFound, self.client.extend_volume,
                           None, extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ac6084c0-0546-45f9-b284-38a367e0e0e2')
     def test_reserve_volume_with_nonexistent_volume_id(self):
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.reserve_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('eb467654-3dc1-4a72-9b46-47c29d22654c')
     def test_unreserve_volume_with_nonexistent_volume_id(self):
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.client.unreserve_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('449c4ed2-ecdd-47bb-98dc-072aeccf158c')
     def test_reserve_volume_with_negative_volume_status(self):
         # Mark volume as reserved.
         self.client.reserve_volume(self.volume['id'])
         # Mark volume which is marked as reserved before
-        self.assertRaises(exceptions.BadRequest,
+        self.assertRaises(lib_exc.BadRequest,
                           self.client.reserve_volume,
                           self.volume['id'])
         # Unmark volume as reserved.
         self.client.unreserve_volume(self.volume['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f')
     def test_list_volumes_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {self.name_field: v_name}
@@ -240,6 +272,7 @@
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9ca17820-a0e7-4cbd-a7fa-f4468735e359')
     def test_list_volumes_detail_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {self.name_field: v_name}
@@ -248,12 +281,14 @@
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('143b279b-7522-466b-81be-34a87d564a7c')
     def test_list_volumes_with_invalid_status(self):
         params = {'status': 'null'}
         fetched_volume = self.client.list_volumes(params)
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ba94b27b-be3f-496c-a00e-0283b373fa75')
     def test_list_volumes_detail_with_invalid_status(self):
         params = {'status': 'null'}
         fetched_volume = \
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 179eb09..3c1cce3 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -23,13 +23,16 @@
 class VolumesV2SnapshotTestJSON(base.BaseVolumeTest):
 
     @classmethod
+    def skip_checks(cls):
+        super(VolumesV2SnapshotTestJSON, cls).skip_checks()
+        if not CONF.volume_feature_enabled.snapshot:
+            raise cls.skipException("Cinder volume snapshots are disabled")
+
+    @classmethod
     def resource_setup(cls):
         super(VolumesV2SnapshotTestJSON, cls).resource_setup()
         cls.volume_origin = cls.create_volume()
 
-        if not CONF.volume_feature_enabled.snapshot:
-            raise cls.skipException("Cinder volume snapshots are disabled")
-
         cls.name_field = cls.special_fields['name_field']
         cls.descrip_field = cls.special_fields['descrip_field']
 
@@ -59,18 +62,19 @@
                 self.assertEqual(params[key], snap[key], msg)
 
     @test.attr(type='gate')
+    @test.idempotent_id('b467b54c-07a4-446d-a1cf-651dedcc3ff1')
     @test.services('compute')
     def test_snapshot_create_with_volume_in_use(self):
         # Create a snapshot when volume status is in-use
         # Create a test instance
         server_name = data_utils.rand_name('instance-')
-        resp, server = self.servers_client.create_server(server_name,
-                                                         self.image_ref,
-                                                         self.flavor_ref)
+        server = self.servers_client.create_server(server_name,
+                                                   self.image_ref,
+                                                   self.flavor_ref)
         self.addCleanup(self.servers_client.delete_server, server['id'])
         self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
         mountpoint = '/dev/%s' % CONF.compute.volume_device_name
-        _, body = self.servers_client.attach_volume(
+        self.servers_client.attach_volume(
             server['id'], self.volume_origin['id'], mountpoint)
         self.volumes_client.wait_for_volume_status(self.volume_origin['id'],
                                                    'in-use')
@@ -87,6 +91,7 @@
         self.snapshots.remove(snapshot)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2a8abbe4-d871-46db-b049-c41f5af8216e')
     def test_snapshot_create_get_list_update_delete(self):
         # Create a snapshot
         s_name = data_utils.rand_name('snap')
@@ -127,6 +132,7 @@
         self.snapshots.remove(snapshot)
 
     @test.attr(type='gate')
+    @test.idempotent_id('59f41f43-aebf-48a9-ab5d-d76340fab32b')
     def test_snapshots_list_with_params(self):
         """list snapshots with params."""
         # Create a snapshot
@@ -148,6 +154,7 @@
         self._list_by_param_values_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('220a1022-1fcd-4a74-a7bd-6b859156cda2')
     def test_snapshots_list_details_with_params(self):
         """list snapshot details with params."""
         # Create a snapshot
@@ -167,6 +174,7 @@
         self._list_by_param_values_and_assert(params, with_detail=True)
 
     @test.attr(type='gate')
+    @test.idempotent_id('677863d1-3142-456d-b6ac-9924f667a7f4')
     def test_volume_from_snapshot(self):
         # Create a temporary snap using wrapper method from base, then
         # create a snap based volume and deletes it
diff --git a/tempest/api/volume/test_volumes_snapshots_negative.py b/tempest/api/volume/test_volumes_snapshots_negative.py
index 2d7b6de..fbbc623 100644
--- a/tempest/api/volume/test_volumes_snapshots_negative.py
+++ b/tempest/api/volume/test_volumes_snapshots_negative.py
@@ -12,10 +12,11 @@
 
 import uuid
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -24,25 +25,26 @@
 class VolumesV2SnapshotNegativeTestJSON(base.BaseVolumeTest):
 
     @classmethod
-    def resource_setup(cls):
-        super(VolumesV2SnapshotNegativeTestJSON, cls).resource_setup()
-
+    def skip_checks(cls):
+        super(VolumesV2SnapshotNegativeTestJSON, cls).skip_checks()
         if not CONF.volume_feature_enabled.snapshot:
             raise cls.skipException("Cinder volume snapshots are disabled")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e3e466af-70ab-4f4b-a967-ab04e3532ea7')
     def test_create_snapshot_with_nonexistent_volume_id(self):
         # Create a snapshot with nonexistent volume id
         s_name = data_utils.rand_name('snap')
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.snapshots_client.create_snapshot,
                           str(uuid.uuid4()), display_name=s_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bb9da53e-d335-4309-9c15-7e76fd5e4d6d')
     def test_create_snapshot_without_passing_volume_id(self):
         # Create a snapshot without passing volume id
         s_name = data_utils.rand_name('snap')
-        self.assertRaises(exceptions.NotFound,
+        self.assertRaises(lib_exc.NotFound,
                           self.snapshots_client.create_snapshot,
                           None, display_name=s_name)
 
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index bc14b2c..f6b52a9 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -31,9 +31,13 @@
     """
 
     @classmethod
+    def setup_clients(cls):
+        super(VolumesV2ListTestJSON, cls).setup_clients()
+        cls.client = cls.volumes_client
+
+    @classmethod
     def resource_setup(cls):
         super(VolumesV2ListTestJSON, cls).resource_setup()
-        cls.client = cls.volumes_client
 
         # Create 3 test volumes
         cls.volume_list = []
@@ -54,6 +58,7 @@
         super(VolumesV2ListTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('2a7064eb-b9c3-429b-b888-33928fc5edd3')
     def test_volume_list_details_with_multiple_params(self):
         # List volumes detail using combined condition
         def _list_details_with_multiple_params(limit=2,
diff --git a/tempest/api_schema/response/compute/aggregates.py b/tempest/api_schema/response/compute/aggregates.py
index 9393a16..fc20885 100644
--- a/tempest/api_schema/response/compute/aggregates.py
+++ b/tempest/api_schema/response/compute/aggregates.py
@@ -14,6 +14,29 @@
 
 import copy
 
+# create-aggregate api doesn't have 'hosts' and 'metadata' attributes.
+aggregate_for_create = {
+    'type': 'object',
+    'properties': {
+        'availability_zone': {'type': ['string', 'null']},
+        'created_at': {'type': 'string'},
+        'deleted': {'type': 'boolean'},
+        'deleted_at': {'type': ['string', 'null']},
+        'id': {'type': 'integer'},
+        'name': {'type': 'string'},
+        'updated_at': {'type': ['string', 'null']}
+    },
+    'required': ['availability_zone', 'created_at', 'deleted',
+                 'deleted_at', 'id', 'name', 'updated_at']
+}
+
+aggregate = copy.deepcopy(aggregate_for_create)
+aggregate['properties'].update({
+    'hosts': {'type': 'array'},
+    'metadata': {'type': 'object'}
+})
+aggregate['required'].extend(['hosts', 'metadata'])
+
 aggregate = {
     'type': 'object',
     'properties': {
@@ -69,18 +92,10 @@
     'response_body': {
         'type': 'object',
         'properties': {
-            'aggregate': aggregate
+            'aggregate': aggregate_for_create
         },
         'required': ['aggregate']
     }
 }
-# create-aggregate api doesn't have 'hosts' and 'metadata' attributes.
-del common_create_aggregate['response_body']['properties']['aggregate'][
-    'properties']['hosts']
-del common_create_aggregate['response_body']['properties']['aggregate'][
-    'properties']['metadata']
-common_create_aggregate['response_body']['properties']['aggregate'][
-    'required'] = ['availability_zone', 'created_at', 'deleted', 'deleted_at',
-                   'id', 'name', 'updated_at']
 
 aggregate_add_remove_host = get_aggregate
diff --git a/tempest/api_schema/response/compute/baremetal_nodes.py b/tempest/api_schema/response/compute/baremetal_nodes.py
new file mode 100644
index 0000000..e82792c
--- /dev/null
+++ b/tempest/api_schema/response/compute/baremetal_nodes.py
@@ -0,0 +1,53 @@
+# Copyright 2015 NEC Corporation.  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.
+
+node = {
+    'type': 'object',
+    'properties': {
+        'id': {'type': 'string'},
+        'interfaces': {'type': 'array'},
+        'host': {'type': 'string'},
+        'task_state': {'type': ['string', 'null']},
+        'cpus': {'type': ['integer', 'string']},
+        'memory_mb': {'type': ['integer', 'string']},
+        'disk_gb': {'type': ['integer', 'string']},
+    },
+    'required': ['id', 'interfaces', 'host', 'task_state', 'cpus', 'memory_mb',
+                 'disk_gb']
+}
+
+list_baremetal_nodes = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'nodes': {
+                'type': 'array',
+                'items': node
+            }
+        },
+        'required': ['nodes']
+    }
+}
+
+get_baremetal_node = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'node': node
+        },
+        'required': ['node']
+    }
+}
diff --git a/tempest/api_schema/response/compute/flavors.py b/tempest/api_schema/response/compute/flavors.py
index 44020d2..65f2c28 100644
--- a/tempest/api_schema/response/compute/flavors.py
+++ b/tempest/api_schema/response/compute/flavors.py
@@ -30,8 +30,11 @@
                     },
                     'required': ['name', 'links', 'id']
                 }
-            }
+            },
+            'flavors_links': parameter_types.links
         },
+        # NOTE(gmann): flavors_links attribute is not necessary
+        # to be present always So it is not 'required'.
         'required': ['flavors']
     }
 }
diff --git a/tempest/api_schema/response/compute/hypervisors.py b/tempest/api_schema/response/compute/hypervisors.py
index e9e1bc9..273b579 100644
--- a/tempest/api_schema/response/compute/hypervisors.py
+++ b/tempest/api_schema/response/compute/hypervisors.py
@@ -160,9 +160,14 @@
                 'items': {
                     'type': 'object',
                     'properties': {
+                        'status': {'type': 'string'},
+                        'state': {'type': 'string'},
                         'id': {'type': ['integer', 'string']},
                         'hypervisor_hostname': {'type': 'string'}
                     },
+                    # NOTE: When loading os-hypervisor-status extension,
+                    # a response contains status and state. So these params
+                    # should not be required.
                     'required': ['id', 'hypervisor_hostname']
                 }
             }
diff --git a/tempest/api_schema/response/compute/quotas.py b/tempest/api_schema/response/compute/quotas.py
index f49771e..863104c 100644
--- a/tempest/api_schema/response/compute/quotas.py
+++ b/tempest/api_schema/response/compute/quotas.py
@@ -28,8 +28,13 @@
                     'metadata_items': {'type': 'integer'},
                     'key_pairs': {'type': 'integer'},
                     'security_groups': {'type': 'integer'},
-                    'security_group_rules': {'type': 'integer'}
+                    'security_group_rules': {'type': 'integer'},
+                    'server_group_members': {'type': 'integer'},
+                    'server_groups': {'type': 'integer'},
                 },
+                # NOTE: server_group_members and server_groups are represented
+                # when enabling quota_server_group extension. So they should
+                # not be required.
                 'required': ['instances', 'cores', 'ram',
                              'floating_ips', 'fixed_ips',
                              'metadata_items', 'key_pairs',
diff --git a/tempest/api_schema/response/compute/v2/flavors.py b/tempest/api_schema/response/compute/v2/flavors.py
index 811ea84..76c4cee 100644
--- a/tempest/api_schema/response/compute/v2/flavors.py
+++ b/tempest/api_schema/response/compute/v2/flavors.py
@@ -15,6 +15,7 @@
 import copy
 
 from tempest.api_schema.response.compute import flavors
+from tempest.api_schema.response.compute import parameter_types
 
 list_flavors_details = copy.deepcopy(flavors.common_flavor_list_details)
 
@@ -23,6 +24,12 @@
 list_flavors_details['response_body']['properties']['flavors']['items'][
     'properties']['swap'] = {'type': ['string', 'integer']}
 
+# Defining 'flavors_links' attributes for V2 flavor schema
+list_flavors_details['response_body'][
+    'properties'].update({'flavors_links': parameter_types.links})
+# NOTE(gmann): flavors_links attribute is not necessary to be
+# present always So it is not 'required'.
+
 # Defining extra attributes for V2 flavor schema
 list_flavors_details['response_body']['properties']['flavors']['items'][
     'properties'].update({'OS-FLV-DISABLED:disabled': {'type': 'boolean'},
diff --git a/tempest/api_schema/response/compute/v2/floating_ips.py b/tempest/api_schema/response/compute/v2/floating_ips.py
index def0a78..7250773 100644
--- a/tempest/api_schema/response/compute/v2/floating_ips.py
+++ b/tempest/api_schema/response/compute/v2/floating_ips.py
@@ -146,8 +146,14 @@
                         'instance_uuid': {'type': ['string', 'null']},
                         'interface': {'type': ['string', 'null']},
                         'pool': {'type': ['string', 'null']},
-                        'project_id': {'type': ['string', 'null']}
+                        'project_id': {'type': ['string', 'null']},
+                        'fixed_ip': {
+                            'type': ['string', 'null'],
+                            'format': 'ip-address'
+                        }
                     },
+                    # NOTE: fixed_ip is introduced after JUNO release,
+                    # So it is not defined as 'required'.
                     'required': ['address', 'instance_uuid', 'interface',
                                  'pool', 'project_id']
                 }
diff --git a/tempest/api_schema/response/compute/v2/images.py b/tempest/api_schema/response/compute/v2/images.py
index 923c744..2317e6b 100644
--- a/tempest/api_schema/response/compute/v2/images.py
+++ b/tempest/api_schema/response/compute/v2/images.py
@@ -12,15 +12,20 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import copy
+
 from tempest.api_schema.response.compute import parameter_types
 
+image_links = copy.deepcopy(parameter_types.links)
+image_links['items']['properties'].update({'type': {'type': 'string'}})
+
 common_image_schema = {
     'type': 'object',
     'properties': {
         'id': {'type': 'string'},
         'status': {'type': 'string'},
         'updated': {'type': 'string'},
-        'links': parameter_types.links,
+        'links': image_links,
         'name': {'type': 'string'},
         'created': {'type': 'string'},
         'minDisk': {'type': 'integer'},
@@ -67,7 +72,7 @@
                     'type': 'object',
                     'properties': {
                         'id': {'type': 'string'},
-                        'links': parameter_types.links,
+                        'links': image_links,
                         'name': {'type': 'string'}
                     },
                     'required': ['id', 'links', 'name']
diff --git a/tempest/api_schema/response/compute/v2/limits.py b/tempest/api_schema/response/compute/v2/limits.py
index b9857f1..a7decb7 100644
--- a/tempest/api_schema/response/compute/v2/limits.py
+++ b/tempest/api_schema/response/compute/v2/limits.py
@@ -38,8 +38,15 @@
                             'maxSecurityGroupRules': {'type': 'integer'},
                             'maxTotalKeypairs': {'type': 'integer'},
                             'totalRAMUsed': {'type': 'integer'},
-                            'totalInstancesUsed': {'type': 'integer'}
+                            'totalInstancesUsed': {'type': 'integer'},
+                            'maxServerGroupMembers': {'type': 'integer'},
+                            'maxServerGroups': {'type': 'integer'},
+                            'totalServerGroupsUsed': {'type': 'integer'}
                         },
+                        # NOTE(gmann): maxServerGroupMembers,  maxServerGroups
+                        # and totalServerGroupsUsed are API extension,
+                        # and some environments return a response without these
+                        # attributes.So they are not 'required'.
                         'required': ['maxImageMeta',
                                      'maxPersonality',
                                      'maxPersonalitySize',
diff --git a/tempest/api_schema/response/compute/v2/servers.py b/tempest/api_schema/response/compute/v2/servers.py
index 09abaed..0132350 100644
--- a/tempest/api_schema/response/compute/v2/servers.py
+++ b/tempest/api_schema/response/compute/v2/servers.py
@@ -30,10 +30,10 @@
                     'links': parameter_types.links,
                     'OS-DCF:diskConfig': {'type': 'string'}
                 },
-                # NOTE: OS-DCF:diskConfig is API extension, and some
-                # environments return a response without the attribute.
-                # So it is not 'required'.
-                'required': ['id', 'security_groups', 'links']
+                # NOTE: OS-DCF:diskConfig & security_groups are API extension,
+                # and some environments return a response without these
+                # attributes.So they are not 'required'.
+                'required': ['id', 'links']
             }
         },
         'required': ['server']
@@ -64,6 +64,7 @@
 get_server['response_body']['properties']['server']['properties'].update({
     'key_name': {'type': ['string', 'null']},
     'hostId': {'type': 'string'},
+    'security_groups': {'type': 'array'},
 
     # NOTE: Non-admin users also can see "OS-SRV-USG" and "OS-EXT-AZ"
     # attributes.
@@ -288,10 +289,11 @@
     'properties'].update({
         'hostId': {'type': 'string'},
         'OS-DCF:diskConfig': {'type': 'string'},
+        'security_groups': {'type': 'array'},
         'accessIPv4': parameter_types.access_ip_v4,
         'accessIPv6': parameter_types.access_ip_v6
     })
-# NOTE(GMann): OS-DCF:diskConfig and accessIPv4/v6 are API
+# NOTE(GMann): OS-DCF:diskConfig, security_groups and accessIPv4/v6 are API
 # extensions, and some environments return a response
 # without these attributes. So they are not 'required'.
 list_servers_detail['response_body']['properties']['servers']['items'][
diff --git a/tempest/auth.py b/tempest/auth.py
index 6a92b5f..9d8341c 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -22,13 +22,11 @@
 
 import six
 
-from tempest import config
 from tempest.openstack.common import log as logging
-from tempest.services.identity.json import token_client as json_id
+from tempest.services.identity.v2.json import token_client as json_v2id
 from tempest.services.identity.v3.json import token_client as json_v3id
 
 
-CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
@@ -38,34 +36,21 @@
     Provide authentication
     """
 
-    def __init__(self, credentials, interface=None):
+    def __init__(self, credentials):
         """
         :param credentials: credentials for authentication
-        :param interface: 'json' or 'xml'. Applicable for tempest client only
-            (deprecated: only json now supported)
         """
-        credentials = self._convert_credentials(credentials)
         if self.check_credentials(credentials):
             self.credentials = credentials
         else:
             raise TypeError("Invalid credentials")
-        self.interface = 'json'
         self.cache = None
         self.alt_auth_data = None
         self.alt_part = None
 
-    def _convert_credentials(self, credentials):
-        # Support dict credentials for backwards compatibility
-        if isinstance(credentials, dict):
-            return get_credentials(**credentials)
-        else:
-            return credentials
-
     def __str__(self):
-        return "Creds :{creds}, interface: {interface}, " \
-               "cached auth data: {cache}".format(
-                   creds=self.credentials, interface=self.interface,
-                   cache=self.cache)
+        return "Creds :{creds}, cached auth data: {cache}".format(
+            creds=self.credentials, cache=self.cache)
 
     @abc.abstractmethod
     def _decorate_request(self, filters, method, url, headers=None, body=None,
@@ -201,9 +186,14 @@
 
     token_expiry_threshold = datetime.timedelta(seconds=60)
 
-    def __init__(self, credentials, interface=None):
-        super(KeystoneAuthProvider, self).__init__(credentials, interface)
-        self.auth_client = self._auth_client()
+    def __init__(self, credentials, auth_url,
+                 disable_ssl_certificate_validation=None,
+                 ca_certs=None, trace_requests=None):
+        super(KeystoneAuthProvider, self).__init__(credentials)
+        self.dsvm = disable_ssl_certificate_validation
+        self.ca_certs = ca_certs
+        self.trace_requests = trace_requests
+        self.auth_client = self._auth_client(auth_url)
 
     def _decorate_request(self, filters, method, url, headers=None, body=None,
                           auth_data=None):
@@ -251,8 +241,10 @@
 
     EXPIRY_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
 
-    def _auth_client(self):
-        return json_id.TokenClientJSON()
+    def _auth_client(self, auth_url):
+        return json_v2id.TokenClientJSON(
+            auth_url, disable_ssl_certificate_validation=self.dsvm,
+            ca_certs=self.ca_certs, trace_requests=self.trace_requests)
 
     def _auth_params(self):
         return dict(
@@ -329,15 +321,18 @@
 
     EXPIRY_DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
 
-    def _auth_client(self):
-        return json_v3id.V3TokenClientJSON()
+    def _auth_client(self, auth_url):
+        return json_v3id.V3TokenClientJSON(
+            auth_url, disable_ssl_certificate_validation=self.dsvm,
+            ca_certs=self.ca_certs, trace_requests=self.trace_requests)
 
     def _auth_params(self):
         return dict(
             user=self.credentials.username,
             password=self.credentials.password,
-            tenant=self.credentials.tenant_name,
-            domain=self.credentials.user_domain_name,
+            project=self.credentials.tenant_name,
+            user_domain=self.credentials.user_domain_name,
+            project_domain=self.credentials.project_domain_name,
             auth_data=True)
 
     def _fill_credentials(self, auth_data_body):
@@ -440,47 +435,43 @@
             datetime.datetime.utcnow()
 
 
-def get_default_credentials(credential_type, fill_in=True):
-    """
-    Returns configured credentials of the specified type
-    based on the configured auth_version
-    """
-    return get_credentials(fill_in=fill_in, credential_type=credential_type)
+def is_identity_version_supported(identity_version):
+    return identity_version in IDENTITY_VERSION
 
 
-def get_credentials(credential_type=None, fill_in=True, **kwargs):
+def get_credentials(auth_url, fill_in=True, identity_version='v2', **kwargs):
     """
     Builds a credentials object based on the configured auth_version
 
-    :param credential_type (string): requests credentials from tempest
-           configuration file. Valid values are defined in
-           Credentials.TYPE.
-    :param kwargs (dict): take into account only if credential_type is
-           not specified or None. Dict of credential key/value pairs
+    :param auth_url (string): Full URI of the OpenStack Identity API(Keystone)
+           which is used to fetch the token from Identity service.
+    :param fill_in (boolean): obtain a token and fill in all credential
+           details provided by the identity service. When fill_in is not
+           specified, credentials are not validated. Validation can be invoked
+           by invoking ``is_valid()``
+    :param identity_version (string): identity API version is used to
+           select the matching auth provider and credentials class
+    :param kwargs (dict): Dict of credential key/value pairs
 
     Examples:
 
         Returns credentials from the provided parameters:
         >>> get_credentials(username='foo', password='bar')
 
-        Returns credentials from tempest configuration:
-        >>> get_credentials(credential_type='user')
+        Returns credentials including IDs:
+        >>> get_credentials(username='foo', password='bar', fill_in=True)
     """
-    if CONF.identity.auth_version == 'v2':
-        credential_class = KeystoneV2Credentials
-        auth_provider_class = KeystoneV2AuthProvider
-    elif CONF.identity.auth_version == 'v3':
-        credential_class = KeystoneV3Credentials
-        auth_provider_class = KeystoneV3AuthProvider
-    else:
-        raise exceptions.InvalidConfiguration('Unsupported auth version')
-    if credential_type is not None:
-        creds = credential_class.get_default(credential_type)
-    else:
-        creds = credential_class(**kwargs)
+    if not is_identity_version_supported(identity_version):
+        raise exceptions.InvalidIdentityVersion(
+            identity_version=identity_version)
+
+    credential_class, auth_provider_class = IDENTITY_VERSION.get(
+        identity_version)
+
+    creds = credential_class(**kwargs)
     # Fill in the credentials fields that were not specified
     if fill_in:
-        auth_provider = auth_provider_class(creds)
+        auth_provider = auth_provider_class(creds, auth_url)
         creds = auth_provider.fill_credentials()
     return creds
 
@@ -490,18 +481,9 @@
     Set of credentials for accessing OpenStack services
 
     ATTRIBUTES: list of valid class attributes representing credentials.
-
-    TYPES: types of credentials available in the configuration file.
-           For each key there's a tuple (section, prefix) to match the
-           configuration options.
     """
 
     ATTRIBUTES = []
-    TYPES = {
-        'identity_admin': ('identity', 'admin'),
-        'user': ('identity', None),
-        'alt_user': ('identity', 'alt')
-    }
 
     def __init__(self, **kwargs):
         """
@@ -554,21 +536,8 @@
         except AttributeError:
             return default
 
-    @classmethod
-    def get_default(cls, credentials_type):
-        if credentials_type not in cls.TYPES:
-            raise exceptions.InvalidCredentials()
-        creds = cls._get_default(credentials_type)
-        if not creds.is_valid():
-            msg = ("The %s credentials are incorrectly set in the config file."
-                   " Double check that all required values are assigned" %
-                   credentials_type)
-            raise exceptions.InvalidConfiguration(msg)
-        return creds
-
-    @classmethod
-    def _get_default(cls, credentials_type):
-        raise NotImplementedError
+    def get_init_attributes(self):
+        return self._initial.keys()
 
     def is_valid(self):
         raise NotImplementedError
@@ -584,21 +553,8 @@
 
 class KeystoneV2Credentials(Credentials):
 
-    CONF_ATTRIBUTES = ['username', 'password', 'tenant_name']
-    ATTRIBUTES = ['user_id', 'tenant_id']
-    ATTRIBUTES.extend(CONF_ATTRIBUTES)
-
-    @classmethod
-    def _get_default(cls, credentials_type='user'):
-        params = {}
-        section, prefix = cls.TYPES[credentials_type]
-        for attr in cls.CONF_ATTRIBUTES:
-            _section = getattr(CONF, section)
-            if prefix is None:
-                params[attr] = getattr(_section, attr)
-            else:
-                params[attr] = getattr(_section, prefix + "_" + attr)
-        return cls(**params)
+    ATTRIBUTES = ['username', 'password', 'tenant_name', 'user_id',
+                  'tenant_id']
 
     def is_valid(self):
         """
@@ -608,26 +564,15 @@
         return None not in (self.username, self.password)
 
 
-class KeystoneV3Credentials(KeystoneV2Credentials):
+class KeystoneV3Credentials(Credentials):
     """
     Credentials suitable for the Keystone Identity V3 API
     """
 
-    CONF_ATTRIBUTES = ['domain_name', 'password', 'tenant_name', 'username']
-    ATTRIBUTES = ['project_domain_id', 'project_domain_name', 'project_id',
+    ATTRIBUTES = ['domain_name', 'password', 'tenant_name', 'username',
+                  'project_domain_id', 'project_domain_name', 'project_id',
                   'project_name', 'tenant_id', 'tenant_name', 'user_domain_id',
                   'user_domain_name', 'user_id']
-    ATTRIBUTES.extend(CONF_ATTRIBUTES)
-
-    def __init__(self, **kwargs):
-        """
-        If domain is not specified, load the one configured for the
-        identity manager.
-        """
-        domain_fields = set(x for x in self.ATTRIBUTES if 'domain' in x)
-        if not domain_fields.intersection(kwargs.keys()):
-            kwargs['user_domain_name'] = CONF.identity.admin_domain_name
-        super(KeystoneV3Credentials, self).__init__(**kwargs)
 
     def __setattr__(self, key, value):
         parent = super(KeystoneV3Credentials, self)
@@ -685,3 +630,7 @@
              self.project_id is not None,
              self.project_name is not None and valid_project_domain])
         return all([self.password is not None, valid_user, valid_project])
+
+
+IDENTITY_VERSION = {'v2': (KeystoneV2Credentials, KeystoneV2AuthProvider),
+                    'v3': (KeystoneV3Credentials, KeystoneV3AuthProvider)}
diff --git a/tempest/cli/__init__.py b/tempest/cli/__init__.py
index 4782129..6733204 100644
--- a/tempest/cli/__init__.py
+++ b/tempest/cli/__init__.py
@@ -68,14 +68,22 @@
 
 
 class ClientTestBase(test.BaseTestCase):
+
+    @classmethod
+    def skip_checks(cls):
+        super(ClientTestBase, cls).skip_checks()
+        if not CONF.identity_feature_enabled.api_v2:
+            raise cls.skipException("CLI clients rely on identity v2 API, "
+                                    "which is configured as not available")
+
     @classmethod
     def resource_setup(cls):
         if not CONF.cli.enabled:
             msg = "cli testing disabled"
             raise cls.skipException(msg)
         super(ClientTestBase, cls).resource_setup()
-        cls.cred_prov = credentials.get_isolated_credentials(cls.__name__)
-        cls.creds = cls.cred_prov.get_admin_creds()
+        cls.isolated_creds = credentials.get_isolated_credentials(cls.__name__)
+        cls.creds = cls.isolated_creds.get_admin_creds()
 
     def _get_clients(self):
         clients = base.CLIClient(self.creds.username,
diff --git a/tempest/cli/simple_read_only/compute/__init__.py b/tempest/cli/simple_read_only/compute/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/compute/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/compute/test_nova.py b/tempest/cli/simple_read_only/compute/test_nova.py
deleted file mode 100644
index aee92fa..0000000
--- a/tempest/cli/simple_read_only/compute/test_nova.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# 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.
-
-from tempest_lib import decorators
-from tempest_lib import exceptions
-import testtools
-
-from tempest import cli
-from tempest import config
-from tempest.openstack.common import log as logging
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyNovaClientTest(cli.ClientTestBase):
-
-    """
-    This is a first pass at a simple read only python-novaclient test. This
-    only exercises client commands that are read only.
-
-    This should test commands:
-    * as a regular user
-    * as a admin user
-    * with and without optional parameters
-    * initially just check return codes, and later test command outputs
-
-    """
-
-    @classmethod
-    def resource_setup(cls):
-        if not CONF.service_available.nova:
-            msg = ("%s skipped as Nova is not available" % cls.__name__)
-            raise cls.skipException(msg)
-        super(SimpleReadOnlyNovaClientTest, cls).resource_setup()
-
-    def nova(self, *args, **kwargs):
-        return self.clients.nova(*args,
-                                 endpoint_type=CONF.compute.endpoint_type,
-                                 **kwargs)
-
-    def test_admin_fake_action(self):
-        self.assertRaises(exceptions.CommandFailed,
-                          self.nova,
-                          'this-does-nova-exist')
-
-    # NOTE(jogo): Commands in order listed in 'nova help'
-
-    # Positional arguments:
-
-    def test_admin_absolute_limites(self):
-        self.nova('absolute-limits')
-        self.nova('absolute-limits', params='--reserved')
-
-    def test_admin_aggregate_list(self):
-        self.nova('aggregate-list')
-
-    def test_admin_availability_zone_list(self):
-        self.assertIn("internal", self.nova('availability-zone-list'))
-
-    def test_admin_cloudpipe_list(self):
-        self.nova('cloudpipe-list')
-
-    def test_admin_credentials(self):
-        self.nova('credentials')
-
-    @testtools.skipIf(CONF.service_available.neutron,
-                      "Neutron does not provide this feature")
-    def test_admin_dns_domains(self):
-        self.nova('dns-domains')
-
-    @decorators.skip_because(bug="1157349")
-    def test_admin_dns_list(self):
-        self.nova('dns-list')
-
-    def test_admin_endpoints(self):
-        self.nova('endpoints')
-
-    def test_admin_flavor_acces_list(self):
-        self.assertRaises(exceptions.CommandFailed,
-                          self.nova,
-                          'flavor-access-list')
-        # Failed to get access list for public flavor type
-        self.assertRaises(exceptions.CommandFailed,
-                          self.nova,
-                          'flavor-access-list',
-                          params='--flavor m1.tiny')
-
-    def test_admin_flavor_list(self):
-        self.assertIn("Memory_MB", self.nova('flavor-list'))
-
-    def test_admin_floating_ip_bulk_list(self):
-        self.nova('floating-ip-bulk-list')
-
-    def test_admin_floating_ip_list(self):
-        self.nova('floating-ip-list')
-
-    def test_admin_floating_ip_pool_list(self):
-        self.nova('floating-ip-pool-list')
-
-    def test_admin_host_list(self):
-        self.nova('host-list')
-
-    def test_admin_hypervisor_list(self):
-        self.nova('hypervisor-list')
-
-    def test_admin_image_list(self):
-        self.nova('image-list')
-
-    @decorators.skip_because(bug="1157349")
-    def test_admin_interface_list(self):
-        self.nova('interface-list')
-
-    def test_admin_keypair_list(self):
-        self.nova('keypair-list')
-
-    def test_admin_list(self):
-        self.nova('list')
-        self.nova('list', params='--all-tenants 1')
-        self.nova('list', params='--all-tenants 0')
-        self.assertRaises(exceptions.CommandFailed,
-                          self.nova,
-                          'list',
-                          params='--all-tenants bad')
-
-    def test_admin_network_list(self):
-        self.nova('network-list')
-
-    def test_admin_rate_limits(self):
-        self.nova('rate-limits')
-
-    def test_admin_secgroup_list(self):
-        self.nova('secgroup-list')
-
-    @decorators.skip_because(bug="1157349")
-    def test_admin_secgroup_list_rules(self):
-        self.nova('secgroup-list-rules')
-
-    @cli.min_client_version(client='nova', version='2.18')
-    def test_admin_server_group_list(self):
-        self.nova('server-group-list')
-
-    def test_admin_servce_list(self):
-        self.nova('service-list')
-
-    def test_admin_usage(self):
-        self.nova('usage')
-
-    def test_admin_usage_list(self):
-        self.nova('usage-list')
-
-    @testtools.skipIf(not CONF.service_available.cinder,
-                      "Skipped as Cinder is not available")
-    def test_admin_volume_list(self):
-        self.nova('volume-list')
-
-    @testtools.skipIf(not CONF.service_available.cinder,
-                      "Skipped as Cinder is not available")
-    def test_admin_volume_snapshot_list(self):
-        self.nova('volume-snapshot-list')
-
-    @testtools.skipIf(not CONF.service_available.cinder,
-                      "Skipped as Cinder is not available")
-    def test_admin_volume_type_list(self):
-        self.nova('volume-type-list')
-
-    def test_admin_help(self):
-        self.nova('help')
-
-    def test_admin_list_extensions(self):
-        self.nova('list-extensions')
-
-    def test_admin_net_list(self):
-        self.nova('net-list')
-
-    def test_agent_list(self):
-        self.nova('agent-list')
-        self.nova('agent-list', flags='--debug')
-
-    def test_migration_list(self):
-        self.nova('migration-list')
-        self.nova('migration-list', flags='--debug')
-
-    # Optional arguments:
-
-    def test_admin_version(self):
-        self.nova('', flags='--version')
-
-    def test_admin_debug_list(self):
-        self.nova('list', flags='--debug')
-
-    def test_admin_timeout(self):
-        self.nova('list', flags='--timeout %d' % CONF.cli.timeout)
-
-    def test_admin_timing(self):
-        self.nova('list', flags='--timing')
diff --git a/tempest/cli/simple_read_only/data_processing/test_sahara.py b/tempest/cli/simple_read_only/data_processing/test_sahara.py
index c06c2c9..153dbd2 100644
--- a/tempest/cli/simple_read_only/data_processing/test_sahara.py
+++ b/tempest/cli/simple_read_only/data_processing/test_sahara.py
@@ -47,11 +47,13 @@
             *args, endpoint_type=CONF.data_processing.endpoint_type, **kwargs)
 
     @test.attr(type='negative')
+    @test.idempotent_id('c8809259-710f-43f9-b452-54b2be3115a9')
     def test_sahara_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.sahara,
                           'this-does-not-exist')
 
+    @test.idempotent_id('39afe90c-0fd8-456e-89e2-da6de9680fff')
     def test_sahara_plugins_list(self):
         plugins = self.parser.listing(self.sahara('plugin-list'))
         self.assertTableStruct(plugins, [
@@ -60,6 +62,7 @@
             'title'
         ])
 
+    @test.idempotent_id('3eb36fd8-bb06-4004-9e90-84ddf4dbcf5b')
     @testtools.skipUnless(CONF.data_processing_feature_enabled.plugins,
                           'No plugins defined')
     def test_sahara_plugins_show(self):
@@ -72,6 +75,7 @@
             'Value'
         ])
 
+    @test.idempotent_id('502b684b-3d41-4619-aa6c-4db3465ae79d')
     def test_sahara_node_group_template_list(self):
         result = self.sahara('node-group-template-list')
         node_group_templates = self.parser.listing(result)
@@ -83,6 +87,7 @@
             'description'
         ])
 
+    @test.idempotent_id('6c36fe4d-3b88-4b0d-b702-2a051db7dae7')
     def test_sahara_cluster_template_list(self):
         result = self.sahara('cluster-template-list')
         cluster_templates = self.parser.listing(result)
@@ -94,6 +99,7 @@
             'description'
         ])
 
+    @test.idempotent_id('b951949d-b9a6-49db-add5-8a18ac533810')
     def test_sahara_cluster_list(self):
         result = self.sahara('cluster-list')
         clusters = self.parser.listing(result)
@@ -104,6 +110,7 @@
             'node_count'
         ])
 
+    @test.idempotent_id('dbc83a8c-15b6-4aa8-b274-5896577397e1')
     def test_sahara_data_source_list(self):
         result = self.sahara('data-source-list')
         data_sources = self.parser.listing(result)
@@ -114,6 +121,7 @@
             'description'
         ])
 
+    @test.idempotent_id('a8f77e05-d4bf-45c3-8245-57835d0de37b')
     def test_sahara_job_binary_data_list(self):
         result = self.sahara('job-binary-data-list')
         job_binary_data_list = self.parser.listing(result)
@@ -122,6 +130,7 @@
             'name'
         ])
 
+    @test.idempotent_id('a8f4d0f3-fa1c-49ce-b73f-d624d89dc381')
     def test_sahara_job_binary_list(self):
         result = self.sahara('job-binary-list')
         job_binaries = self.parser.listing(result)
@@ -131,6 +140,7 @@
             'description'
         ])
 
+    @test.idempotent_id('91164ca4-d049-49e0-a52a-686b408196ff')
     def test_sahara_job_template_list(self):
         result = self.sahara('job-template-list')
         job_templates = self.parser.listing(result)
@@ -140,6 +150,7 @@
             'description'
         ])
 
+    @test.idempotent_id('6829c251-a8b6-449d-af86-7dd98b69a7ce')
     def test_sahara_job_list(self):
         result = self.sahara('job-list')
         jobs = self.parser.listing(result)
@@ -149,10 +160,12 @@
             'status'
         ])
 
+    @test.idempotent_id('e4bd5d3b-474b-4b7a-82ab-f6bb0bc89faf')
     def test_sahara_bash_completion(self):
         self.sahara('bash-completion')
 
     # Optional arguments
+    @test.idempotent_id('699c14e5-632e-46b8-91e5-6bff8c8307e5')
     def test_sahara_help(self):
         help_text = self.sahara('help')
         lines = help_text.split('\n')
@@ -172,6 +185,7 @@
                                'plugin-list', 'job-binary-create', 'help'))
         self.assertFalse(wanted_commands - commands)
 
+    @test.idempotent_id('84a18ea6-6379-4024-af6b-0e938f60dfc2')
     def test_sahara_version(self):
         version = self.sahara('', flags='--version')
         self.assertTrue(re.search('[0-9.]+', version))
diff --git a/tempest/cli/simple_read_only/identity/test_keystone.py b/tempest/cli/simple_read_only/identity/test_keystone.py
index 1fc7908..10a26d5 100644
--- a/tempest/cli/simple_read_only/identity/test_keystone.py
+++ b/tempest/cli/simple_read_only/identity/test_keystone.py
@@ -20,6 +20,7 @@
 from tempest import cli
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 
 CONF = config.CONF
 
@@ -38,11 +39,13 @@
     def keystone(self, *args, **kwargs):
         return self.clients.keystone(*args, **kwargs)
 
+    @test.idempotent_id('19c3ae95-3c19-4bba-8ba3-48ad19939b71')
     def test_admin_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.keystone,
                           'this-does-not-exist')
 
+    @test.idempotent_id('a1100917-c7c5-4887-a4da-f7d7f13194f5')
     def test_admin_catalog_list(self):
         out = self.keystone('catalog')
         catalog = self.parser.details_multiple(out, with_label=True)
@@ -57,6 +60,7 @@
             self.assertIn('publicURL', svc.keys())
             self.assertIn('region', svc.keys())
 
+    @test.idempotent_id('35c73506-eab6-4abc-956e-42da90aba8ec')
     def test_admin_endpoint_list(self):
         out = self.keystone('endpoint-list')
         endpoints = self.parser.listing(out)
@@ -64,6 +68,7 @@
             'id', 'region', 'publicurl', 'internalurl',
             'adminurl', 'service_id'])
 
+    @test.idempotent_id('f17cb155-bd16-4f32-9956-1b073752fc07')
     def test_admin_endpoint_service_match(self):
         endpoints = self.parser.listing(self.keystone('endpoint-list'))
         services = self.parser.listing(self.keystone('service-list'))
@@ -73,33 +78,40 @@
         for endpoint in endpoints:
             self.assertIn(endpoint['service_id'], svc_by_id)
 
+    @test.idempotent_id('be7176f2-9c34-4d84-bb7d-b4bc85d06a33')
     def test_admin_role_list(self):
         roles = self.parser.listing(self.keystone('role-list'))
         self.assertTableStruct(roles, ['id', 'name'])
 
+    @test.idempotent_id('96a4de8d-aa9e-4ca5-89f0-985809eccd66')
     def test_admin_service_list(self):
         services = self.parser.listing(self.keystone('service-list'))
         self.assertTableStruct(services, ['id', 'name', 'type', 'description'])
 
+    @test.idempotent_id('edb45480-0f7b-49eb-8f95-7562cbba96da')
     def test_admin_tenant_list(self):
         tenants = self.parser.listing(self.keystone('tenant-list'))
         self.assertTableStruct(tenants, ['id', 'name', 'enabled'])
 
+    @test.idempotent_id('25a2753d-6bd1-40c0-addc-32864b00cb2d')
     def test_admin_user_list(self):
         users = self.parser.listing(self.keystone('user-list'))
         self.assertTableStruct(users, [
             'id', 'name', 'enabled', 'email'])
 
+    @test.idempotent_id('f92bf8d4-b27b-47c9-8450-e27c57758de9')
     def test_admin_user_role_list(self):
         user_roles = self.parser.listing(self.keystone('user-role-list'))
         self.assertTableStruct(user_roles, [
             'id', 'name', 'user_id', 'tenant_id'])
 
+    @test.idempotent_id('14a2687b-3ce1-404c-9f78-a0e28e2f8f7b')
     def test_admin_discover(self):
         discovered = self.keystone('discover')
         self.assertIn('Keystone found at http', discovered)
         self.assertIn('supports version', discovered)
 
+    @test.idempotent_id('9a567c8c-3787-4e5f-9c30-bed55f2b75c0')
     def test_admin_help(self):
         help_text = self.keystone('help')
         lines = help_text.split('\n')
@@ -118,9 +130,11 @@
                                'token-get', 'discover', 'bootstrap'))
         self.assertFalse(wanted_commands - commands)
 
+    @test.idempotent_id('a7b9e1fe-db31-4846-82c5-52a7aa9863c3')
     def test_admin_bashcompletion(self):
         self.keystone('bash-completion')
 
+    @test.idempotent_id('5328c681-df8b-4874-a65c-8fa278f0af8f')
     def test_admin_ec2_credentials_list(self):
         creds = self.keystone('ec2-credentials-list')
         creds = self.parser.listing(creds)
@@ -128,11 +142,14 @@
 
     # Optional arguments:
 
+    @test.idempotent_id('af95e809-ce95-4505-8627-170d803b1d13')
     def test_admin_version(self):
         self.keystone('', flags='--version')
 
+    @test.idempotent_id('9e26521f-7bfa-4d8e-9d61-fd364f0c20c0')
     def test_admin_debug_list(self):
         self.keystone('catalog', flags='--debug')
 
+    @test.idempotent_id('097b3a52-725f-4df7-84b6-277a2b6f6e38')
     def test_admin_timeout(self):
         self.keystone('catalog', flags='--timeout %d' % CONF.cli.timeout)
diff --git a/tempest/cli/simple_read_only/image/test_glance.py b/tempest/cli/simple_read_only/image/test_glance.py
index 03e00d7..3d7126b 100644
--- a/tempest/cli/simple_read_only/image/test_glance.py
+++ b/tempest/cli/simple_read_only/image/test_glance.py
@@ -20,6 +20,7 @@
 from tempest import cli
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 
 CONF = config.CONF
 
@@ -46,11 +47,13 @@
                                    endpoint_type=CONF.image.endpoint_type,
                                    **kwargs)
 
+    @test.idempotent_id('c6bd9bf9-717f-4458-8d74-05b682ea7adf')
     def test_glance_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.glance,
                           'this-does-not-exist')
 
+    @test.idempotent_id('72bcdaf3-11cd-48cb-bb8e-62b329acc1ef')
     def test_glance_image_list(self):
         out = self.glance('image-list')
         endpoints = self.parser.listing(out)
@@ -58,6 +61,7 @@
             'ID', 'Name', 'Disk Format', 'Container Format',
             'Size', 'Status'])
 
+    @test.idempotent_id('965d294c-8772-4899-ba33-26ee23406135')
     def test_glance_member_list(self):
         tenant_name = '--tenant-id %s' % CONF.identity.admin_tenant_name
         out = self.glance('member-list',
@@ -66,6 +70,7 @@
         self.assertTableStruct(endpoints,
                                ['Image ID', 'Member ID', 'Can Share'])
 
+    @test.idempotent_id('43b80ee5-4297-47f3-ab4c-6f81b9c6edb3')
     def test_glance_help(self):
         help_text = self.glance('help')
         lines = help_text.split('\n')
@@ -88,11 +93,14 @@
 
     # Optional arguments:
 
+    @test.idempotent_id('3b2359ea-3719-4b47-81e5-44a042572b11')
     def test_glance_version(self):
         self.glance('', flags='--version')
 
+    @test.idempotent_id('1a52d3bd-3edf-4d67-b3da-999a5d9e0c5e')
     def test_glance_debug_list(self):
         self.glance('image-list', flags='--debug')
 
+    @test.idempotent_id('6f42b076-f9a7-4e2b-a729-579f53e7814e')
     def test_glance_timeout(self):
         self.glance('image-list', flags='--timeout %d' % CONF.cli.timeout)
diff --git a/tempest/cli/simple_read_only/network/test_neutron.py b/tempest/cli/simple_read_only/network/test_neutron.py
index 6cf0640..8af8ada 100644
--- a/tempest/cli/simple_read_only/network/test_neutron.py
+++ b/tempest/cli/simple_read_only/network/test_neutron.py
@@ -48,28 +48,33 @@
                                     **kwargs)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('84dd7190-2b98-4709-8e2c-3c1d25b9e7d2')
     def test_neutron_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.neutron,
                           'this-does-not-exist')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c598c337-313a-45ac-bf27-d6b4124a9e5b')
     def test_neutron_net_list(self):
         net_list = self.parser.listing(self.neutron('net-list'))
         self.assertTableStruct(net_list, ['id', 'name', 'subnets'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3e172b04-2e3b-4fcf-922d-99d5c803779f')
     def test_neutron_ext_list(self):
         ext = self.parser.listing(self.neutron('ext-list'))
         self.assertTableStruct(ext, ['alias', 'name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2e0de814-52d6-4f81-be17-fe327072fc23')
     @test.requires_ext(extension='dhcp_agent_scheduler', service='network')
     def test_neutron_dhcp_agent_list_hosting_net(self):
         self.neutron('dhcp-agent-list-hosting-net',
                      params=CONF.compute.fixed_network_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8524a24a-3895-40a5-8c9d-49d4459cdda4')
     @test.requires_ext(extension='agent', service='network')
     def test_neutron_agent_list(self):
         agents = self.parser.listing(self.neutron('agent-list'))
@@ -77,16 +82,19 @@
         self.assertTableStruct(agents, field_names)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('97c3ef92-7303-45f1-80db-b6622f176782')
     @test.requires_ext(extension='router', service='network')
     def test_neutron_floatingip_list(self):
         self.neutron('floatingip-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('823e0fee-404c-49a7-8bf3-d2f0383cc649')
     @test.requires_ext(extension='metering', service='network')
     def test_neutron_meter_label_list(self):
         self.neutron('meter-label-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7fb76098-01f6-417f-b9c7-e630ba3f394b')
     @test.requires_ext(extension='metering', service='network')
     def test_neutron_meter_label_rule_list(self):
         self.neutron('meter-label-rule-list')
@@ -100,39 +108,47 @@
                 self.fail('%s: Unexpected failure.' % command)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('396d1d87-fd0c-4716-9ff0-f1baa54c6c61')
     def test_neutron_lb_healthmonitor_list(self):
         self._test_neutron_lbaas_command('lb-healthmonitor-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f41fa54d-5cd8-4f2c-bb4e-13abc72dccb6')
     def test_neutron_lb_member_list(self):
         self._test_neutron_lbaas_command('lb-member-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3ec04885-7573-4cce-b086-5722c0b00d85')
     def test_neutron_lb_pool_list(self):
         self._test_neutron_lbaas_command('lb-pool-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1ab530e0-ec87-498f-baf2-85f6635a2ad9')
     def test_neutron_lb_vip_list(self):
         self._test_neutron_lbaas_command('lb-vip-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e92f7362-4009-4b37-afee-f469105b24e7')
     @test.requires_ext(extension='external-net', service='network')
     def test_neutron_net_external_list(self):
         net_ext_list = self.parser.listing(self.neutron('net-external-list'))
         self.assertTableStruct(net_ext_list, ['id', 'name', 'subnets'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ed840980-7c84-4b6e-b280-f13c5848a0e9')
     def test_neutron_port_list(self):
         port_list = self.parser.listing(self.neutron('port-list'))
         self.assertTableStruct(port_list, ['id', 'name', 'mac_address',
                                            'fixed_ips'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('dded0dfa-f2ac-4c1f-bc90-69fd06dd7132')
     @test.requires_ext(extension='quotas', service='network')
     def test_neutron_quota_list(self):
         self.neutron('quota-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('927fca1e-4397-42a2-ba47-d738299466de')
     @test.requires_ext(extension='router', service='network')
     def test_neutron_router_list(self):
         router_list = self.parser.listing(self.neutron('router-list'))
@@ -140,12 +156,14 @@
                                              'external_gateway_info'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e2e3d2d5-1aee-499d-84d9-37382dcf26ff')
     @test.requires_ext(extension='security-group', service='network')
     def test_neutron_security_group_list(self):
         security_grp = self.parser.listing(self.neutron('security-group-list'))
         self.assertTableStruct(security_grp, ['id', 'name', 'description'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('288602c2-8b59-44cd-8c5d-1ec916a114d3')
     @test.requires_ext(extension='security-group', service='network')
     def test_neutron_security_group_rule_list(self):
         security_grp = self.parser.listing(self.neutron
@@ -156,12 +174,14 @@
                                               'remote_group'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2a874a08-b9c9-4f0f-82ef-8cadb15bbd5d')
     def test_neutron_subnet_list(self):
         subnet_list = self.parser.listing(self.neutron('subnet-list'))
         self.assertTableStruct(subnet_list, ['id', 'name', 'cidr',
                                              'allocation_pools'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('048e1ec3-cf6c-4066-b262-2028e03ce825')
     @test.requires_ext(extension='vpnaas', service='network')
     def test_neutron_vpn_ikepolicy_list(self):
         ikepolicy = self.parser.listing(self.neutron('vpn-ikepolicy-list'))
@@ -171,6 +191,7 @@
                                            'ike_version', 'pfs'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bb8902b7-b2e6-49fd-b9bd-a26dd99732df')
     @test.requires_ext(extension='vpnaas', service='network')
     def test_neutron_vpn_ipsecpolicy_list(self):
         ipsecpolicy = self.parser.listing(self.neutron('vpn-ipsecpolicy-list'))
@@ -180,6 +201,7 @@
                                              'pfs'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c0f33f9a-0ba9-4177-bcd5-dce34b81d523')
     @test.requires_ext(extension='vpnaas', service='network')
     def test_neutron_vpn_service_list(self):
         vpn_list = self.parser.listing(self.neutron('vpn-service-list'))
@@ -187,6 +209,7 @@
                                           'router_id', 'status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bb142f8a-e568-405f-b1b7-4cb458de7971')
     @test.requires_ext(extension='vpnaas', service='network')
     def test_neutron_ipsec_site_connection_list(self):
         ipsec_site = self.parser.listing(self.neutron
@@ -198,6 +221,7 @@
                                             'auth_mode', 'status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('89baff14-8cb7-4ad8-9c24-b0278711170b')
     @test.requires_ext(extension='fwaas', service='network')
     def test_neutron_firewall_list(self):
         firewall_list = self.parser.listing(self.neutron
@@ -206,6 +230,7 @@
                                                'firewall_policy_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('996e418a-2a51-4018-9602-478ca8053e61')
     @test.requires_ext(extension='fwaas', service='network')
     def test_neutron_firewall_policy_list(self):
         firewall_policy = self.parser.listing(self.neutron
@@ -214,6 +239,7 @@
                                                  'firewall_rules'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d4638dd6-98d4-4400-a920-26572de1a6fc')
     @test.requires_ext(extension='fwaas', service='network')
     def test_neutron_firewall_rule_list(self):
         firewall_rule = self.parser.listing(self.neutron
@@ -223,6 +249,7 @@
                                                'summary', 'enabled'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1c4551e1-e3f3-4af2-8a40-c3f551e4a536')
     def test_neutron_help(self):
         help_text = self.neutron('help')
         lines = help_text.split('\n')
@@ -243,13 +270,16 @@
     # Optional arguments:
 
     @test.attr(type='smoke')
+    @test.idempotent_id('381e6fe3-cddc-47c9-a773-70ddb2f79a91')
     def test_neutron_version(self):
         self.neutron('', flags='--version')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bcad0e07-da8c-4c7c-8ab6-499e5d7ab8cb')
     def test_neutron_debug_net_list(self):
         self.neutron('net-list', flags='--debug')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3e42d78e-65e5-4e8f-8c29-ca7be8feebb4')
     def test_neutron_quiet_net_list(self):
         self.neutron('net-list', flags='--quiet')
diff --git a/tempest/cli/simple_read_only/object_storage/test_swift.py b/tempest/cli/simple_read_only/object_storage/test_swift.py
index 40c4c15..7201eab 100644
--- a/tempest/cli/simple_read_only/object_storage/test_swift.py
+++ b/tempest/cli/simple_read_only/object_storage/test_swift.py
@@ -19,6 +19,7 @@
 
 from tempest import cli
 from tempest import config
+from tempest import test
 
 CONF = config.CONF
 
@@ -42,14 +43,17 @@
         return self.clients.swift(
             *args, endpoint_type=CONF.object_storage.endpoint_type, **kwargs)
 
+    @test.idempotent_id('74360cdc-e7ec-493f-8a87-2b65f4d54aa3')
     def test_swift_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.swift,
                           'this-does-not-exist')
 
+    @test.idempotent_id('809ec373-828e-4279-8df6-9d4db81c7909')
     def test_swift_list(self):
         self.swift('list')
 
+    @test.idempotent_id('325d5fe4-e5ab-4f52-aec4-357533f24fa1')
     def test_swift_stat(self):
         output = self.swift('stat')
         entries = ['Account', 'Containers', 'Objects', 'Bytes', 'Content-Type',
@@ -57,6 +61,7 @@
         for entry in entries:
             self.assertTrue(entry in output)
 
+    @test.idempotent_id('af1483e1-dafd-4552-a39b-b9d337df808b')
     def test_swift_capabilities(self):
         output = self.swift('capabilities')
         entries = ['account_listing_limit', 'container_listing_limit',
@@ -64,6 +69,7 @@
         for entry in entries:
             self.assertTrue(entry in output)
 
+    @test.idempotent_id('29c83a64-8eb7-418c-a39b-c70cefa5b695')
     def test_swift_help(self):
         help_text = self.swift('', flags='--help')
         lines = help_text.split('\n')
@@ -84,15 +90,19 @@
 
     # Optional arguments:
 
+    @test.idempotent_id('2026be82-4e53-4414-a828-f1c894b8cf0f')
     def test_swift_version(self):
         self.swift('', flags='--version')
 
+    @test.idempotent_id('0ae6172e-3df7-42b8-a987-d42609ada6ed')
     def test_swift_debug_list(self):
         self.swift('list', flags='--debug')
 
+    @test.idempotent_id('1bdf5dd0-7df5-446c-a124-2b0703a5d199')
     def test_swift_retries_list(self):
         self.swift('list', flags='--retries 3')
 
+    @test.idempotent_id('64eae749-8fbd-4d85-bc7f-f706d3581c6f')
     def test_swift_region_list(self):
         region = CONF.object_storage.region
         if not region:
diff --git a/tempest/cli/simple_read_only/orchestration/test_heat.py b/tempest/cli/simple_read_only/orchestration/test_heat.py
index d3a9b01..7751e2c 100644
--- a/tempest/cli/simple_read_only/orchestration/test_heat.py
+++ b/tempest/cli/simple_read_only/orchestration/test_heat.py
@@ -18,6 +18,7 @@
 import tempest.cli
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 
 CONF = config.CONF
 
@@ -46,58 +47,71 @@
         return self.clients.heat(
             *args, endpoint_type=CONF.orchestration.endpoint_type, **kwargs)
 
+    @test.idempotent_id('0ae034bb-ce35-45e8-b7aa-3e339cd3140f')
     def test_heat_stack_list(self):
         self.heat('stack-list')
 
+    @test.idempotent_id('a360d069-7250-4aed-9721-0a6f2db7c3fa')
     def test_heat_stack_list_debug(self):
         self.heat('stack-list', flags='--debug')
 
+    @test.idempotent_id('e1b7c177-5ab4-4d3f-8a26-ea01ebbd2b8c')
     def test_heat_resource_template_fmt_default(self):
         ret = self.heat('resource-template OS::Nova::Server')
         self.assertIn('Type: OS::Nova::Server', ret)
 
+    @test.idempotent_id('93f82f76-aab2-4910-9359-11cf48f2a46b')
     def test_heat_resource_template_fmt_arg_short_yaml(self):
         ret = self.heat('resource-template -F yaml OS::Nova::Server')
         self.assertIn('Type: OS::Nova::Server', ret)
         self.assertIsInstance(yaml.safe_load(ret), dict)
 
+    @test.idempotent_id('7356a98c-e14d-43f0-8c25-c9f7daa0aafa')
     def test_heat_resource_template_fmt_arg_long_json(self):
         ret = self.heat('resource-template --format json OS::Nova::Server')
         self.assertIn('"Type": "OS::Nova::Server"', ret)
         self.assertIsInstance(json.loads(ret), dict)
 
+    @test.idempotent_id('2fd99d20-beff-4667-b42e-de9095f671d7')
     def test_heat_resource_type_list(self):
         ret = self.heat('resource-type-list')
         rsrc_types = self.parser.listing(ret)
         self.assertTableStruct(rsrc_types, ['resource_type'])
 
+    @test.idempotent_id('62f60dbf-d139-4698-b230-a09fb531d643')
     def test_heat_resource_type_show(self):
         rsrc_schema = self.heat('resource-type-show OS::Nova::Server')
         # resource-type-show returns a json resource schema
         self.assertIsInstance(json.loads(rsrc_schema), dict)
 
+    @test.idempotent_id('6ca16ff7-9d5f-4448-a8c2-4cecc7b5ba3a')
     def test_heat_template_validate_yaml(self):
         ret = self.heat('template-validate -f %s' % self.heat_template_path)
         # On success template-validate returns a json representation
         # of the template parameters
         self.assertIsInstance(json.loads(ret), dict)
 
+    @test.idempotent_id('35241014-16ea-4cb6-ad3e-4ee5f41446de')
     def test_heat_template_validate_hot(self):
         ret = self.heat('template-validate -f %s' % self.heat_template_path)
         self.assertIsInstance(json.loads(ret), dict)
 
+    @test.idempotent_id('34d43e0a-36dc-4ea8-9b85-0189e3de89d8')
     def test_heat_help(self):
         self.heat('help')
 
     @tempest.cli.min_client_version(client='heat', version='0.2.7')
+    @test.idempotent_id('c122c08b-839d-49d1-afd1-bc546b2d18d3')
     def test_heat_bash_completion(self):
         self.heat('bash-completion')
 
+    @test.idempotent_id('1b045e12-2fa0-4895-9282-00668428dfbe')
     def test_heat_help_cmd(self):
         # Check requesting help for a specific command works
         help_text = self.heat('help resource-template')
         lines = help_text.split('\n')
         self.assertFirstLineStartsWith(lines, 'usage: heat resource-template')
 
+    @test.idempotent_id('c7837f8f-d0a8-47fd-b75b-14ba3e3fa9a2')
     def test_heat_version(self):
         self.heat('', flags='--version')
diff --git a/tempest/cli/simple_read_only/telemetry/test_ceilometer.py b/tempest/cli/simple_read_only/telemetry/test_ceilometer.py
index f9bf8b2..85db596 100644
--- a/tempest/cli/simple_read_only/telemetry/test_ceilometer.py
+++ b/tempest/cli/simple_read_only/telemetry/test_ceilometer.py
@@ -43,15 +43,19 @@
         return self.clients.ceilometer(
             *args, endpoint_type=CONF.telemetry.endpoint_type, **kwargs)
 
+    @test.idempotent_id('ab717d43-a9c4-4dcf-bad8-c4777933a970')
     def test_ceilometer_meter_list(self):
         self.ceilometer('meter-list')
 
     @test.attr(type='slow')
+    @test.idempotent_id('fe2e52a4-a99b-426e-a52d-d0bde50f3e4c')
     def test_ceilometer_resource_list(self):
         self.ceilometer('resource-list')
 
+    @test.idempotent_id('eede695c-f3bf-449f-a420-02f3cc426d52')
     def test_ceilometermeter_alarm_list(self):
         self.ceilometer('alarm-list')
 
+    @test.idempotent_id('0586bcc4-8e35-415f-8f23-77b590042684')
     def test_ceilometer_version(self):
         self.ceilometer('', flags='--version')
diff --git a/tempest/cli/simple_read_only/volume/test_cinder.py b/tempest/cli/simple_read_only/volume/test_cinder.py
index c2e0a42..cb29cc8 100644
--- a/tempest/cli/simple_read_only/volume/test_cinder.py
+++ b/tempest/cli/simple_read_only/volume/test_cinder.py
@@ -22,6 +22,7 @@
 from tempest import cli
 from tempest import clients
 from tempest import config
+from tempest import test
 
 
 CONF = config.CONF
@@ -51,25 +52,30 @@
                                    endpoint_type=CONF.volume.endpoint_type,
                                    **kwargs)
 
+    @test.idempotent_id('229bc6dc-d804-4668-b753-b590caf63061')
     def test_cinder_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.cinder,
                           'this-does-not-exist')
 
+    @test.idempotent_id('77140216-14db-4fc5-a246-e2a587e9e99b')
     def test_cinder_absolute_limit_list(self):
         roles = self.parser.listing(self.cinder('absolute-limits'))
         self.assertTableStruct(roles, ['Name', 'Value'])
 
+    @test.idempotent_id('2206b9ce-1a36-4a0a-a129-e5afc7cee1dd')
     def test_cinder_backup_list(self):
         backup_list = self.parser.listing(self.cinder('backup-list'))
         self.assertTableStruct(backup_list, ['ID', 'Volume ID', 'Status',
                                              'Name', 'Size', 'Object Count',
                                              'Container'])
 
+    @test.idempotent_id('c7f50346-cd99-4e0b-953f-796ff5f47295')
     def test_cinder_extra_specs_list(self):
         extra_specs_list = self.parser.listing(self.cinder('extra-specs-list'))
         self.assertTableStruct(extra_specs_list, ['ID', 'Name', 'extra_specs'])
 
+    @test.idempotent_id('9de694cb-b40b-442c-a30c-5f9873e144f7')
     def test_cinder_volumes_list(self):
         list = self.parser.listing(self.cinder('list'))
         self.assertTableStruct(list, ['ID', 'Status', 'Name', 'Size',
@@ -82,29 +88,34 @@
                           'list',
                           params='--all-tenants bad')
 
+    @test.idempotent_id('56f7c15c-ee82-4f23-bbe8-ce99b66da493')
     def test_cinder_quota_class_show(self):
         """This CLI can accept and string as param."""
         roles = self.parser.listing(self.cinder('quota-class-show',
                                                 params='abc'))
         self.assertTableStruct(roles, ['Property', 'Value'])
 
+    @test.idempotent_id('a919a811-b7f0-47a7-b4e5-f3eb674dd200')
     def test_cinder_quota_defaults(self):
         """This CLI can accept and string as param."""
         roles = self.parser.listing(self.cinder('quota-defaults',
                                                 params=self.admin_tenant_id))
         self.assertTableStruct(roles, ['Property', 'Value'])
 
+    @test.idempotent_id('18166673-ffa8-4df3-b60c-6375532288bc')
     def test_cinder_quota_show(self):
         """This CLI can accept and string as param."""
         roles = self.parser.listing(self.cinder('quota-show',
                                                 params=self.admin_tenant_id))
         self.assertTableStruct(roles, ['Property', 'Value'])
 
+    @test.idempotent_id('b2c66ed9-ca96-4dc4-94cc-8083e664e516')
     def test_cinder_rate_limits(self):
         rate_limits = self.parser.listing(self.cinder('rate-limits'))
         self.assertTableStruct(rate_limits, ['Verb', 'URI', 'Value', 'Remain',
                                              'Unit', 'Next_Available'])
 
+    @test.idempotent_id('7a19955b-807c-481a-a2ee-9d76733eac28')
     @testtools.skipUnless(CONF.volume_feature_enabled.snapshot,
                           'Volume snapshot not available.')
     def test_cinder_snapshot_list(self):
@@ -112,22 +123,27 @@
         self.assertTableStruct(snapshot_list, ['ID', 'Volume ID', 'Status',
                                                'Name', 'Size'])
 
+    @test.idempotent_id('6e54ecd9-7ba9-490d-8e3b-294b67139e73')
     def test_cinder_type_list(self):
         type_list = self.parser.listing(self.cinder('type-list'))
         self.assertTableStruct(type_list, ['ID', 'Name'])
 
+    @test.idempotent_id('2c363583-24a0-4980-b9cb-b50c0d241e82')
     def test_cinder_list_extensions(self):
         roles = self.parser.listing(self.cinder('list-extensions'))
         self.assertTableStruct(roles, ['Name', 'Summary', 'Alias', 'Updated'])
 
+    @test.idempotent_id('691bd6df-30ad-4be7-927b-a02d62aaa38a')
     def test_cinder_credentials(self):
         credentials = self.parser.listing(self.cinder('credentials'))
         self.assertTableStruct(credentials, ['User Credentials', 'Value'])
 
+    @test.idempotent_id('5c6d71a3-4904-4a3a-aec9-7fd4aa830e95')
     def test_cinder_availability_zone_list(self):
         zone_list = self.parser.listing(self.cinder('availability-zone-list'))
         self.assertTableStruct(zone_list, ['Name', 'Status'])
 
+    @test.idempotent_id('9b0fd5a6-f955-42b9-a42f-6f542a80b9a3')
     def test_cinder_endpoints(self):
         out = self.cinder('endpoints')
         tables = self.parser.tables(out)
@@ -136,28 +152,34 @@
             self.assertTrue(2 >= len(headers))
             self.assertEqual('Value', headers[1])
 
+    @test.idempotent_id('301b5ae1-9591-4e9f-999c-d525a9bdf822')
     def test_cinder_service_list(self):
         service_list = self.parser.listing(self.cinder('service-list'))
         self.assertTableStruct(service_list, ['Binary', 'Host', 'Zone',
                                               'Status', 'State', 'Updated_at'])
 
+    @test.idempotent_id('7260ae52-b462-461e-9048-36d0bccf92c6')
     def test_cinder_transfer_list(self):
         transfer_list = self.parser.listing(self.cinder('transfer-list'))
         self.assertTableStruct(transfer_list, ['ID', 'Volume ID', 'Name'])
 
+    @test.idempotent_id('0976dea8-14f3-45a9-8495-3617fc4fbb13')
     def test_cinder_bash_completion(self):
         self.cinder('bash-completion')
 
+    @test.idempotent_id('b7c00361-be80-4512-8735-5f98fc54f2a9')
     def test_cinder_qos_list(self):
         qos_list = self.parser.listing(self.cinder('qos-list'))
         self.assertTableStruct(qos_list, ['ID', 'Name', 'Consumer', 'specs'])
 
+    @test.idempotent_id('2e92dc6e-22b5-4d94-abfc-b543b0c50a89')
     def test_cinder_encryption_type_list(self):
         encrypt_list = self.parser.listing(self.cinder('encryption-type-list'))
         self.assertTableStruct(encrypt_list, ['Volume Type ID', 'Provider',
                                               'Cipher', 'Key Size',
                                               'Control Location'])
 
+    @test.idempotent_id('0ee6cb4c-8de6-4811-a7be-7f4bb75b80cc')
     def test_admin_help(self):
         help_text = self.cinder('help')
         lines = help_text.split('\n')
@@ -178,15 +200,19 @@
 
     # Optional arguments:
 
+    @test.idempotent_id('2fd6f530-183c-4bda-8918-1e59e36c26b9')
     def test_cinder_version(self):
         self.cinder('', flags='--version')
 
+    @test.idempotent_id('306bac51-c443-4426-a6cf-583a953fcd68')
     def test_cinder_debug_list(self):
         self.cinder('list', flags='--debug')
 
+    @test.idempotent_id('6d97fcd2-5dd1-429d-af70-030c949d86cd')
     def test_cinder_retries_list(self):
         self.cinder('list', flags='--retries 3')
 
+    @test.idempotent_id('95a2850c-35b4-4159-bb93-51647a5ad232')
     def test_cinder_region_list(self):
         region = CONF.volume.region
         if not region:
diff --git a/tempest/clients.py b/tempest/clients.py
index 03928ba..63bc117 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -15,7 +15,7 @@
 
 import copy
 
-from tempest import auth
+from tempest.common import cred_provider
 from tempest.common import negative_rest_client
 from tempest import config
 from tempest import manager
@@ -29,6 +29,8 @@
     AggregatesClientJSON
 from tempest.services.compute.json.availability_zone_client import \
     AvailabilityZoneClientJSON
+from tempest.services.compute.json.baremetal_nodes_client import \
+    BaremetalNodesClientJSON
 from tempest.services.compute.json.certificates_client import \
     CertificatesClientJSON
 from tempest.services.compute.json.extensions_client import \
@@ -64,15 +66,17 @@
     TenantUsagesClientJSON
 from tempest.services.compute.json.volumes_extensions_client import \
     VolumesExtensionsClientJSON
-from tempest.services.data_processing.v1_1.client import DataProcessingClient
+from tempest.services.data_processing.v1_1.data_processing_client import \
+    DataProcessingClient
 from tempest.services.database.json.flavors_client import \
     DatabaseFlavorsClientJSON
 from tempest.services.database.json.limits_client import \
     DatabaseLimitsClientJSON
 from tempest.services.database.json.versions_client import \
     DatabaseVersionsClientJSON
-from tempest.services.identity.json.identity_client import IdentityClientJSON
-from tempest.services.identity.json.token_client import TokenClientJSON
+from tempest.services.identity.v2.json.identity_client import \
+    IdentityClientJSON
+from tempest.services.identity.v2.json.token_client import TokenClientJSON
 from tempest.services.identity.v3.json.credentials_client import \
     CredentialsClientJSON
 from tempest.services.identity.v3.json.endpoints_client import \
@@ -155,10 +159,7 @@
     }
     default_params_with_timeout_values.update(default_params)
 
-    def __init__(self, credentials=None, interface='json', service=None):
-        # Set interface and client type first
-        self.interface = interface
-        # super cares for credentials validation
+    def __init__(self, credentials=None, service=None):
         super(Manager, self).__init__(credentials=credentials)
 
         self._set_compute_clients()
@@ -194,8 +195,22 @@
                 endpoint_type=CONF.telemetry.endpoint_type,
                 **self.default_params_with_timeout_values)
         if CONF.service_available.glance:
-            self.image_client = ImageClientJSON(self.auth_provider)
-            self.image_client_v2 = ImageClientV2JSON(self.auth_provider)
+            self.image_client = ImageClientJSON(
+                self.auth_provider,
+                CONF.image.catalog_type,
+                CONF.image.region or CONF.identity.region,
+                endpoint_type=CONF.image.endpoint_type,
+                build_interval=CONF.image.build_interval,
+                build_timeout=CONF.image.build_timeout,
+                **self.default_params)
+            self.image_client_v2 = ImageClientV2JSON(
+                self.auth_provider,
+                CONF.image.catalog_type,
+                CONF.image.region or CONF.identity.region,
+                endpoint_type=CONF.image.endpoint_type,
+                build_interval=CONF.image.build_interval,
+                build_timeout=CONF.image.build_timeout,
+                **self.default_params)
         self.orchestration_client = OrchestrationClient(
             self.auth_provider,
             CONF.orchestration.catalog_type,
@@ -204,6 +219,12 @@
             build_interval=CONF.orchestration.build_interval,
             build_timeout=CONF.orchestration.build_timeout,
             **self.default_params)
+        self.data_processing_client = DataProcessingClient(
+            self.auth_provider,
+            CONF.data_processing.catalog_type,
+            CONF.identity.region,
+            endpoint_type=CONF.data_processing.endpoint_type,
+            **self.default_params_with_timeout_values)
         self.negative_client = negative_rest_client.NegativeRestClient(
             self.auth_provider, service)
 
@@ -214,8 +235,6 @@
                            self.credentials.tenant_name)
         self.ec2api_client = botoclients.APIClientEC2(*ec2_client_args)
         self.s3_client = botoclients.ObjectClientS3(*ec2_client_args)
-        self.data_processing_client = DataProcessingClient(
-            self.auth_provider)
 
     def _set_compute_clients(self):
         params = {
@@ -235,7 +254,11 @@
             SecurityGroupDefaultRulesClientJSON(self.auth_provider, **params))
         self.certificates_client = CertificatesClientJSON(self.auth_provider,
                                                           **params)
-        self.servers_client = ServersClientJSON(self.auth_provider, **params)
+        self.servers_client = ServersClientJSON(
+            self.auth_provider,
+            enable_instance_password=CONF.compute_feature_enabled
+                .enable_instance_password,
+            **params)
         self.limits_client = LimitsClientJSON(self.auth_provider, **params)
         self.images_client = ImagesClientJSON(self.auth_provider, **params)
         self.keypairs_client = KeyPairsClientJSON(self.auth_provider, **params)
@@ -267,6 +290,8 @@
             InstanceUsagesAuditLogClientJSON(self.auth_provider, **params)
         self.tenant_networks_client = \
             TenantNetworksClientJSON(self.auth_provider, **params)
+        self.baremetal_nodes_client = BaremetalNodesClientJSON(
+            self.auth_provider, **params)
 
         # NOTE: The following client needs special timeout values because
         # the API is a proxy for the other component.
@@ -296,16 +321,30 @@
             **self.default_params_with_timeout_values)
 
     def _set_identity_clients(self):
-        self.identity_client = IdentityClientJSON(self.auth_provider)
-        self.identity_v3_client = IdentityV3ClientJSON(self.auth_provider)
-        self.endpoints_client = EndPointClientJSON(self.auth_provider)
-        self.service_client = ServiceClientJSON(self.auth_provider)
-        self.policy_client = PolicyClientJSON(self.auth_provider)
-        self.region_client = RegionClientJSON(self.auth_provider)
-        self.token_client = TokenClientJSON()
+        params = {
+            'service': CONF.identity.catalog_type,
+            'region': CONF.identity.region,
+            'endpoint_type': 'adminURL'
+        }
+        params.update(self.default_params_with_timeout_values)
+
+        self.identity_client = IdentityClientJSON(self.auth_provider,
+                                                  **params)
+        self.identity_v3_client = IdentityV3ClientJSON(self.auth_provider,
+                                                       **params)
+        self.endpoints_client = EndPointClientJSON(self.auth_provider,
+                                                   **params)
+        self.service_client = ServiceClientJSON(self.auth_provider, **params)
+        self.policy_client = PolicyClientJSON(self.auth_provider, **params)
+        self.region_client = RegionClientJSON(self.auth_provider, **params)
+        self.credentials_client = CredentialsClientJSON(self.auth_provider,
+                                                        **params)
+        # Token clients do not use the catalog. They only need default_params.
+        self.token_client = TokenClientJSON(CONF.identity.uri,
+                                            **self.default_params)
         if CONF.identity_feature_enabled.api_v3:
-            self.token_v3_client = V3TokenClientJSON()
-        self.credentials_client = CredentialsClientJSON(self.auth_provider)
+            self.token_v3_client = V3TokenClientJSON(CONF.identity.uri_v3,
+                                                     **self.default_params)
 
     def _set_volume_clients(self):
         params = {
@@ -330,9 +369,12 @@
                                                     **params)
         self.snapshots_v2_client = SnapshotsV2ClientJSON(self.auth_provider,
                                                          **params)
-        self.volumes_client = VolumesClientJSON(self.auth_provider, **params)
-        self.volumes_v2_client = VolumesV2ClientJSON(self.auth_provider,
-                                                     **params)
+        self.volumes_client = VolumesClientJSON(
+            self.auth_provider, default_volume_size=CONF.volume.volume_size,
+            **params)
+        self.volumes_v2_client = VolumesV2ClientJSON(
+            self.auth_provider, default_volume_size=CONF.volume.volume_size,
+            **params)
         self.volume_types_client = VolumeTypesClientJSON(self.auth_provider,
                                                          **params)
         self.volume_services_client = VolumesServicesClientJSON(
@@ -376,8 +418,8 @@
     managed client objects
     """
 
-    def __init__(self, interface='json', service=None):
+    def __init__(self, service=None):
         super(AdminManager, self).__init__(
-            credentials=auth.get_default_credentials('identity_admin'),
-            interface=interface,
+            credentials=cred_provider.get_configured_credentials(
+                'identity_admin'),
             service=service)
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index 28992b9..669f506 100755
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -54,9 +54,9 @@
 import json
 import sys
 
-from tempest import auth
 from tempest import clients
 from tempest.cmd import cleanup_service
+from tempest.common import cred_provider
 from tempest import config
 from tempest.openstack.common import log as logging
 
@@ -159,7 +159,8 @@
         kwargs = {"username": CONF.identity.admin_username,
                   "password": CONF.identity.admin_password,
                   "tenant_name": tenant['name']}
-        mgr = clients.Manager(credentials=auth.get_credentials(**kwargs))
+        mgr = clients.Manager(credentials=cred_provider.get_credentials(
+            **kwargs))
         kwargs = {'data': tenant_data,
                   'is_dry_run': is_dry_run,
                   'saved_state_json': None,
@@ -221,7 +222,7 @@
                 needs_role = False
                 LOG.debug("User already had admin privilege for this tenant")
         if needs_role:
-            LOG.debug("Adding admin priviledge for : %s" % tenant_id)
+            LOG.debug("Adding admin privilege for : %s" % tenant_id)
             id_cl.assign_user_role(tenant_id, self.admin_id,
                                    self.admin_role_id)
             self.admin_role_added.append(tenant_id)
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 9c4a5dc..7b217bb 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -168,7 +168,7 @@
 
     def list(self):
         client = self.client
-        _, servers_body = client.list_servers()
+        servers_body = client.list_servers()
         servers = servers_body['servers']
         LOG.debug("List count, %s Servers" % len(servers))
         return servers
@@ -192,7 +192,7 @@
 
     def list(self):
         client = self.client
-        _, sgs = client.list_server_groups()
+        sgs = client.list_server_groups()
         LOG.debug("List count, %s Server Groups" % len(sgs))
         return sgs
 
@@ -297,7 +297,7 @@
 
     def list(self):
         client = self.client
-        _, floating_ips = client.list_floating_ips()
+        floating_ips = client.list_floating_ips()
         LOG.debug("List count, %s Floating IPs" % len(floating_ips))
         return floating_ips
 
@@ -833,9 +833,9 @@
 
     def save_state(self):
         flavors = self.list()
-        flavor_data = self.data['flavors'] = {}
+        self.data['flavors'] = {}
         for flavor in flavors:
-            flavor_data[flavor['id']] = flavor['name']
+            self.data['flavors'][flavor['id']] = flavor['name']
 
 
 class ImageService(BaseService):
@@ -871,9 +871,9 @@
 
     def save_state(self):
         images = self.list()
-        image_data = self.data['images'] = {}
+        self.data['images'] = {}
         for image in images:
-            image_data[image['id']] = image['name']
+            self.data['images'][image['id']] = image['name']
 
 
 class IdentityService(BaseService):
@@ -919,9 +919,9 @@
 
     def save_state(self):
         users = self.list()
-        user_data = self.data['users'] = {}
+        self.data['users'] = {}
         for user in users:
-            user_data[user['id']] = user['name']
+            self.data['users'][user['id']] = user['name']
 
 
 class RoleService(IdentityService):
@@ -958,9 +958,9 @@
 
     def save_state(self):
         roles = self.list()
-        role_data = self.data['roles'] = {}
+        self.data['roles'] = {}
         for role in roles:
-            role_data[role['id']] = role['name']
+            self.data['roles'][role['id']] = role['name']
 
 
 class TenantService(IdentityService):
@@ -996,9 +996,9 @@
 
     def save_state(self):
         tenants = self.list()
-        tenant_data = self.data['tenants'] = {}
+        self.data['tenants'] = {}
         for tenant in tenants:
-            tenant_data[tenant['id']] = tenant['name']
+            self.data['tenants'][tenant['id']] = tenant['name']
 
 
 class DomainService(BaseService):
@@ -1034,9 +1034,9 @@
 
     def save_state(self):
         domains = self.list()
-        domain_data = self.data['domains'] = {}
+        self.data['domains'] = {}
         for domain in domains:
-            domain_data[domain['id']] = domain['name']
+            self.data['domains'][domain['id']] = domain['name']
 
 
 def get_tenant_cleanup_services():
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 889b2dd..4c09bd2 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -110,17 +110,17 @@
 import unittest
 
 import netaddr
+from tempest_lib import exceptions as lib_exc
 import yaml
 
 import tempest.auth
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest.openstack.common import timeutils
 from tempest.services.compute.json import flavors_client
 from tempest.services.compute.json import security_groups_client
 from tempest.services.compute.json import servers_client
-from tempest.services.identity.json import identity_client
+from tempest.services.identity.v2.json import identity_client
 from tempest.services.image.v2.json import image_client
 from tempest.services.network.json import network_client
 from tempest.services.object_storage import container_client
@@ -176,8 +176,20 @@
             username=user,
             password=pw,
             tenant_name=tenant)
-        _auth = tempest.auth.KeystoneV2AuthProvider(_creds)
-        self.identity = identity_client.IdentityClientJSON(_auth)
+        auth_provider_params = {
+            'disable_ssl_certificate_validation':
+                CONF.identity.disable_ssl_certificate_validation,
+            'ca_certs': CONF.identity.ca_certificates_file,
+            'trace_requests': CONF.debug.trace_requests
+        }
+        _auth = tempest.auth.KeystoneV2AuthProvider(
+            _creds, CONF.identity.uri, **auth_provider_params)
+        self.identity = identity_client.IdentityClientJSON(
+            _auth,
+            CONF.identity.catalog_type,
+            CONF.identity.region,
+            endpoint_type='adminURL',
+            **default_params_with_timeout_values)
         self.servers = servers_client.ServersClientJSON(_auth,
                                                         **compute_params)
         self.flavors = flavors_client.FlavorsClientJSON(_auth,
@@ -188,7 +200,14 @@
                                                   **object_storage_params)
         self.containers = container_client.ContainerClient(
             _auth, **object_storage_params)
-        self.images = image_client.ImageClientV2JSON(_auth)
+        self.images = image_client.ImageClientV2JSON(
+            _auth,
+            CONF.image.catalog_type,
+            CONF.image.region or CONF.identity.region,
+            endpoint_type=CONF.image.endpoint_type,
+            build_interval=CONF.image.build_interval,
+            build_timeout=CONF.image.build_timeout,
+            **default_params)
         self.telemetry = telemetry_client.TelemetryClientJSON(
             _auth,
             CONF.telemetry.catalog_type,
@@ -232,9 +251,6 @@
         LOG.error("%s not found in USERS: %s" % (name, USERS))
 
 
-def resp_ok(response):
-    return 200 >= int(response['status']) < 300
-
 ###################
 #
 # TENANTS
@@ -297,7 +313,7 @@
             USERS[user]['tenant_id'],
             USERS[user]['id'],
             role['id'])
-    except exceptions.Conflict:
+    except lib_exc.Conflict:
         # don't care if it's already assigned
         pass
 
@@ -313,14 +329,14 @@
     for u in users:
         try:
             tenant = admin.identity.get_tenant_by_name(u['tenant'])
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             LOG.error("Tenant: %s - not found" % u['tenant'])
             continue
         try:
             admin.identity.get_user_by_username(tenant['id'], u['name'])
             LOG.warn("User '%s' already exists in this environment"
                      % u['name'])
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             admin.identity.create_user(
                 u['name'], u['pass'], tenant['id'],
                 "%s@%s" % (u['name'], tenant['id']),
@@ -405,8 +421,7 @@
             # on the cloud. We don't care about the results except that it
             # remains authorized.
             client = client_for_user(user['name'])
-            resp, body = client.servers.list_servers()
-            self.assertEqual(resp['status'], '200')
+            client.servers.list_servers()
 
     def check_objects(self):
         """Check that the objects created are still there."""
@@ -432,7 +447,7 @@
                 found,
                 "Couldn't find expected server %s" % server['name'])
 
-            r, found = client.servers.get_server(found['id'])
+            found = client.servers.get_server(found['id'])
             # validate neutron is enabled and ironic disabled:
             if (CONF.service_available.neutron and
                     not CONF.baremetal.driver_enabled):
@@ -707,7 +722,7 @@
                                           cidr=subnet['range'],
                                           name=subnet['name'],
                                           ip_version=ip_version)
-        except exceptions.BadRequest as e:
+        except lib_exc.BadRequest as e:
             is_overlapping_cidr = 'overlaps with another subnet' in str(e)
             if not is_overlapping_cidr:
                 raise
@@ -780,7 +795,7 @@
 #######################
 
 def _get_server_by_name(client, name):
-    r, body = client.servers.list_servers()
+    body = client.servers.list_servers()
     for server in body['servers']:
         if name == server['name']:
             return server
@@ -816,7 +831,7 @@
                 client.networks, 'networks', x)['id'])
             kwargs['networks'] = [{'uuid': get_net_id(network)}
                                   for network in server['networks']]
-        resp, body = client.servers.create_server(
+        body = client.servers.create_server(
             server['name'], image_id, flavor_id, **kwargs)
         server_id = body['id']
         client.servers.wait_for_server_status(server_id, 'ACTIVE')
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 65a3a95..697965f 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -154,7 +154,7 @@
 
 def verify_extensions(os, service, results):
     extensions_client = get_extension_client(os, service)
-    if service == 'neutron' or service == 'cinder':
+    if service != 'swift':
         resp = extensions_client.list_extensions()
     else:
         __, resp = extensions_client.list_extensions()
@@ -327,7 +327,7 @@
         CONF_PARSER = moves.configparser.SafeConfigParser()
         CONF_PARSER.optionxform = str
         CONF_PARSER.readfp(conf_file)
-    os = clients.AdminManager(interface='json')
+    os = clients.AdminManager()
     services = check_service_availability(os, update)
     results = {}
     for service in ['nova', 'cinder', 'neutron', 'swift']:
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index 66285e4..e21a85e 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -17,7 +17,6 @@
 
 import yaml
 
-from tempest import auth
 from tempest.common import cred_provider
 from tempest import config
 from tempest import exceptions
@@ -38,6 +37,7 @@
 
     def __init__(self, name):
         super(Accounts, self).__init__(name)
+        self.name = name
         if os.path.isfile(CONF.auth.test_accounts_file):
             accounts = read_accounts_yaml(CONF.auth.test_accounts_file)
             self.use_default_creds = False
@@ -71,7 +71,8 @@
     def _create_hash_file(self, hash_string):
         path = os.path.join(os.path.join(self.accounts_dir, hash_string))
         if not os.path.isfile(path):
-            open(path, 'w').close()
+            with open(path, 'w') as fd:
+                fd.write(self.name)
             return True
         return False
 
@@ -82,11 +83,18 @@
             # Create File from first hash (since none are in use)
             self._create_hash_file(hashes[0])
             return hashes[0]
+        names = []
         for _hash in hashes:
             res = self._create_hash_file(_hash)
             if res:
                 return _hash
-        msg = 'Insufficient number of users provided'
+            else:
+                path = os.path.join(os.path.join(self.accounts_dir,
+                                                 _hash))
+                with open(path, 'r') as fd:
+                    names.append(fd.read())
+        msg = ('Insufficient number of users provided. %s have allocated all '
+               'the credentials for this allocation request' % ','.join(names))
         raise exceptions.InvalidConfiguration(msg)
 
     def _get_creds(self):
@@ -101,7 +109,7 @@
         hash_path = os.path.join(self.accounts_dir, hash_string)
         if not os.path.isfile(hash_path):
             LOG.warning('Expected an account lock file %s to remove, but '
-                        'one did not exist')
+                        'one did not exist' % hash_path)
         else:
             os.remove(hash_path)
             if not os.listdir(self.accounts_dir):
@@ -109,9 +117,9 @@
 
     def get_hash(self, creds):
         for _hash in self.hash_dict:
-            # Comparing on the attributes that are expected in the YAML
+            # Comparing on the attributes that were read from the YAML
             if all([getattr(creds, k) == self.hash_dict[_hash][k] for k in
-                    creds.CONF_ATTRIBUTES]):
+                    creds.get_init_attributes()]):
                 return _hash
         raise AttributeError('Invalid credentials %s' % creds)
 
@@ -123,7 +131,7 @@
         if self.isolated_creds.get('primary'):
             return self.isolated_creds.get('primary')
         creds = self._get_creds()
-        primary_credential = auth.get_credentials(**creds)
+        primary_credential = cred_provider.get_credentials(**creds)
         self.isolated_creds['primary'] = primary_credential
         return primary_credential
 
@@ -131,7 +139,7 @@
         if self.isolated_creds.get('alt'):
             return self.isolated_creds.get('alt')
         creds = self._get_creds()
-        alt_credential = auth.get_credentials(**creds)
+        alt_credential = cred_provider.get_credentials(**creds)
         self.isolated_creds['alt'] = alt_credential
         return alt_credential
 
@@ -189,9 +197,10 @@
             return self.isolated_creds.get('primary')
         if not self.use_default_creds:
             creds = self.get_creds(0)
-            primary_credential = auth.get_credentials(**creds)
+            primary_credential = cred_provider.get_credentials(**creds)
         else:
-            primary_credential = auth.get_default_credentials('user')
+            primary_credential = cred_provider.get_configured_credentials(
+                'user')
         self.isolated_creds['primary'] = primary_credential
         return primary_credential
 
@@ -200,9 +209,10 @@
             return self.isolated_creds.get('alt')
         if not self.use_default_creds:
             creds = self.get_creds(1)
-            alt_credential = auth.get_credentials(**creds)
+            alt_credential = cred_provider.get_credentials(**creds)
         else:
-            alt_credential = auth.get_default_credentials('alt_user')
+            alt_credential = cred_provider.get_configured_credentials(
+                'alt_user')
         self.isolated_creds['alt'] = alt_credential
         return alt_credential
 
@@ -210,4 +220,5 @@
         self.isolated_creds = {}
 
     def get_admin_creds(self):
-        return auth.get_default_credentials("identity_admin", fill_in=False)
+        return cred_provider.get_configured_credentials(
+            "identity_admin", fill_in=False)
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index c5be0c0..033410e 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -16,17 +16,78 @@
 
 import six
 
+from tempest import auth
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 
 CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
+# Type of credentials available from configuration
+CREDENTIAL_TYPES = {
+    'identity_admin': ('identity', 'admin'),
+    'user': ('identity', None),
+    'alt_user': ('identity', 'alt')
+}
+
+
+# Read credentials from configuration, builds a Credentials object
+# based on the specified or configured version
+def get_configured_credentials(credential_type, fill_in=True,
+                               identity_version=None):
+    identity_version = identity_version or CONF.identity.auth_version
+    if identity_version not in ('v2', 'v3'):
+        raise exceptions.InvalidConfiguration(
+            'Unsupported auth version: %s' % identity_version)
+    if credential_type not in CREDENTIAL_TYPES:
+        raise exceptions.InvalidCredentials()
+    conf_attributes = ['username', 'password', 'tenant_name']
+    if identity_version == 'v3':
+        conf_attributes.append('domain_name')
+    # Read the parts of credentials from config
+    params = {}
+    section, prefix = CREDENTIAL_TYPES[credential_type]
+    for attr in conf_attributes:
+        _section = getattr(CONF, section)
+        if prefix is None:
+            params[attr] = getattr(_section, attr)
+        else:
+            params[attr] = getattr(_section, prefix + "_" + attr)
+    # Build and validate credentials. We are reading configured credentials,
+    # so validate them even if fill_in is False
+    credentials = get_credentials(fill_in=fill_in, **params)
+    if not fill_in:
+        if not credentials.is_valid():
+            msg = ("The %s credentials are incorrectly set in the config file."
+                   " Double check that all required values are assigned" %
+                   credential_type)
+            raise exceptions.InvalidConfiguration(msg)
+    return credentials
+
+
+# Wrapper around auth.get_credentials to use the configured identity version
+# is none is specified
+def get_credentials(fill_in=True, identity_version=None, **kwargs):
+    identity_version = identity_version or CONF.identity.auth_version
+    # In case of "v3" add the domain from config if not specified
+    if identity_version == 'v3':
+        domain_fields = set(x for x in auth.KeystoneV3Credentials.ATTRIBUTES
+                            if 'domain' in x)
+        if not domain_fields.intersection(kwargs.keys()):
+            kwargs['user_domain_name'] = CONF.identity.admin_domain_name
+        auth_url = CONF.identity.uri_v3
+    else:
+        auth_url = CONF.identity.uri
+    return auth.get_credentials(auth_url,
+                                fill_in=fill_in,
+                                identity_version=identity_version,
+                                **kwargs)
+
 
 @six.add_metaclass(abc.ABCMeta)
 class CredentialProvider(object):
-    def __init__(self, name, interface='json', password='pass',
-                 network_resources=None):
+    def __init__(self, name, password='pass', network_resources=None):
         self.name = name
 
     @abc.abstractmethod
diff --git a/tempest/common/credentials.py b/tempest/common/credentials.py
index 08b592f..40761c8 100644
--- a/tempest/common/credentials.py
+++ b/tempest/common/credentials.py
@@ -12,8 +12,10 @@
 #    limitations under the License.
 
 from tempest.common import accounts
+from tempest.common import cred_provider
 from tempest.common import isolated_creds
 from tempest import config
+from tempest import exceptions
 
 CONF = config.CONF
 
@@ -37,3 +39,31 @@
             return accounts.Accounts(name=name)
         else:
             return accounts.NotLockingAccounts(name=name)
+
+
+# We want a helper function here to check and see if admin credentials
+# are available so we can do a single call from skip_checks if admin
+# creds area vailable.
+def is_admin_available():
+    is_admin = True
+    # In the case of a pre-provisioned account, if even if creds were
+    # configured, the admin credentials won't be available
+    if (CONF.auth.locking_credentials_provider and
+        not CONF.auth.allow_tenant_isolation):
+        is_admin = False
+    else:
+        try:
+            cred_provider.get_configured_credentials('identity_admin')
+        # NOTE(mtreinish) This should never be caught because of the if above.
+        # NotImplementedError is only raised if admin credentials are requested
+        # and the locking test accounts cred provider is being used.
+        except NotImplementedError:
+            is_admin = False
+        # NOTE(mtreinish): This will be raised by the non-locking accounts
+        # provider if there aren't admin credentials provided in the config
+        # file. This exception originates from the auth call to get configured
+        # credentials
+        except exceptions.InvalidConfiguration:
+            is_admin = False
+
+    return is_admin
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index a663931..3eed689 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -13,8 +13,8 @@
 #    under the License.
 
 import netaddr
+from tempest_lib import exceptions as lib_exc
 
-from tempest import auth
 from tempest import clients
 from tempest.common import cred_provider
 from tempest.common.utils import data_utils
@@ -28,15 +28,12 @@
 
 class IsolatedCreds(cred_provider.CredentialProvider):
 
-    def __init__(self, name, interface='json', password='pass',
-                 network_resources=None):
-        super(IsolatedCreds, self).__init__(name, interface, password,
-                                            network_resources)
+    def __init__(self, name, password='pass', network_resources=None):
+        super(IsolatedCreds, self).__init__(name, password, network_resources)
         self.network_resources = network_resources
         self.isolated_creds = {}
         self.isolated_net_resources = {}
         self.ports = []
-        self.interface = interface
         self.password = password
         self.identity_admin_client, self.network_admin_client = (
             self._get_admin_clients())
@@ -48,7 +45,7 @@
             identity
             network
         """
-        os = clients.AdminManager(interface=self.interface)
+        os = clients.AdminManager()
         return os.identity_client, os.network_client
 
     def _create_tenant(self, name, description):
@@ -81,7 +78,7 @@
             role = next(r for r in roles if r['name'] == role_name)
         except StopIteration:
             msg = 'No "%s" role found' % role_name
-            raise exceptions.NotFound(msg)
+            raise lib_exc.NotFound(msg)
         self.identity_admin_client.assign_user_role(tenant['id'], user['id'],
                                                     role['id'])
 
@@ -129,7 +126,7 @@
         return self._get_credentials(user, tenant)
 
     def _get_credentials(self, user, tenant):
-        return auth.get_credentials(
+        return cred_provider.get_credentials(
             username=user['name'], user_id=user['id'],
             tenant_name=tenant['name'], tenant_id=tenant['id'],
             password=self.password)
@@ -201,7 +198,7 @@
                                       tenant_id=tenant_id,
                                       ip_version=4)
                 break
-            except exceptions.BadRequest as e:
+            except lib_exc.BadRequest as e:
                 if 'overlaps with another subnet' not in str(e):
                     raise
         else:
@@ -282,7 +279,7 @@
         net_client = self.network_admin_client
         try:
             net_client.delete_router(router_id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             LOG.warn('router with name: %s not found for delete' %
                      router_name)
 
@@ -290,7 +287,7 @@
         net_client = self.network_admin_client
         try:
             net_client.delete_subnet(subnet_id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             LOG.warn('subnet with name: %s not found for delete' %
                      subnet_name)
 
@@ -298,7 +295,7 @@
         net_client = self.network_admin_client
         try:
             net_client.delete_network(network_id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             LOG.warn('network with name: %s not found for delete' %
                      network_name)
 
@@ -310,7 +307,7 @@
         for secgroup in secgroups_to_delete:
             try:
                 net_client.delete_security_group(secgroup['id'])
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 LOG.warn('Security group %s, id %s not found for clean-up' %
                          (secgroup['name'], secgroup['id']))
 
@@ -326,7 +323,7 @@
                 try:
                     net_client.remove_router_interface_with_subnet_id(
                         router['id'], subnet['id'])
-                except exceptions.NotFound:
+                except lib_exc.NotFound:
                     LOG.warn('router with name: %s not found for delete' %
                              router['name'])
                 self._clear_isolated_router(router['id'], router['name'])
@@ -336,6 +333,7 @@
             if (not self.network_resources or
                 self.network_resources.get('network')):
                 self._clear_isolated_network(network['id'], network['name'])
+        self.isolated_net_resources = {}
 
     def clear_isolated_creds(self):
         if not self.isolated_creds:
@@ -344,14 +342,15 @@
         for creds in self.isolated_creds.itervalues():
             try:
                 self._delete_user(creds.user_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 LOG.warn("user with name: %s not found for delete" %
                          creds.username)
             try:
                 self._delete_tenant(creds.tenant_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 LOG.warn("tenant with name: %s not found for delete" %
                          creds.tenant_name)
+        self.isolated_creds = {}
 
     def is_multi_user(self):
         return True
diff --git a/tempest/common/service_client.py b/tempest/common/service_client.py
index 69e25e2..fde05af 100644
--- a/tempest/common/service_client.py
+++ b/tempest/common/service_client.py
@@ -16,7 +16,6 @@
 from tempest_lib import exceptions as lib_exceptions
 
 from tempest import config
-from tempest import exceptions
 
 CONF = config.CONF
 
@@ -59,22 +58,12 @@
                 method, url,
                 extra_headers=extra_headers,
                 headers=headers, body=body)
-        except lib_exceptions.Unauthorized as ex:
-            raise exceptions.Unauthorized(ex)
-        except lib_exceptions.NotFound as ex:
-            raise exceptions.NotFound(ex)
-        except lib_exceptions.BadRequest as ex:
-            raise exceptions.BadRequest(ex)
-        except lib_exceptions.Conflict as ex:
-            raise exceptions.Conflict(ex)
-        except lib_exceptions.OverLimit as ex:
-            raise exceptions.OverLimit(ex)
         # TODO(oomichi): This is just a workaround for failing gate tests
         # when separating Forbidden from Unauthorized in tempest-lib.
         # We will need to remove this translation and replace negative tests
         # with lib_exceptions.Forbidden in the future.
         except lib_exceptions.Forbidden as ex:
-            raise exceptions.Unauthorized(ex)
+            raise lib_exceptions.Unauthorized(ex)
 
 
 class ResponseBody(dict):
@@ -90,10 +79,22 @@
         self.response = response
 
     def __str__(self):
-        body = super.__str__(self)
+        body = super(ResponseBody, self).__str__()
         return "response: %s\nBody: %s" % (self.response, body)
 
 
+class ResponseBodyData(object):
+    """Class that wraps an http response and string data into a single value.
+    """
+
+    def __init__(self, response, data):
+        self.response = response
+        self.data = data
+
+    def __str__(self):
+        return "response: %s\nBody: %s" % (self.response, self.data)
+
+
 class ResponseBodyList(list):
     """Class that wraps an http response and list body into a single value.
 
@@ -107,5 +108,5 @@
         self.response = response
 
     def __str__(self):
-        body = super.__str__(self)
+        body = super(ResponseBodyList, self).__str__()
         return "response: %s\nBody: %s" % (self.response, body)
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 6e61c55..1f1414f 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -23,7 +23,7 @@
 CONF = config.CONF
 
 
-class RemoteClient():
+class RemoteClient(object):
 
     # NOTE(afazekas): It should always get an address instead of server
     def __init__(self, server, username, password=None, pkey=None):
@@ -163,4 +163,4 @@
                                                   % dhcp_client)
         if dhcp_client == 'udhcpc' and not fixed_ip:
             raise ValueError("need to set 'fixed_ip' for udhcpc client")
-        return getattr(self, '_renew_lease_' + dhcp_client)(fixed_ip=fixed_ip)
\ No newline at end of file
+        return getattr(self, '_renew_lease_' + dhcp_client)(fixed_ip=fixed_ip)
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index c77c81e..9b11676 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -32,7 +32,7 @@
 
     # NOTE(afazekas): UNKNOWN status possible on ERROR
     # or in a very early stage.
-    resp, body = client.get_server(server_id)
+    body = client.get_server(server_id)
     old_status = server_status = body['status']
     old_task_state = task_state = _get_task_state(body)
     start_time = int(time.time())
@@ -59,7 +59,7 @@
                 return
 
         time.sleep(client.build_interval)
-        resp, body = client.get_server(server_id)
+        body = client.get_server(server_id)
         server_status = body['status']
         task_state = _get_task_state(body)
         if (server_status != old_status) or (task_state != old_task_state):
diff --git a/tempest/config.py b/tempest/config.py
index c60434a..a66aa9b 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -40,7 +40,7 @@
                help="Path to the yaml file that contains the list of "
                     "credentials to use for running tests"),
     cfg.BoolOpt('allow_tenant_isolation',
-                default=False,
+                default=True,
                 help="Allows test cases to create/destroy tenants and "
                      "users. This option requires that OpenStack Identity "
                      "API admin credentials are known. If false, isolated "
@@ -455,7 +455,13 @@
     cfg.ListOpt('dns_servers',
                 default=["8.8.8.8", "8.8.4.4"],
                 help="List of dns servers which should be used"
-                     " for subnet creation")
+                     " for subnet creation"),
+    cfg.StrOpt('port_vnic_type',
+               choices=[None, 'normal', 'direct', 'macvtap'],
+               help="vnic_type to use when Launching instances"
+                    " with pre-configured ports."
+                    " Supported ports are:"
+                    " ['normal','direct','macvtap']"),
 ]
 
 network_feature_group = cfg.OptGroup(name='network-feature-enabled',
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 7ddeeff..09f7016 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -63,6 +63,10 @@
     message = "Invalid service tag"
 
 
+class InvalidIdentityVersion(TempestException):
+    message = "Invalid version %(identity_version) of the identity service"
+
+
 class TimeoutException(TempestException):
     message = "Request timed out"
 
@@ -151,26 +155,10 @@
     message = "The success code is different than the expected one"
 
 
-class NotFound(RestClientException):
-    message = "Object not found"
-
-
-class Unauthorized(RestClientException):
-    message = 'Unauthorized'
-
-
 class BadRequest(RestClientException):
     message = "Bad request"
 
 
-class OverLimit(RestClientException):
-    message = "Quota exceeded"
-
-
-class Conflict(RestClientException):
-    message = "An object with that identifier already exists"
-
-
 class ResponseWithNonEmptyBody(RFCViolation):
     message = ("RFC Violation! Response with %(status)d HTTP Status Code "
                "MUST NOT have a body")
diff --git a/tempest/manager.py b/tempest/manager.py
index 538b619..a256f25 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest import auth
+from tempest.common import cred_provider
 from tempest import config
 from tempest import exceptions
 
@@ -39,29 +40,35 @@
         """
         self.auth_version = CONF.identity.auth_version
         if credentials is None:
-            self.credentials = auth.get_default_credentials('user')
+            self.credentials = cred_provider.get_configured_credentials('user')
         else:
             self.credentials = credentials
         # Check if passed or default credentials are valid
         if not self.credentials.is_valid():
             raise exceptions.InvalidCredentials()
         # Creates an auth provider for the credentials
-        self.auth_provider = self.get_auth_provider(self.credentials)
+        self.auth_provider = get_auth_provider(self.credentials)
         # FIXME(andreaf) unused
         self.client_attr_names = []
 
-    @classmethod
-    def get_auth_provider_class(cls, credentials):
-        if isinstance(credentials, auth.KeystoneV3Credentials):
-            return auth.KeystoneV3AuthProvider
-        else:
-            return auth.KeystoneV2AuthProvider
 
-    def get_auth_provider(self, credentials):
-        if credentials is None:
-            raise exceptions.InvalidCredentials(
-                'Credentials must be specified')
-        auth_provider_class = self.get_auth_provider_class(credentials)
-        return auth_provider_class(
-            interface=getattr(self, 'interface', None),
-            credentials=credentials)
+def get_auth_provider_class(credentials):
+    if isinstance(credentials, auth.KeystoneV3Credentials):
+        return auth.KeystoneV3AuthProvider, CONF.identity.uri_v3
+    else:
+        return auth.KeystoneV2AuthProvider, CONF.identity.uri
+
+
+def get_auth_provider(credentials):
+    default_params = {
+        'disable_ssl_certificate_validation':
+            CONF.identity.disable_ssl_certificate_validation,
+        'ca_certs': CONF.identity.ca_certificates_file,
+        'trace_requests': CONF.debug.trace_requests
+    }
+    if credentials is None:
+        raise exceptions.InvalidCredentials(
+            'Credentials must be specified')
+    auth_provider_class, auth_url = get_auth_provider_class(
+        credentials)
+    return auth_provider_class(credentials, auth_url, **default_params)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index b1f5cce..968c8ca 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -19,9 +19,10 @@
 
 import netaddr
 import six
+from tempest_lib import exceptions as lib_exc
 
-from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common import credentials
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux import remote_client
@@ -110,7 +111,7 @@
             # Tempest clients return dicts, so there is no common delete
             # method available. Using a callable instead
             delete_thing(*args, **kwargs)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             # If the resource is already missing, mission accomplished.
             pass
 
@@ -186,8 +187,8 @@
 
         LOG.debug("Creating a server (name: %s, image: %s, flavor: %s)",
                   name, image, flavor)
-        _, server = self.servers_client.create_server(name, image, flavor,
-                                                      **create_kwargs)
+        server = self.servers_client.create_server(name, image, flavor,
+                                                   **create_kwargs)
         if wait_on_delete:
             self.addCleanup(self.servers_client.wait_for_server_termination,
                             server['id'])
@@ -202,7 +203,7 @@
         # The instance retrieved on creation is missing network
         # details, necessitating retrieval after it becomes active to
         # ensure correct details.
-        _, server = self.servers_client.get_server(server['id'])
+        server = self.servers_client.get_server(server['id'])
         self.assertEqual(server['name'], name)
         return server
 
@@ -378,13 +379,13 @@
             LOG.debug('Console output not supported, cannot log')
             return
         if not servers:
-            _, servers = self.servers_client.list_servers()
+            servers = self.servers_client.list_servers()
             servers = servers['servers']
         for server in servers:
             console_output = self.servers_client.get_console_output(
-                server['id'], length=None)
-            LOG.debug('Console output for %s\nhead=%s\nbody=\n%s',
-                      server['id'], console_output[0], console_output[1])
+                server['id'], length=None).data
+            LOG.debug('Console output for %s\nbody=\n%s',
+                      server['id'], console_output)
 
     def _log_net_info(self, exc):
         # network debug is called as part of ssh init
@@ -417,7 +418,7 @@
     def nova_volume_attach(self):
         # TODO(andreaf) Device should be here CONF.compute.volume_device_name
         volume = self.servers_client.attach_volume(
-            self.server['id'], self.volume['id'], '/dev/vdb')[1]
+            self.server['id'], self.volume['id'], '/dev/vdb')
         self.assertEqual(self.volume['id'], volume['id'])
         self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
         # Refresh the volume after the attachment
@@ -512,7 +513,7 @@
         Nova clients
         """
 
-        _, floating_ip = self.floating_ips_client.create_floating_ip(pool_name)
+        floating_ip = self.floating_ips_client.create_floating_ip(pool_name)
         self.addCleanup(self.delete_wrapper,
                         self.floating_ips_client.delete_floating_ip,
                         floating_ip['id'])
@@ -628,7 +629,7 @@
             try:
                 result = client.create_subnet(**subnet)
                 break
-            except exceptions.Conflict as e:
+            except lib_exc.Conflict as e:
                 is_overlapping_cidr = 'overlaps with another subnet' in str(e)
                 if not is_overlapping_cidr:
                     raise
@@ -639,14 +640,15 @@
         self.addCleanup(self.delete_wrapper, subnet.delete)
         return subnet
 
-    def _create_port(self, network, client=None, namestart='port-quotatest'):
+    def _create_port(self, network_id, client=None, namestart='port-quotatest',
+                     **kwargs):
         if not client:
             client = self.network_client
         name = data_utils.rand_name(namestart)
         result = client.create_port(
             name=name,
-            network_id=network.id,
-            tenant_id=network.tenant_id)
+            network_id=network_id,
+            **kwargs)
         self.assertIsNotNone(result, 'Unable to allocate port')
         port = net_resources.DeletablePort(client=client,
                                            **result['port'])
@@ -907,6 +909,11 @@
             dict(
                 # ping
                 protocol='icmp',
+            ),
+            dict(
+                # ipv6-icmp for ping6
+                protocol='icmp',
+                ethertype='IPv6',
             )
         ]
         for ruleset in rulesets:
@@ -915,7 +922,7 @@
                 try:
                     sg_rule = self._create_security_group_rule(
                         client=client, secgroup=secgroup, **ruleset)
-                except exceptions.Conflict as ex:
+                except lib_exc.Conflict as ex:
                     # if rule already exist - skip rule and continue
                     msg = 'Security group rule already exists'
                     if msg not in ex._error_string:
@@ -1047,6 +1054,66 @@
             subnet.add_to_router(router.id)
         return network, subnet, router
 
+    def create_server(self, name=None, image=None, flavor=None,
+                      wait_on_boot=True, wait_on_delete=True,
+                      create_kwargs=None):
+        vnic_type = CONF.network.port_vnic_type
+
+        # If vnic_type is configured create port for
+        # every network
+        if vnic_type:
+            ports = []
+            networks = []
+            create_port_body = {'binding:vnic_type': vnic_type,
+                                'namestart': 'port-smoke'}
+            if create_kwargs:
+                net_client = create_kwargs.get("network_client",
+                                               self.network_client)
+
+                # Convert security group names to security group ids
+                # to pass to create_port
+                if create_kwargs.get('security_groups'):
+                    security_groups = net_client.list_security_groups().get(
+                        'security_groups')
+                    sec_dict = dict([(s['name'], s['id'])
+                                    for s in security_groups])
+
+                    sec_groups_names = [s['name'] for s in create_kwargs[
+                        'security_groups']]
+                    security_groups_ids = [sec_dict[s]
+                                           for s in sec_groups_names]
+
+                    if security_groups_ids:
+                        create_port_body[
+                            'security_groups'] = security_groups_ids
+                networks = create_kwargs.get('networks')
+            else:
+                net_client = self.network_client
+            # If there are no networks passed to us we look up
+            # for the tenant's private networks and create a port
+            # if there is only one private network. The same behaviour
+            # as we would expect when passing the call to the clients
+            # with no networks
+            if not networks:
+                networks = net_client.list_networks(filters={
+                    'router:external': False})
+                self.assertEqual(1, len(networks),
+                                 "There is more than one"
+                                 " network for the tenant")
+            for net in networks:
+                net_id = net['uuid']
+                port = self._create_port(network_id=net_id,
+                                         client=net_client,
+                                         **create_port_body)
+                ports.append({'port': port.id})
+            if ports:
+                create_kwargs['networks'] = ports
+
+        return super(NetworkScenarioTest, self).create_server(
+            name=name, image=image, flavor=flavor,
+            wait_on_boot=wait_on_boot, wait_on_delete=wait_on_delete,
+            create_kwargs=create_kwargs)
+
 
 # power/provision states as of icehouse
 class BaremetalPowerStates(object):
@@ -1124,7 +1191,7 @@
             node = None
             try:
                 node = self.get_node(instance_id=instance_id)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
             return node is not None
 
@@ -1187,7 +1254,7 @@
         self.servers_client.wait_for_server_status(self.instance['id'],
                                                    'ACTIVE')
         self.node = self.get_node(instance_id=self.instance['id'])
-        _, self.instance = self.servers_client.get_server(self.instance['id'])
+        self.instance = self.servers_client.get_server(self.instance['id'])
 
     def terminate_instance(self):
         self.servers_client.delete_server(self.instance['id'])
@@ -1259,8 +1326,9 @@
 
     @classmethod
     def credentials(cls):
-        admin_creds = auth.get_default_credentials('identity_admin')
-        creds = auth.get_default_credentials('user')
+        admin_creds = cred_provider.get_configured_credentials(
+            'identity_admin')
+        creds = cred_provider.get_configured_credentials('user')
         admin_creds.tenant_name = creds.tenant_name
         return admin_creds
 
diff --git a/tempest/scenario/orchestration/test_server_cfn_init.py b/tempest/scenario/orchestration/test_server_cfn_init.py
index 6052e0b..53f7843 100644
--- a/tempest/scenario/orchestration/test_server_cfn_init.py
+++ b/tempest/scenario/orchestration/test_server_cfn_init.py
@@ -81,7 +81,7 @@
 
         server_resource = self.client.get_resource(sid, 'SmokeServer')
         server_id = server_resource['physical_resource_id']
-        _, server = self.servers_client.get_server(server_id)
+        server = self.servers_client.get_server(server_id)
         server_ip =\
             server['addresses'][CONF.compute.network_for_ssh][0]['addr']
 
@@ -126,6 +126,7 @@
 
     @test.attr(type='slow')
     @decorators.skip_because(bug='1374175')
+    @test.idempotent_id('2be9be1f-8106-4ee2-a7ba-444c7557db2f')
     @test.services('orchestration', 'compute')
     def test_server_cfn_init(self):
         self.assign_keypair()
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 469ac4a..ff450de 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -96,6 +96,7 @@
         self.assertEqual(aggregate['availability_zone'], availability_zone)
         return aggregate
 
+    @test.idempotent_id('cb2b4c4f-0c7c-4164-bdde-6285b302a081')
     @test.services('compute')
     def test_aggregate_basic_ops(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index fd4449a..434d3df 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -104,7 +104,7 @@
         return int(ephemeral)
 
     def add_floating_ip(self):
-        _, floating_ip = self.floating_ips_client.create_floating_ip()
+        floating_ip = self.floating_ips_client.create_floating_ip()
         self.floating_ips_client.associate_floating_ip_to_server(
             floating_ip['ip'], self.instance['id'])
         return floating_ip['ip']
@@ -117,6 +117,7 @@
             self.assertEqual(n_port['device_id'], self.instance['id'])
             self.assertEqual(n_port['mac_address'], port['address'])
 
+    @test.idempotent_id('549173a5-38ec-42bb-b0e2-c8b9f4a08943')
     @test.services('baremetal', 'compute', 'image', 'network')
     def test_baremetal_server_ops(self):
         test_filename = '/mnt/rebuild_test.txt'
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index 35f6689..4c4dc94 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -65,7 +65,7 @@
 
     def check_login_page(self):
         response = urllib2.urlopen(CONF.dashboard.dashboard_url)
-        self.assertIn("Log In", response.read())
+        self.assertIn("id_username", response.read())
 
     def user_login(self, username, password):
         self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
@@ -89,6 +89,7 @@
         response = self.opener.open(CONF.dashboard.dashboard_url)
         self.assertIn('Overview', response.read())
 
+    @test.idempotent_id('4f8851b1-0e69-482b-b63b-84c6e76f6c80')
     @test.services('dashboard')
     def test_basic_scenario(self):
         creds = self.credentials()
diff --git a/tempest/scenario/test_encrypted_cinder_volumes.py b/tempest/scenario/test_encrypted_cinder_volumes.py
index ac2ef8a..eed3d0b 100644
--- a/tempest/scenario/test_encrypted_cinder_volumes.py
+++ b/tempest/scenario/test_encrypted_cinder_volumes.py
@@ -48,6 +48,7 @@
         self.nova_volume_attach()
         self.nova_volume_detach()
 
+    @test.idempotent_id('79165fb4-5534-4b9d-8429-97ccffb8f86e')
     @test.services('compute', 'volume', 'image')
     def test_encrypted_cinder_volumes_luks(self):
         self.launch_instance()
@@ -55,9 +56,10 @@
                                      'luks.LuksEncryptor')
         self.attach_detach_volume()
 
+    @test.idempotent_id('cbc752ed-b716-4717-910f-956cce965722')
     @test.services('compute', 'volume', 'image')
     def test_encrypted_cinder_volumes_cryptsetup(self):
         self.launch_instance()
         self.create_encrypted_volume('nova.volume.encryptors.'
                                      'cryptsetup.CryptsetupEncryptor')
-        self.attach_detach_volume()
\ No newline at end of file
+        self.attach_detach_volume()
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index 99a2023..af2b4cb 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -12,7 +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.
-from tempest_lib import exceptions
+from tempest_lib import exceptions as lib_exc
 
 from tempest.common.utils import data_utils
 from tempest import config
@@ -54,7 +54,7 @@
             function, args, kwargs = cls._cleanup_resources.pop(-1)
             try:
                 function(*args, **kwargs)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
         super(TestLargeOpsScenario, cls).resource_cleanup()
 
@@ -87,7 +87,7 @@
             security_groups=[{'name': secgroup['name']}])
         # needed because of bug 1199788
         params = {'name': name}
-        _, server_list = self.servers_client.list_servers(params)
+        server_list = self.servers_client.list_servers(params)
         self.servers = server_list['servers']
         for server in self.servers:
             # after deleting all servers - wait for all servers to clear
@@ -104,14 +104,17 @@
         self.glance_image_create()
         self.nova_boot()
 
+    @test.idempotent_id('14ba0e78-2ed9-4d17-9659-a48f4756ecb3')
     @test.services('compute', 'image')
     def test_large_ops_scenario_1(self):
         self._large_ops_scenario()
 
+    @test.idempotent_id('b9b79b88-32aa-42db-8f8f-dcc8f4b4ccfe')
     @test.services('compute', 'image')
     def test_large_ops_scenario_2(self):
         self._large_ops_scenario()
 
+    @test.idempotent_id('3aab7e82-2de3-419a-9da1-9f3a070668fb')
     @test.services('compute', 'image')
     def test_large_ops_scenario_3(self):
         self._large_ops_scenario()
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 57a5406..6f6036f 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -161,7 +161,7 @@
         """
         for server_id, ip in self.server_ips.iteritems():
             private_key = self.servers_keypairs[server_id]['private_key']
-            server_name = self.servers_client.get_server(server_id)[1]['name']
+            server_name = self.servers_client.get_server(server_id)['name']
             username = config.scenario.ssh_user
             ssh_client = self.get_remote_client(
                 server_or_ip=ip,
@@ -185,7 +185,7 @@
 
             # Start netcat
             start_server = ('while true; do '
-                            'sudo nc -l -p %(port)s -e sh /tmp/%(script)s; '
+                            'sudo nc -ll -p %(port)s -e sh /tmp/%(script)s; '
                             'done &')
             cmd = start_server % {'port': self.port1,
                                   'script': 'script1'}
@@ -309,6 +309,7 @@
         for member, counter in counters.iteritems():
             self.assertGreater(counter, 0, 'Member %s never balanced' % member)
 
+    @test.idempotent_id('c0c6f1ca-603b-4509-9c0f-2c63f0d838ee')
     @test.services('compute', 'network')
     def test_load_balancer_basic(self):
         self._create_server('server1')
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 5ea48e0..63f74c4 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -53,13 +53,13 @@
                                          create_kwargs=create_kwargs)
 
     def nova_list(self):
-        _, servers = self.servers_client.list_servers()
+        servers = self.servers_client.list_servers()
         # The list servers in the compute client is inconsistent...
         servers = servers['servers']
         self.assertIn(self.server['id'], [x['id'] for x in servers])
 
     def nova_show(self):
-        _, got_server = self.servers_client.get_server(self.server['id'])
+        got_server = self.servers_client.get_server(self.server['id'])
         self.assertThat(
             self.server, custom_matchers.MatchesDictExceptForKeys(
                 got_server, excluded_keys=['OS-EXT-AZ:availability_zone']))
@@ -78,7 +78,7 @@
     def nova_volume_attach(self):
         volume_device_path = '/dev/' + CONF.compute.volume_device_name
         volume = self.servers_client.attach_volume(
-            self.server['id'], self.volume['id'], volume_device_path)[1]
+            self.server['id'], self.volume['id'], volume_device_path)
         self.assertEqual(self.volume['id'], volume['id'])
         self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
         # Refresh the volume after the attachment
@@ -109,7 +109,7 @@
                         self.server['id'], secgroup['name'])
 
         def wait_for_secgroup_add():
-            _, body = self.servers_client.get_server(self.server['id'])
+            body = self.servers_client.get_server(self.server['id'])
             return {'name': secgroup['name']} in body['security_groups']
 
         if not test.call_until_true(wait_for_secgroup_add,
@@ -119,6 +119,7 @@
                    '%s' % (secgroup['id'], self.server['id']))
             raise exceptions.TimeoutException(msg)
 
+    @test.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
     @test.services('compute', 'volume', 'image', 'network')
     def test_minimum_basic_scenario(self):
         self.glance_image_create()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 598c6d1..6e82a41 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -94,6 +94,7 @@
         self._check_network_connectivity()
 
     @decorators.skip_because(bug="1323658")
+    @test.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
     @test.services('compute', 'network')
     def test_server_connectivity_stop_start(self):
         self._setup_network_and_servers()
@@ -104,12 +105,14 @@
         self.servers_client.start(self.server['id'])
         self._wait_server_status_and_check_network_connectivity()
 
+    @test.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
     @test.services('compute', 'network')
     def test_server_connectivity_reboot(self):
         self._setup_network_and_servers()
         self.servers_client.reboot(self.server['id'], reboot_type='SOFT')
         self._wait_server_status_and_check_network_connectivity()
 
+    @test.idempotent_id('88a529c2-1daa-4c85-9aec-d541ba3eb699')
     @test.services('compute', 'network')
     def test_server_connectivity_rebuild(self):
         self._setup_network_and_servers()
@@ -118,6 +121,7 @@
                                     image_ref=image_ref_alt)
         self._wait_server_status_and_check_network_connectivity()
 
+    @test.idempotent_id('2b2642db-6568-4b35-b812-eceed3fa20ce')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.services('compute', 'network')
@@ -129,6 +133,7 @@
         self.servers_client.unpause_server(self.server['id'])
         self._wait_server_status_and_check_network_connectivity()
 
+    @test.idempotent_id('5cdf9499-541d-4923-804e-b9a60620a7f0')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.services('compute', 'network')
@@ -142,6 +147,7 @@
         self._wait_server_status_and_check_network_connectivity()
 
     @decorators.skip_because(bug="1323658")
+    @test.idempotent_id('719eb59d-2f42-4b66-b8b1-bb1254473967')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize is not available.')
     @test.services('compute', 'network')
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index fc174cd..4199b2c 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -16,7 +16,6 @@
 import collections
 import re
 
-from tempest_lib import decorators
 import testtools
 
 from tempest.common.utils import data_utils
@@ -230,7 +229,7 @@
         port_list = self._list_ports(device_id=server['id'])
         self.assertEqual(1, len(port_list))
         old_port = port_list[0]
-        _, interface = self.interface_client.create_interface(
+        interface = self.interface_client.create_interface(
             server=server['id'],
             network_id=self.new_net.id)
         self.addCleanup(self.network_client.wait_for_resource_deletion,
@@ -243,7 +242,7 @@
         def check_ports():
             self.new_port_list = [port for port in
                                   self._list_ports(device_id=server['id'])
-                                  if port != old_port]
+                                  if port['id'] != old_port['id']]
             return len(self.new_port_list) == 1
 
         if not test.call_until_true(check_ports, CONF.network.build_timeout,
@@ -329,6 +328,7 @@
                 raise
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
     @test.services('compute', 'network')
     def test_network_basic_ops(self):
         """
@@ -379,8 +379,12 @@
                                                msg="after re-associate "
                                                    "floating ip")
 
+    @test.idempotent_id('c5adff73-e961-41f1-b4a9-343614f18cfa')
     @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
                           'NIC hotplug not available')
+    @testtools.skipIf(CONF.network.port_vnic_type in ['direct', 'macvtap'],
+                      'NIC hotplug not supported for '
+                      'vnic_type direct or macvtap')
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_hotplug_nic(self):
@@ -398,6 +402,7 @@
         self._hotplug_server()
         self._check_network_internal_connectivity(network=self.new_net)
 
+    @test.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
     @testtools.skipIf(CONF.baremetal.driver_enabled,
                       'Router state cannot be altered on a shared baremetal '
                       'network')
@@ -429,24 +434,16 @@
             should_connect=True, msg="after updating "
             "admin_state_up of router to True")
 
-    def _check_dns_server(self, ssh_client, dns_servers):
-        servers = ssh_client.get_dns_servers()
-        self.assertEqual(set(dns_servers), set(servers),
-                         'Looking for servers: {trgt_serv}. '
-                         'Retrieved DNS nameservers: {act_serv} '
-                         'From host: {host}.'
-                         .format(host=ssh_client.ssh_client.host,
-                                 act_serv=servers,
-                                 trgt_serv=dns_servers))
-
-    @decorators.skip_because(bug="1412325")
+    @test.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
+    @testtools.skipIf(CONF.baremetal.driver_enabled,
+                      'network isolation not available for baremetal nodes')
     @testtools.skipUnless(CONF.scenario.dhcp_client,
                           "DHCP client is not available.")
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_subnet_details(self):
         """Tests that subnet's extra configuration details are affecting
-        the VMs
+        the VMs. This test relies on non-shared, isolated tenant networks.
 
          NOTE: Neutron subnets push data to servers via dhcp-agent, so any
          update in subnet requires server to actively renew its DHCP lease.
@@ -469,6 +466,13 @@
         # arbitrary ip addresses as nameservers, instead of parsing CONF
         initial_dns_server = '1.2.3.4'
         alt_dns_server = '9.8.7.6'
+
+        # renewal should be immediate.
+        # Timeouts are suggested by salvatore-orlando in
+        # https://bugs.launchpad.net/neutron/+bug/1412325/comments/3
+        renew_delay = CONF.network.build_interval
+        renew_timeout = CONF.network.build_timeout
+
         self._setup_network_and_servers(dns_nameservers=[initial_dns_server])
         self.check_public_network_connectivity(should_connect=True)
 
@@ -477,18 +481,44 @@
         private_key = self._get_server_key(server)
         ssh_client = self._ssh_to_server(ip_address, private_key)
 
-        self._check_dns_server(ssh_client, [initial_dns_server])
+        dns_servers = [initial_dns_server]
+        servers = ssh_client.get_dns_servers()
+        self.assertEqual(set(dns_servers), set(servers),
+                         'Looking for servers: {trgt_serv}. '
+                         'Retrieved DNS nameservers: {act_serv} '
+                         'From host: {host}.'
+                         .format(host=ssh_client.ssh_client.host,
+                                 act_serv=servers,
+                                 trgt_serv=dns_servers))
 
         self.subnet.update(dns_nameservers=[alt_dns_server])
         # asserts that Neutron DB has updated the nameservers
         self.assertEqual([alt_dns_server], self.subnet.dns_nameservers,
                          "Failed to update subnet's nameservers")
 
-        # server needs to renew its dhcp lease in order to get the new dns
-        # definitions from subnet
-        ssh_client.renew_lease(fixed_ip=floating_ip['fixed_ip_address'])
-        self._check_dns_server(ssh_client, [alt_dns_server])
+        def check_new_dns_server():
+            """Server needs to renew its dhcp lease in order to get the new dns
+            definitions from subnet
+            NOTE(amuller): we are renewing the lease as part of the retry
+            because Neutron updates dnsmasq asynchronously after the
+            subnet-update API call returns.
+            """
+            ssh_client.renew_lease(fixed_ip=floating_ip['fixed_ip_address'])
+            if ssh_client.get_dns_servers() != [alt_dns_server]:
+                LOG.debug("Failed to update DNS nameservers")
+                return False
+            return True
 
+        self.assertTrue(test.call_until_true(check_new_dns_server,
+                                             renew_timeout,
+                                             renew_delay),
+                        msg="DHCP renewal failed to fetch "
+                            "new DNS nameservers")
+
+    @test.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
+    @testtools.skipIf(CONF.baremetal.driver_enabled,
+                      'admin_state of instance ports cannot be altered '
+                      'for baremetal nodes')
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_update_instance_port_admin_state(self):
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index dc82217..d5d2d77 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.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 functools
 import netaddr
 from tempest import config
 from tempest.openstack.common import log as logging
@@ -118,14 +119,28 @@
         ssh1, srv1 = self.prepare_server()
         ssh2, srv2 = self.prepare_server()
 
+        def guest_has_address(ssh, addr):
+            return addr in ssh.get_ip_list()
+
+        srv1_v6_addr_assigned = functools.partial(
+            guest_has_address, ssh1, srv1['accessIPv6'])
+        srv2_v6_addr_assigned = functools.partial(
+            guest_has_address, ssh2, srv2['accessIPv6'])
+
         result = ssh1.get_ip_list()
         self.assertIn(srv1['accessIPv4'], result)
         # v6 should be configured since the image supports it
-        self.assertIn(srv1['accessIPv6'], result)
+        # It can take time for ipv6 automatic address to get assigned
+        self.assertTrue(
+            test.call_until_true(srv1_v6_addr_assigned,
+                                 CONF.compute.ping_timeout, 1))
         result = ssh2.get_ip_list()
         self.assertIn(srv2['accessIPv4'], result)
         # v6 should be configured since the image supports it
-        self.assertIn(srv2['accessIPv6'], result)
+        # It can take time for ipv6 automatic address to get assigned
+        self.assertTrue(
+            test.call_until_true(srv2_v6_addr_assigned,
+                                 CONF.compute.ping_timeout, 1))
         result = ssh1.ping_host(srv2['accessIPv4'])
         self.assertIn('0% packet loss', result)
         result = ssh2.ping_host(srv1['accessIPv4'])
@@ -142,10 +157,12 @@
         else:
             LOG.warning('Ping6 is not available, skipping')
 
+    @test.idempotent_id('2c92df61-29f0-4eaa-bee3-7c65bef62a43')
     @test.services('compute', 'network')
     def test_slaac_from_os(self):
         self._prepare_and_test(address6_mode='slaac')
 
+    @test.idempotent_id('d7e1f858-187c-45a6-89c9-bdafde619a9f')
     @test.services('compute', 'network')
     def test_dhcp6_stateless_from_os(self):
         self._prepare_and_test(address6_mode='dhcpv6-stateless')
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 83739fd..4fbadb0 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -76,6 +76,8 @@
            * test that traffic is blocked with default security group
            * test that traffic is enabled after updating port with new security
            group having appropriate rule
+        8. _test_multiple_security_groups: test multiple security groups can be
+           associated with the vm
 
     assumptions:
         1. alt_tenant/user existed and is different from primary_tenant/user
@@ -89,7 +91,7 @@
             its own router connected to the public network
     """
 
-    class TenantProperties():
+    class TenantProperties(object):
         """
         helper class to save tenant details
             id
@@ -238,7 +240,8 @@
             ],
             'key_name': tenant.keypair['name'],
             'security_groups': security_groups_names,
-            'tenant_id': tenant.creds.tenant_id
+            'tenant_id': tenant.creds.tenant_id,
+            'network_client': tenant.manager.network_client
         }
         server = self.create_server(name=name, create_kwargs=create_kwargs)
         self.assertEqual(
@@ -427,6 +430,7 @@
         self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
     @test.services('compute', 'network')
     def test_cross_tenant_traffic(self):
         if not self.isolated_creds.is_multi_tenant():
@@ -448,6 +452,7 @@
             raise
 
     @test.attr(type='smoke')
+    @test.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
     @test.services('compute', 'network')
     def test_in_tenant_traffic(self):
         try:
@@ -462,6 +467,7 @@
             raise
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
     @test.services('compute', 'network')
     def test_port_update_new_security_group(self):
         """
@@ -511,3 +517,38 @@
             for tenant in self.tenants.values():
                 self._log_console_output(servers=tenant.servers)
             raise
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
+    @test.services('compute', 'network')
+    def test_multiple_security_groups(self):
+        """
+        This test verifies multiple security groups and checks that rules
+        provided in the both the groups is applied onto VM
+        """
+        tenant = self.primary_tenant
+        ip = self._get_server_ip(tenant.access_point,
+                                 floating=self.floating_ip_access)
+        ssh_login = CONF.compute.image_ssh_user
+        private_key = tenant.keypair['private_key']
+        self.check_vm_connectivity(ip,
+                                   should_connect=False)
+        ruleset = dict(
+            protocol='icmp',
+            direction='ingress'
+        )
+        self._create_security_group_rule(
+            secgroup=tenant.security_groups['default'],
+            **ruleset
+        )
+        """
+        Vm now has 2 security groups one with ssh rule(
+        already added in setUp() method),and other with icmp rule
+        (added in the above step).The check_vm_connectivity tests
+        -that vm ping test is successful
+        -ssh to vm is successful
+        """
+        self.check_vm_connectivity(ip,
+                                   username=ssh_login,
+                                   private_key=private_key,
+                                   should_connect=True)
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index d10fcce..d0b595a 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -42,6 +42,7 @@
         cls.set_network_resources()
         super(TestServerAdvancedOps, cls).resource_setup()
 
+    @test.idempotent_id('e6c28180-7454-4b59-b188-0257af08a63b')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize is not available.')
     @test.services('compute')
@@ -62,6 +63,7 @@
         self.servers_client.wait_for_server_status(instance_id,
                                                    'ACTIVE')
 
+    @test.idempotent_id('949da7d5-72c8-4808-8802-e3d70df98e2c')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.services('compute')
@@ -74,19 +76,19 @@
         self.servers_client.suspend_server(instance_id)
         self.servers_client.wait_for_server_status(instance_id,
                                                    'SUSPENDED')
-        _, fetched_instance = self.servers_client.get_server(instance_id)
+        fetched_instance = self.servers_client.get_server(instance_id)
         LOG.debug("Resuming instance %s. Current status: %s",
                   instance_id, fetched_instance['status'])
         self.servers_client.resume_server(instance_id)
         self.servers_client.wait_for_server_status(instance_id,
                                                    'ACTIVE')
-        _, fetched_instance = self.servers_client.get_server(instance_id)
+        fetched_instance = self.servers_client.get_server(instance_id)
         LOG.debug("Suspending instance %s. Current status: %s",
                   instance_id, fetched_instance['status'])
         self.servers_client.suspend_server(instance_id)
         self.servers_client.wait_for_server_status(instance_id,
                                                    'SUSPENDED')
-        _, fetched_instance = self.servers_client.get_server(instance_id)
+        fetched_instance = self.servers_client.get_server(instance_id)
         LOG.debug("Resuming instance %s. Current status: %s",
                   instance_id, fetched_instance['status'])
         self.servers_client.resume_server(instance_id)
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 23743c5..b306b11 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -80,7 +80,7 @@
     def verify_ssh(self):
         if self.run_ssh:
             # Obtain a floating IP
-            _, floating_ip = self.floating_ips_client.create_floating_ip()
+            floating_ip = self.floating_ips_client.create_floating_ip()
             self.addCleanup(self.delete_wrapper,
                             self.floating_ips_client.delete_floating_ip,
                             floating_ip['id'])
@@ -93,6 +93,7 @@
                 username=self.image_utils.ssh_user(self.image_ref),
                 private_key=self.keypair['private_key'])
 
+    @test.idempotent_id('7fff3fb3-91d8-4fd0-bd7d-0204f1f180ba')
     @test.services('compute', 'network')
     def test_server_basicops(self):
         self.add_keypair()
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index 8882177..155ecbf 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -60,6 +60,7 @@
         self.servers_client.unshelve_server(server['id'])
         self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
 
+    @test.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.services('compute', 'network', 'image')
@@ -77,7 +78,7 @@
                                     create_kwargs=create_kwargs)
 
         if CONF.compute.use_floatingip_for_ssh:
-            _, floating_ip = self.floating_ips_client.create_floating_ip()
+            floating_ip = self.floating_ips_client.create_floating_ip()
             self.addCleanup(self.delete_wrapper,
                             self.floating_ips_client.delete_floating_ip,
                             floating_ip['id'])
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 5cb7c99..109d36b 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -57,6 +57,7 @@
         got_timestamp = ssh_client.exec_command('cat /tmp/timestamp')
         self.assertEqual(self.timestamp, got_timestamp)
 
+    @test.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.services('compute', 'network', 'image')
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 16f5283..bd3cefa 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -16,6 +16,7 @@
 import time
 
 from tempest_lib import decorators
+from tempest_lib import exceptions as lib_exc
 import testtools
 
 from tempest.common.utils import data_utils
@@ -23,6 +24,7 @@
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest.scenario import manager
+from tempest import test
 import tempest.test
 
 CONF = config.CONF
@@ -85,7 +87,7 @@
             try:
                 while self.snapshots_client.get_snapshot(snapshot['id']):
                     time.sleep(1)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 pass
         self.addCleanup(cleaner)
         self._wait_for_volume_status(volume, 'available')
@@ -102,7 +104,7 @@
 
     def _attach_volume(self, server, volume):
         # TODO(andreaf) we should use device from config instead if vdb
-        _, attached_volume = self.servers_client.attach_volume(
+        attached_volume = self.servers_client.attach_volume(
             server['id'], volume['id'], device='/dev/vdb')
         self.assertEqual(volume['id'], attached_volume['id'])
         self._wait_for_volume_status(attached_volume, 'in-use')
@@ -139,6 +141,7 @@
         self.assertEqual(self.timestamp, got_timestamp)
 
     @decorators.skip_because(bug="1205344")
+    @test.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @tempest.test.services('compute', 'network', 'volume', 'image')
diff --git a/tempest/scenario/test_swift_basic_ops.py b/tempest/scenario/test_swift_basic_ops.py
index 660b586..b622c4a 100644
--- a/tempest/scenario/test_swift_basic_ops.py
+++ b/tempest/scenario/test_swift_basic_ops.py
@@ -38,6 +38,7 @@
      * change ACL of the container and make sure it works successfully
     """
 
+    @test.idempotent_id('b920faf1-7b8a-4657-b9fe-9c4512bfb381')
     @test.services('object_storage')
     def test_swift_basic_ops(self):
         self.get_swift_stat()
@@ -51,6 +52,7 @@
                                               not_present_obj=[obj_name])
         self.delete_container(container_name)
 
+    @test.idempotent_id('916c7111-cb1f-44b2-816d-8f760e4ea910')
     @test.services('object_storage')
     def test_swift_acl_anonymous_download(self):
         """This test will cover below steps:
diff --git a/tempest/scenario/test_swift_telemetry_middleware.py b/tempest/scenario/test_swift_telemetry_middleware.py
index dce6023..8305641 100644
--- a/tempest/scenario/test_swift_telemetry_middleware.py
+++ b/tempest/scenario/test_swift_telemetry_middleware.py
@@ -1,7 +1,5 @@
-#
 # Copyright 2014 Red Hat
 #
-# Author: Chris Dent <chdent@redhat.com>
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -76,19 +74,22 @@
             LOG.debug('got samples %s', results)
 
             # Extract container info from samples.
-            containers = [sample['resource_metadata']['container']
-                          for sample in results
-                          if sample['resource_metadata']['container']
-                          != 'None']
-            # Extract object info from samples.
-            objects = [sample['resource_metadata']['object']
-                       for sample in results
-                       if sample['resource_metadata']['object'] != 'None']
+            containers, objects = [], []
+            for sample in results:
+                meta = sample['resource_metadata']
+                if meta.get('container') and meta['container'] != 'None':
+                    containers.append(meta['container'])
+                elif (meta.get('target') and
+                      meta['target']['metadata']['container'] != 'None'):
+                    containers.append(meta['target']['metadata']['container'])
 
-            return (containers
-                    and objects
-                    and container_name in containers
-                    and obj_name in objects)
+                if meta.get('object') and meta['object'] != 'None':
+                    objects.append(meta['object'])
+                elif (meta.get('target') and
+                      meta['target']['metadata']['object'] != 'None'):
+                    objects.append(meta['target']['metadata']['object'])
+
+            return (container_name in containers and obj_name in objects)
 
         self.assertTrue(test.call_until_true(_check_samples,
                                              NOTIFICATIONS_WAIT,
@@ -96,6 +97,7 @@
                         'Correct notifications were not received after '
                         '%s seconds.' % NOTIFICATIONS_WAIT)
 
+    @test.idempotent_id('6d6b88e5-3e38-41bc-b34a-79f713a6cb84')
     @test.services('object_storage', 'telemetry')
     def test_swift_middleware_notifies(self):
         container_name = self.create_container()
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index c8f438e..d1ea270 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -101,7 +101,7 @@
 
     def _ssh_to_server(self, server, keypair):
         if CONF.compute.use_floatingip_for_ssh:
-            _, floating_ip = self.floating_ips_client.create_floating_ip()
+            floating_ip = self.floating_ips_client.create_floating_ip()
             self.addCleanup(self.delete_wrapper,
                             self.floating_ips_client.delete_floating_ip,
                             floating_ip['id'])
@@ -133,6 +133,7 @@
         self.assertEqual(expected, actual)
 
     @decorators.skip_because(bug='1373513')
+    @test.idempotent_id('557cd2c2-4eb8-4dce-98be-f86765ff311b')
     @test.services('compute', 'volume', 'image')
     def test_volume_boot_pattern(self):
         keypair = self.create_keypair()
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index f997a65..68ec6e7 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -21,8 +21,8 @@
 import testscenarios
 import testtools
 
-from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common.utils import misc
 from tempest import config
 from tempest import exceptions
@@ -101,7 +101,7 @@
 
     def __init__(self):
         os = clients.Manager(
-            auth.get_default_credentials('user', fill_in=False))
+            cred_provider.get_configured_credentials('user', fill_in=False))
         self.images_client = os.images_client
         self.flavors_client = os.flavors_client
         self.image_pattern = CONF.input_scenario.image_regex
@@ -120,12 +120,15 @@
         if not CONF.service_available.glance:
             return []
         if not hasattr(self, '_scenario_images'):
-            images = self.images_client.list_images()
-            self._scenario_images = [
-                (self._normalize_name(i['name']), dict(image_ref=i['id']))
-                for i in images if re.search(self.image_pattern,
-                                             str(i['name']))
-            ]
+            try:
+                images = self.images_client.list_images()
+                self._scenario_images = [
+                    (self._normalize_name(i['name']), dict(image_ref=i['id']))
+                    for i in images if re.search(self.image_pattern,
+                                                 str(i['name']))
+                ]
+            except Exception:
+                self._scenario_images = []
         return self._scenario_images
 
     @property
@@ -134,12 +137,15 @@
         :return: a scenario with name and uuid of flavors
         """
         if not hasattr(self, '_scenario_flavors'):
-            flavors = self.flavors_client.list_flavors()
-            self._scenario_flavors = [
-                (self._normalize_name(f['name']), dict(flavor_ref=f['id']))
-                for f in flavors if re.search(self.flavor_pattern,
-                                              str(f['name']))
-            ]
+            try:
+                flavors = self.flavors_client.list_flavors()
+                self._scenario_flavors = [
+                    (self._normalize_name(f['name']), dict(flavor_ref=f['id']))
+                    for f in flavors if re.search(self.flavor_pattern,
+                                                  str(f['name']))
+                ]
+            except Exception:
+                self._scenario_flavors = []
         return self._scenario_flavors
 
 
diff --git a/tempest/services/baremetal/v1/json/baremetal_client.py b/tempest/services/baremetal/v1/json/baremetal_client.py
index 1c72a2b..09b6cd1 100644
--- a/tempest/services/baremetal/v1/json/baremetal_client.py
+++ b/tempest/services/baremetal/v1/json/baremetal_client.py
@@ -136,18 +136,18 @@
         Create a baremetal node with the specified parameters.
 
         :param cpu_arch: CPU architecture of the node. Default: x86_64.
-        :param cpu_num: Number of CPUs. Default: 8.
-        :param storage: Disk size. Default: 1024.
-        :param memory: Available RAM. Default: 4096.
+        :param cpus: Number of CPUs. Default: 8.
+        :param local_gb: Disk size. Default: 1024.
+        :param memory_mb: Available RAM. Default: 4096.
         :param driver: Driver name. Default: "fake"
         :return: A tuple with the server response and the created node.
 
         """
         node = {'chassis_uuid': chassis_id,
                 'properties': {'cpu_arch': kwargs.get('cpu_arch', 'x86_64'),
-                               'cpu_num': kwargs.get('cpu_num', 8),
-                               'storage': kwargs.get('storage', 1024),
-                               'memory': kwargs.get('memory', 4096)},
+                               'cpus': kwargs.get('cpus', 8),
+                               'local_gb': kwargs.get('local_gb', 1024),
+                               'memory_mb': kwargs.get('memory_mb', 4096)},
                 'driver': kwargs.get('driver', 'fake')}
 
         return self._create_request('nodes', node)
@@ -232,9 +232,9 @@
 
         """
         node_attributes = ('properties/cpu_arch',
-                           'properties/cpu_num',
-                           'properties/storage',
-                           'properties/memory',
+                           'properties/cpus',
+                           'properties/local_gb',
+                           'properties/memory_mb',
                            'driver',
                            'instance_uuid')
 
diff --git a/tempest/services/botoclients.py b/tempest/services/botoclients.py
index f581e89..1cbdb0c 100644
--- a/tempest/services/botoclients.py
+++ b/tempest/services/botoclients.py
@@ -15,6 +15,7 @@
 
 import ConfigParser
 import contextlib
+from tempest_lib import exceptions as lib_exc
 import types
 import urlparse
 
@@ -38,7 +39,7 @@
         # FIXME(andreaf) replace credentials and auth_url with auth_provider
 
         insecure_ssl = CONF.identity.disable_ssl_certificate_validation
-        ca_cert = CONF.identity.ca_certificates_file
+        self.ca_cert = CONF.identity.ca_certificates_file
 
         self.connection_timeout = str(CONF.boto.http_socket_timeout)
         self.num_retries = str(CONF.boto.num_retries)
@@ -48,7 +49,7 @@
                         "auth_url": auth_url,
                         "tenant_name": tenant_name,
                         "insecure": insecure_ssl,
-                        "cacert": ca_cert}
+                        "cacert": self.ca_cert}
 
     def _keystone_aws_get(self):
         # FIXME(andreaf) Move EC2 credentials to AuthProvider
@@ -65,7 +66,7 @@
             ec2_cred = keystone.ec2.create(keystone.auth_user_id,
                                            keystone.auth_tenant_id)
         if not all((ec2_cred, ec2_cred.access, ec2_cred.secret)):
-            raise exceptions.NotFound("Unable to get access and secret keys")
+            raise lib_exc.NotFound("Unable to get access and secret keys")
         return ec2_cred
 
     def _config_boto_timeout(self, timeout, retries):
@@ -76,6 +77,16 @@
         boto.config.set("Boto", "http_socket_timeout", timeout)
         boto.config.set("Boto", "num_retries", retries)
 
+    def _config_boto_ca_certificates_file(self, ca_cert):
+        if ca_cert is None:
+            return
+
+        try:
+            boto.config.add_section("Boto")
+        except ConfigParser.DuplicateSectionError:
+            pass
+        boto.config.set("Boto", "ca_certificates_file", ca_cert)
+
     def __getattr__(self, name):
         """Automatically creates methods for the allowed methods set."""
         if name in self.ALLOWED_METHODS:
@@ -93,6 +104,7 @@
 
     def get_connection(self):
         self._config_boto_timeout(self.connection_timeout, self.num_retries)
+        self._config_boto_ca_certificates_file(self.ca_cert)
         if not all((self.connection_data["aws_access_key_id"],
                    self.connection_data["aws_secret_access_key"])):
             if all([self.ks_cred.get('auth_url'),
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 94ea713..10955fd 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -15,10 +15,11 @@
 
 import json
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api_schema.response.compute import aggregates as schema
 from tempest.api_schema.response.compute.v2 import aggregates as v2_schema
 from tempest.common import service_client
-from tempest import exceptions
 
 
 class AggregatesClientJSON(service_client.ServiceClient):
@@ -68,7 +69,7 @@
     def is_resource_deleted(self, id):
         try:
             self.get_aggregate(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index e37c9d9..343c412 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -25,11 +25,13 @@
         resp, body = self.get('os-availability-zone')
         body = json.loads(body)
         self.validate_response(schema.get_availability_zone_list, resp, body)
-        return resp, body['availabilityZoneInfo']
+        return service_client.ResponseBodyList(resp,
+                                               body['availabilityZoneInfo'])
 
     def get_availability_zone_list_detail(self):
         resp, body = self.get('os-availability-zone/detail')
         body = json.loads(body)
         self.validate_response(schema.get_availability_zone_list_detail, resp,
                                body)
-        return resp, body['availabilityZoneInfo']
+        return service_client.ResponseBodyList(resp,
+                                               body['availabilityZoneInfo'])
diff --git a/tempest/services/compute/json/baremetal_nodes_client.py b/tempest/services/compute/json/baremetal_nodes_client.py
new file mode 100644
index 0000000..d8bbadd
--- /dev/null
+++ b/tempest/services/compute/json/baremetal_nodes_client.py
@@ -0,0 +1,43 @@
+# Copyright 2015 NEC Corporation.  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 json
+import urllib
+
+from tempest.api_schema.response.compute import baremetal_nodes as schema
+from tempest.common import service_client
+
+
+class BaremetalNodesClientJSON(service_client.ServiceClient):
+    """
+    Tests Baremetal API
+    """
+
+    def list_baremetal_nodes(self, params=None):
+        """List all baremetal nodes."""
+        url = 'os-baremetal-nodes'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.validate_response(schema.list_baremetal_nodes, resp, body)
+        return service_client.ResponseBodyList(resp, body['nodes'])
+
+    def get_baremetal_node(self, baremetal_node_id):
+        """Returns the details of a single baremetal node."""
+        url = 'os-baremetal-nodes/%s' % baremetal_node_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.validate_response(schema.get_baremetal_node, resp, body)
+        return service_client.ResponseBody(resp, body['node'])
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index b705c37..4a30f1e 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -27,7 +27,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.get_certificate, resp, body)
-        return resp, body['certificate']
+        return service_client.ResponseBody(resp, body['certificate'])
 
     def create_certificate(self):
         """create certificates."""
@@ -35,4 +35,4 @@
         resp, body = self.post(url, None)
         body = json.loads(body)
         self.validate_response(v2schema.create_certificate, resp, body)
-        return resp, body['certificate']
+        return service_client.ResponseBody(resp, body['certificate'])
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index d3148b4..09561b3 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -26,14 +26,14 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.list_extensions, resp, body)
-        return resp, body['extensions']
+        return service_client.ResponseBodyList(resp, body['extensions'])
 
     def is_enabled(self, extension):
-        _, extensions = self.list_extensions()
+        extensions = self.list_extensions()
         exts = extensions['extensions']
         return any([e for e in exts if e['name'] == extension])
 
     def get_extension(self, extension_alias):
         resp, body = self.get('extensions/%s' % extension_alias)
         body = json.loads(body)
-        return resp, body['extension']
+        return service_client.ResponseBody(resp, body['extension'])
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index 5797c16..31cf5b2 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -26,11 +26,11 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.fixed_ips, resp, body)
-        return resp, body['fixed_ip']
+        return service_client.ResponseBody(resp, body['fixed_ip'])
 
     def reserve_fixed_ip(self, ip, body):
         """This reserves and unreserves fixed ips."""
         url = "os-fixed-ips/%s/action" % (ip)
         resp, body = self.post(url, json.dumps(body))
         self.validate_response(schema.fixed_ip_action, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp)
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 9c586e3..0354ba4 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -16,9 +16,10 @@
 import json
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api_schema.response.compute.v2 import floating_ips as schema
 from tempest.common import service_client
-from tempest import exceptions
 
 
 class FloatingIPsClientJSON(service_client.ServiceClient):
@@ -32,17 +33,15 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.list_floating_ips, resp, body)
-        return resp, body['floating_ips']
+        return service_client.ResponseBodyList(resp, body['floating_ips'])
 
     def get_floating_ip_details(self, floating_ip_id):
         """Get the details of a floating IP."""
         url = "os-floating-ips/%s" % str(floating_ip_id)
         resp, body = self.get(url)
         body = json.loads(body)
-        if resp.status == 404:
-            raise exceptions.NotFound(body)
         self.validate_response(schema.floating_ip, resp, body)
-        return resp, body['floating_ip']
+        return service_client.ResponseBody(resp, body['floating_ip'])
 
     def create_floating_ip(self, pool_name=None):
         """Allocate a floating IP to the project."""
@@ -52,14 +51,14 @@
         resp, body = self.post(url, post_body)
         body = json.loads(body)
         self.validate_response(schema.floating_ip, resp, body)
-        return resp, body['floating_ip']
+        return service_client.ResponseBody(resp, body['floating_ip'])
 
     def delete_floating_ip(self, floating_ip_id):
         """Deletes the provided floating IP from the project."""
         url = "os-floating-ips/%s" % str(floating_ip_id)
         resp, body = self.delete(url)
         self.validate_response(schema.add_remove_floating_ip, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def associate_floating_ip_to_server(self, floating_ip, server_id):
         """Associate the provided floating IP to a specific server."""
@@ -73,7 +72,7 @@
         post_body = json.dumps(post_body)
         resp, body = self.post(url, post_body)
         self.validate_response(schema.add_remove_floating_ip, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def disassociate_floating_ip_from_server(self, floating_ip, server_id):
         """Disassociate the provided floating IP from a specific server."""
@@ -87,12 +86,12 @@
         post_body = json.dumps(post_body)
         resp, body = self.post(url, post_body)
         self.validate_response(schema.add_remove_floating_ip, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def is_resource_deleted(self, id):
         try:
             self.get_floating_ip_details(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
@@ -110,7 +109,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.floating_ip_pools, resp, body)
-        return resp, body['floating_ip_pools']
+        return service_client.ResponseBodyList(resp, body['floating_ip_pools'])
 
     def create_floating_ips_bulk(self, ip_range, pool, interface):
         """Allocate floating IPs in bulk."""
@@ -123,14 +122,15 @@
         resp, body = self.post('os-floating-ips-bulk', post_body)
         body = json.loads(body)
         self.validate_response(schema.create_floating_ips_bulk, resp, body)
-        return resp, body['floating_ips_bulk_create']
+        return service_client.ResponseBody(resp,
+                                           body['floating_ips_bulk_create'])
 
     def list_floating_ips_bulk(self):
         """Returns a list of all floating IPs bulk."""
         resp, body = self.get('os-floating-ips-bulk')
         body = json.loads(body)
         self.validate_response(schema.list_floating_ips_bulk, resp, body)
-        return resp, body['floating_ip_info']
+        return service_client.ResponseBodyList(resp, body['floating_ip_info'])
 
     def delete_floating_ips_bulk(self, ip_range):
         """Deletes the provided floating IPs bulk."""
@@ -138,4 +138,5 @@
         resp, body = self.put('os-floating-ips-bulk/delete', post_body)
         body = json.loads(body)
         self.validate_response(schema.delete_floating_ips_bulk, resp, body)
-        return resp, body['floating_ips_bulk_delete']
+        data = body['floating_ips_bulk_delete']
+        return service_client.ResponseBodyData(resp, data)
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index a5755da..0ceb6d1 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -16,10 +16,11 @@
 import json
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api_schema.response.compute.v2 import images as schema
 from tempest.common import service_client
 from tempest.common import waiters
-from tempest import exceptions
 
 
 class ImagesClientJSON(service_client.ServiceClient):
@@ -131,7 +132,7 @@
     def is_resource_deleted(self, id):
         try:
             self.get_image(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index 80d7334..551d751 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -28,11 +28,13 @@
         body = json.loads(body)
         self.validate_response(schema.list_instance_usage_audit_log,
                                resp, body)
-        return resp, body["instance_usage_audit_logs"]
+        return service_client.ResponseBody(resp,
+                                           body["instance_usage_audit_logs"])
 
     def get_instance_usage_audit_log(self, time_before):
         url = 'os-instance_usage_audit_log/%s' % time_before
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.get_instance_usage_audit_log, resp, body)
-        return resp, body["instance_usage_audit_log"]
+        return service_client.ResponseBody(resp,
+                                           body["instance_usage_audit_log"])
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index 595b23c..0c5516c 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -29,7 +29,8 @@
         resp, body = self.get('servers/%s/os-interface' % server)
         body = json.loads(body)
         self.validate_response(schema.list_interfaces, resp, body)
-        return resp, body['interfaceAttachments']
+        return service_client.ResponseBodyList(resp,
+                                               body['interfaceAttachments'])
 
     def create_interface(self, server, port_id=None, network_id=None,
                          fixed_ip=None):
@@ -45,28 +46,28 @@
         resp, body = self.post('servers/%s/os-interface' % server,
                                body=post_body)
         body = json.loads(body)
-        return resp, body['interfaceAttachment']
+        return service_client.ResponseBody(resp, body['interfaceAttachment'])
 
     def show_interface(self, server, port_id):
         resp, body = self.get('servers/%s/os-interface/%s' % (server, port_id))
         body = json.loads(body)
-        return resp, body['interfaceAttachment']
+        return service_client.ResponseBody(resp, body['interfaceAttachment'])
 
     def delete_interface(self, server, port_id):
         resp, body = self.delete('servers/%s/os-interface/%s' % (server,
                                                                  port_id))
         self.validate_response(common_schema.delete_interface, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def wait_for_interface_status(self, server, port_id, status):
         """Waits for a interface to reach a given status."""
-        resp, body = self.show_interface(server, port_id)
+        body = self.show_interface(server, port_id)
         interface_status = body['port_state']
         start = int(time.time())
 
         while(interface_status != status):
             time.sleep(self.build_interval)
-            resp, body = self.show_interface(server, port_id)
+            body = self.show_interface(server, port_id)
             interface_status = body['port_state']
 
             timed_out = int(time.time()) - start >= self.build_timeout
@@ -78,7 +79,7 @@
                             self.build_timeout))
                 raise exceptions.TimeoutException(message)
 
-        return resp, body
+        return body
 
     def add_fixed_ip(self, server_id, network_id):
         """Add a fixed IP to input server instance."""
@@ -91,7 +92,7 @@
                                post_body)
         self.validate_response(servers_schema.server_actions_common_schema,
                                resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def remove_fixed_ip(self, server_id, ip_address):
         """Remove input fixed IP from input server instance."""
@@ -104,4 +105,4 @@
                                post_body)
         self.validate_response(servers_schema.server_actions_common_schema,
                                resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index b41abc8..a65b655 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -31,4 +31,4 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.list_migrations, resp, body)
-        return resp, body['migrations']
+        return service_client.ResponseBodyList(resp, body['migrations'])
diff --git a/tempest/services/compute/json/networks_client.py b/tempest/services/compute/json/networks_client.py
index 361258a..ef1c058 100644
--- a/tempest/services/compute/json/networks_client.py
+++ b/tempest/services/compute/json/networks_client.py
@@ -24,10 +24,10 @@
         resp, body = self.get("os-networks")
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return resp, body['networks']
+        return service_client.ResponseBodyList(resp, body['networks'])
 
     def get_network(self, network_id):
         resp, body = self.get("os-networks/%s" % str(network_id))
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return resp, body['network']
+        return service_client.ResponseBody(resp, body['network'])
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index 410ad60..5aefa7b 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -16,9 +16,10 @@
 import json
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api_schema.response.compute.v2 import security_groups as schema
 from tempest.common import service_client
-from tempest import exceptions
 
 
 class SecurityGroupsClientJSON(service_client.ServiceClient):
@@ -128,12 +129,12 @@
         for sg in body['security_groups']:
             if sg['id'] == security_group_id:
                 return service_client.ResponseBodyList(resp, sg['rules'])
-        raise exceptions.NotFound('No such Security Group')
+        raise lib_exc.NotFound('No such Security Group')
 
     def is_resource_deleted(self, id):
         try:
             self.get_security_group(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index cbe1ca8..bd4fd0e 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -18,18 +18,23 @@
 import time
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api_schema.response.compute import servers as common_schema
 from tempest.api_schema.response.compute.v2 import servers as schema
 from tempest.common import service_client
 from tempest.common import waiters
-from tempest import config
 from tempest import exceptions
 
-CONF = config.CONF
-
 
 class ServersClientJSON(service_client.ServiceClient):
 
+    def __init__(self, auth_provider, service, region,
+                 enable_instance_password=True, **kwargs):
+        super(ServersClientJSON, self).__init__(
+            auth_provider, service, region, **kwargs)
+        self.enable_instance_password = enable_instance_password
+
     def create_server(self, name, image_ref, flavor_ref, **kwargs):
         """
         Creates an instance of a server.
@@ -90,13 +95,13 @@
         # NOTE(maurosr): this deals with the case of multiple server create
         # with return reservation id set True
         if 'reservation_id' in body:
-            return resp, body
-        if CONF.compute_feature_enabled.enable_instance_password:
+            return service_client.ResponseBody(resp, body)
+        if self.enable_instance_password:
             create_schema = schema.create_server_with_admin_pass
         else:
             create_schema = schema.create_server
         self.validate_response(create_schema, resp, body)
-        return resp, body['server']
+        return service_client.ResponseBody(resp, body['server'])
 
     def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
                       accessIPv6=None, disk_config=None):
@@ -130,20 +135,20 @@
         resp, body = self.put("servers/%s" % str(server_id), post_body)
         body = json.loads(body)
         self.validate_response(schema.update_server, resp, body)
-        return resp, body['server']
+        return service_client.ResponseBody(resp, body['server'])
 
     def get_server(self, server_id):
         """Returns the details of an existing server."""
         resp, body = self.get("servers/%s" % str(server_id))
         body = json.loads(body)
         self.validate_response(schema.get_server, resp, body)
-        return resp, body['server']
+        return service_client.ResponseBody(resp, body['server'])
 
     def delete_server(self, server_id):
         """Deletes the given server."""
         resp, body = self.delete("servers/%s" % str(server_id))
         self.validate_response(common_schema.delete_server, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def list_servers(self, params=None):
         """Lists all servers for a user."""
@@ -155,7 +160,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(common_schema.list_servers, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def list_servers_with_detail(self, params=None):
         """Lists all servers in detail for a user."""
@@ -167,7 +172,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.list_servers_detail, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def wait_for_server_status(self, server_id, status, extra_timeout=0,
                                raise_on_error=True, ready_wait=True):
@@ -182,8 +187,8 @@
         start_time = int(time.time())
         while True:
             try:
-                resp, body = self.get_server(server_id)
-            except exceptions.NotFound:
+                body = self.get_server(server_id)
+            except lib_exc.NotFound:
                 return
 
             server_status = body['status']
@@ -200,7 +205,7 @@
         resp, body = self.get("servers/%s/ips" % str(server_id))
         body = json.loads(body)
         self.validate_response(schema.list_addresses, resp, body)
-        return resp, body['addresses']
+        return service_client.ResponseBody(resp, body['addresses'])
 
     def list_addresses_by_network(self, server_id, network_id):
         """Lists all addresses of a specific network type for a server."""
@@ -208,10 +213,11 @@
                               (str(server_id), network_id))
         body = json.loads(body)
         self.validate_response(schema.list_addresses_by_network, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def action(self, server_id, action_name, response_key,
-               schema=common_schema.server_actions_common_schema, **kwargs):
+               schema=common_schema.server_actions_common_schema,
+               response_class=service_client.ResponseBody, **kwargs):
         post_body = json.dumps({action_name: kwargs})
         resp, body = self.post('servers/%s/action' % str(server_id),
                                post_body)
@@ -229,7 +235,7 @@
             body = body[response_key]
         else:
             self.validate_response(schema, resp, body)
-        return resp, body
+        return response_class(resp, body)
 
     def create_backup(self, server_id, backup_type, rotation, name):
         """Backup a server instance."""
@@ -248,7 +254,7 @@
                               str(server_id))
         body = json.loads(body)
         self.validate_response(common_schema.get_password, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def delete_password(self, server_id):
         """
@@ -260,7 +266,7 @@
                                  str(server_id))
         self.validate_response(common_schema.server_actions_delete_password,
                                resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def reboot(self, server_id, reboot_type):
         """Reboots a server."""
@@ -272,7 +278,7 @@
         if 'disk_config' in kwargs:
             kwargs['OS-DCF:diskConfig'] = kwargs['disk_config']
             del kwargs['disk_config']
-        if CONF.compute_feature_enabled.enable_instance_password:
+        if self.enable_instance_password:
             rebuild_schema = schema.rebuild_server_with_admin_pass
         else:
             rebuild_schema = schema.rebuild_server
@@ -301,7 +307,7 @@
         resp, body = self.get("servers/%s/metadata" % str(server_id))
         body = json.loads(body)
         self.validate_response(common_schema.list_server_metadata, resp, body)
-        return resp, body['metadata']
+        return service_client.ResponseBody(resp, body['metadata'])
 
     def set_server_metadata(self, server_id, meta, no_metadata_field=False):
         if no_metadata_field:
@@ -312,7 +318,7 @@
                               post_body)
         body = json.loads(body)
         self.validate_response(common_schema.set_server_metadata, resp, body)
-        return resp, body['metadata']
+        return service_client.ResponseBody(resp, body['metadata'])
 
     def update_server_metadata(self, server_id, meta):
         post_body = json.dumps({'metadata': meta})
@@ -321,14 +327,14 @@
         body = json.loads(body)
         self.validate_response(common_schema.update_server_metadata,
                                resp, body)
-        return resp, body['metadata']
+        return service_client.ResponseBody(resp, body['metadata'])
 
     def get_server_metadata_item(self, server_id, key):
         resp, body = self.get("servers/%s/metadata/%s" % (str(server_id), key))
         body = json.loads(body)
         self.validate_response(schema.set_get_server_metadata_item,
                                resp, body)
-        return resp, body['meta']
+        return service_client.ResponseBody(resp, body['meta'])
 
     def set_server_metadata_item(self, server_id, key, meta):
         post_body = json.dumps({'meta': meta})
@@ -337,14 +343,14 @@
         body = json.loads(body)
         self.validate_response(schema.set_get_server_metadata_item,
                                resp, body)
-        return resp, body['meta']
+        return service_client.ResponseBody(resp, body['meta'])
 
     def delete_server_metadata_item(self, server_id, key):
         resp, body = self.delete("servers/%s/metadata/%s" %
                                  (str(server_id), key))
         self.validate_response(common_schema.delete_server_metadata_item,
                                resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def stop(self, server_id, **kwargs):
         return self.action(server_id, 'os-stop', None, **kwargs)
@@ -364,14 +370,14 @@
                                post_body)
         body = json.loads(body)
         self.validate_response(schema.attach_volume, resp, body)
-        return resp, body['volumeAttachment']
+        return service_client.ResponseBody(resp, body['volumeAttachment'])
 
     def detach_volume(self, server_id, volume_id):
         """Detaches a volume from a server instance."""
         resp, body = self.delete('servers/%s/os-volume_attachments/%s' %
                                  (server_id, volume_id))
         self.validate_response(schema.detach_volume, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def get_volume_attachment(self, server_id, attach_id):
         """Return details about the given volume attachment."""
@@ -379,7 +385,7 @@
             str(server_id), attach_id))
         body = json.loads(body)
         self.validate_response(schema.get_volume_attachment, resp, body)
-        return resp, body['volumeAttachment']
+        return service_client.ResponseBody(resp, body['volumeAttachment'])
 
     def list_volume_attachments(self, server_id):
         """Returns the list of volume attachments for a given instance."""
@@ -387,7 +393,7 @@
             str(server_id)))
         body = json.loads(body)
         self.validate_response(schema.list_volume_attachments, resp, body)
-        return resp, body['volumeAttachments']
+        return service_client.ResponseBodyList(resp, body['volumeAttachments'])
 
     def add_security_group(self, server_id, name):
         """Adds a security group to the server."""
@@ -411,7 +417,7 @@
         resp, body = self.post("servers/%s/action" % str(server_id), req_body)
         self.validate_response(common_schema.server_actions_common_schema,
                                resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def migrate_server(self, server_id, **kwargs):
         """Migrates a server to a new host."""
@@ -460,7 +466,9 @@
     def get_console_output(self, server_id, length):
         kwargs = {'length': length} if length else {}
         return self.action(server_id, 'os-getConsoleOutput', 'output',
-                           common_schema.get_console_output, **kwargs)
+                           common_schema.get_console_output,
+                           response_class=service_client.ResponseBodyData,
+                           **kwargs)
 
     def list_virtual_interfaces(self, server_id):
         """
@@ -470,12 +478,14 @@
                               'os-virtual-interfaces']))
         body = json.loads(body)
         self.validate_response(schema.list_virtual_interfaces, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def rescue_server(self, server_id, **kwargs):
         """Rescue the provided server."""
         return self.action(server_id, 'rescue', 'adminPass',
-                           schema.rescue_server, **kwargs)
+                           schema.rescue_server,
+                           response_class=service_client.ResponseBodyData,
+                           **kwargs)
 
     def unrescue_server(self, server_id):
         """Unrescue the provided server."""
@@ -484,7 +494,7 @@
     def get_server_diagnostics(self, server_id):
         """Get the usage data for a server."""
         resp, body = self.get("servers/%s/diagnostics" % str(server_id))
-        return resp, json.loads(body)
+        return service_client.ResponseBody(resp, json.loads(body))
 
     def list_instance_actions(self, server_id):
         """List the provided server action."""
@@ -492,7 +502,7 @@
                               str(server_id))
         body = json.loads(body)
         self.validate_response(schema.list_instance_actions, resp, body)
-        return resp, body['instanceActions']
+        return service_client.ResponseBodyList(resp, body['instanceActions'])
 
     def get_instance_action(self, server_id, request_id):
         """Returns the action details of the provided server."""
@@ -500,7 +510,7 @@
                               (str(server_id), str(request_id)))
         body = json.loads(body)
         self.validate_response(schema.get_instance_action, resp, body)
-        return resp, body['instanceAction']
+        return service_client.ResponseBody(resp, body['instanceAction'])
 
     def force_delete_server(self, server_id, **kwargs):
         """Force delete a server."""
@@ -540,24 +550,24 @@
 
         body = json.loads(body)
         self.validate_response(schema.create_get_server_group, resp, body)
-        return resp, body['server_group']
+        return service_client.ResponseBody(resp, body['server_group'])
 
     def delete_server_group(self, server_group_id):
         """Delete the given server-group."""
         resp, body = self.delete("os-server-groups/%s" % str(server_group_id))
         self.validate_response(schema.delete_server_group, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def list_server_groups(self):
         """List the server-groups."""
         resp, body = self.get("os-server-groups")
         body = json.loads(body)
         self.validate_response(schema.list_server_groups, resp, body)
-        return resp, body['server_groups']
+        return service_client.ResponseBodyList(resp, body['server_groups'])
 
     def get_server_group(self, server_group_id):
         """Get the details of given server_group."""
         resp, body = self.get("os-server-groups/%s" % str(server_group_id))
         body = json.loads(body)
         self.validate_response(schema.create_get_server_group, resp, body)
-        return resp, body['server_group']
+        return service_client.ResponseBody(resp, body['server_group'])
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index 5dc1d5d..bbc1051 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -30,7 +30,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.list_tenant, resp, body)
-        return resp, body['tenant_usages'][0]
+        return service_client.ResponseBodyList(resp, body['tenant_usages'][0])
 
     def get_tenant_usage(self, tenant_id, params=None):
         url = 'os-simple-tenant-usage/%s' % tenant_id
@@ -40,4 +40,4 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.get_tenant, resp, body)
-        return resp, body['tenant_usage']
+        return service_client.ResponseBodyList(resp, body['tenant_usage'])
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 61d0b23..a9cada8 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -17,6 +17,8 @@
 import time
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.api_schema.response.compute.v2 import volumes as schema
 from tempest.common import service_client
 from tempest import exceptions
@@ -33,7 +35,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.list_volumes, resp, body)
-        return resp, body['volumes']
+        return service_client.ResponseBodyList(resp, body['volumes'])
 
     def list_volumes_with_detail(self, params=None):
         """List all the details of volumes."""
@@ -44,7 +46,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.list_volumes, resp, body)
-        return resp, body['volumes']
+        return service_client.ResponseBodyList(resp, body['volumes'])
 
     def get_volume(self, volume_id):
         """Returns the details of a single volume."""
@@ -52,7 +54,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.create_get_volume, resp, body)
-        return resp, body['volume']
+        return service_client.ResponseBody(resp, body['volume'])
 
     def create_volume(self, size, **kwargs):
         """
@@ -71,23 +73,23 @@
         resp, body = self.post('os-volumes', post_body)
         body = json.loads(body)
         self.validate_response(schema.create_get_volume, resp, body)
-        return resp, body['volume']
+        return service_client.ResponseBody(resp, body['volume'])
 
     def delete_volume(self, volume_id):
         """Deletes the Specified Volume."""
         resp, body = self.delete("os-volumes/%s" % str(volume_id))
         self.validate_response(schema.delete_volume, resp, body)
-        return resp, body
+        return service_client.ResponseBody(resp, body)
 
     def wait_for_volume_status(self, volume_id, status):
         """Waits for a Volume to reach a given status."""
-        resp, body = self.get_volume(volume_id)
+        body = self.get_volume(volume_id)
         volume_status = body['status']
         start = int(time.time())
 
         while volume_status != status:
             time.sleep(self.build_interval)
-            resp, body = self.get_volume(volume_id)
+            body = self.get_volume(volume_id)
             volume_status = body['status']
             if volume_status == 'error':
                 raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
@@ -102,7 +104,7 @@
     def is_resource_deleted(self, id):
         try:
             self.get_volume(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
diff --git a/tempest/services/data_processing/v1_1/client.py b/tempest/services/data_processing/v1_1/data_processing_client.py
similarity index 79%
rename from tempest/services/data_processing/v1_1/client.py
rename to tempest/services/data_processing/v1_1/data_processing_client.py
index 55b6be6..04cf9a3 100644
--- a/tempest/services/data_processing/v1_1/client.py
+++ b/tempest/services/data_processing/v1_1/data_processing_client.py
@@ -15,25 +15,25 @@
 import json
 
 from tempest.common import service_client
-from tempest import config
-
-CONF = config.CONF
 
 
 class DataProcessingClient(service_client.ServiceClient):
 
-    def __init__(self, auth_provider):
-        super(DataProcessingClient, self).__init__(
-            auth_provider,
-            CONF.data_processing.catalog_type,
-            CONF.identity.region,
-            endpoint_type=CONF.data_processing.endpoint_type)
-
     def _request_and_check_resp(self, request_func, uri, resp_status):
         """Make a request using specified request_func and check response
         status code.
 
-        It returns pair: resp and response body.
+        It returns a ResponseBody.
+        """
+        resp, body = request_func(uri)
+        self.expected_success(resp_status, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def _request_and_check_resp_data(self, request_func, uri, resp_status):
+        """Make a request using specified request_func and check response
+        status code.
+
+        It returns pair: resp and response data.
         """
         resp, body = request_func(uri)
         self.expected_success(resp_status, resp.status)
@@ -44,20 +44,35 @@
         """Make a request using specified request_func, check response status
         code and parse response body.
 
-        It returns pair: resp and parsed resource(s) body.
+        It returns a ResponseBody.
         """
         headers = {'Content-Type': 'application/json'}
         resp, body = request_func(uri, headers=headers, *args, **kwargs)
         self.expected_success(resp_status, resp.status)
         body = json.loads(body)
-        return resp, body[resource_name]
+        return service_client.ResponseBody(resp, body[resource_name])
+
+    def _request_check_and_parse_resp_list(self, request_func, uri,
+                                           resp_status, resource_name,
+                                           *args, **kwargs):
+        """Make a request using specified request_func, check response status
+        code and parse response body.
+
+        It returns a ResponseBodyList.
+        """
+        headers = {'Content-Type': 'application/json'}
+        resp, body = request_func(uri, headers=headers, *args, **kwargs)
+        self.expected_success(resp_status, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBodyList(resp, body[resource_name])
 
     def list_node_group_templates(self):
         """List all node group templates for a user."""
 
         uri = 'node-group-templates'
-        return self._request_check_and_parse_resp(self.get, uri,
-                                                  200, 'node_group_templates')
+        return self._request_check_and_parse_resp_list(self.get, uri,
+                                                       200,
+                                                       'node_group_templates')
 
     def get_node_group_template(self, tmpl_id):
         """Returns the details of a single node group template."""
@@ -98,8 +113,8 @@
         """List all enabled plugins."""
 
         uri = 'plugins'
-        return self._request_check_and_parse_resp(self.get,
-                                                  uri, 200, 'plugins')
+        return self._request_check_and_parse_resp_list(self.get,
+                                                       uri, 200, 'plugins')
 
     def get_plugin(self, plugin_name, plugin_version=None):
         """Returns the details of a single plugin."""
@@ -113,8 +128,9 @@
         """List all cluster templates for a user."""
 
         uri = 'cluster-templates'
-        return self._request_check_and_parse_resp(self.get, uri,
-                                                  200, 'cluster_templates')
+        return self._request_check_and_parse_resp_list(self.get, uri,
+                                                       200,
+                                                       'cluster_templates')
 
     def get_cluster_template(self, tmpl_id):
         """Returns the details of a single cluster template."""
@@ -154,8 +170,9 @@
         """List all data sources for a user."""
 
         uri = 'data-sources'
-        return self._request_check_and_parse_resp(self.get,
-                                                  uri, 200, 'data_sources')
+        return self._request_check_and_parse_resp_list(self.get,
+                                                       uri, 200,
+                                                       'data_sources')
 
     def get_data_source(self, source_id):
         """Returns the details of a single data source."""
@@ -191,8 +208,8 @@
         """List all job binary internals for a user."""
 
         uri = 'job-binary-internals'
-        return self._request_check_and_parse_resp(self.get,
-                                                  uri, 200, 'binaries')
+        return self._request_check_and_parse_resp_list(self.get,
+                                                       uri, 200, 'binaries')
 
     def get_job_binary_internal(self, job_binary_id):
         """Returns the details of a single job binary internal."""
@@ -218,14 +235,14 @@
         """Returns data of a single job binary internal."""
 
         uri = 'job-binary-internals/%s/data' % job_binary_id
-        return self._request_and_check_resp(self.get, uri, 200)
+        return self._request_and_check_resp_data(self.get, uri, 200)
 
     def list_job_binaries(self):
         """List all job binaries for a user."""
 
         uri = 'job-binaries'
-        return self._request_check_and_parse_resp(self.get,
-                                                  uri, 200, 'binaries')
+        return self._request_check_and_parse_resp_list(self.get,
+                                                       uri, 200, 'binaries')
 
     def get_job_binary(self, job_binary_id):
         """Returns the details of a single job binary."""
@@ -261,13 +278,14 @@
         """Returns data of a single job binary."""
 
         uri = 'job-binaries/%s/data' % job_binary_id
-        return self._request_and_check_resp(self.get, uri, 200)
+        return self._request_and_check_resp_data(self.get, uri, 200)
 
     def list_jobs(self):
         """List all jobs for a user."""
 
         uri = 'jobs'
-        return self._request_check_and_parse_resp(self.get, uri, 200, 'jobs')
+        return self._request_check_and_parse_resp_list(self.get,
+                                                       uri, 200, 'jobs')
 
     def get_job(self, job_id):
         """Returns the details of a single job."""
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
index dfb2eb3..c956e27 100644
--- a/tempest/services/database/json/flavors_client.py
+++ b/tempest/services/database/json/flavors_client.py
@@ -27,9 +27,9 @@
 
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        return resp, self._parse_resp(body)
+        return service_client.ResponseBodyList(resp, self._parse_resp(body))
 
     def get_db_flavor_details(self, db_flavor_id):
         resp, body = self.get("flavors/%s" % str(db_flavor_id))
         self.expected_success(200, resp.status)
-        return resp, self._parse_resp(body)
+        return service_client.ResponseBody(resp, self._parse_resp(body))
diff --git a/tempest/services/database/json/limits_client.py b/tempest/services/database/json/limits_client.py
index 4daf028..ae758bc 100644
--- a/tempest/services/database/json/limits_client.py
+++ b/tempest/services/database/json/limits_client.py
@@ -15,13 +15,10 @@
 
 import urllib
 
-from tempest import config
-from tempest_lib.common import rest_client
-
-CONF = config.CONF
+from tempest.common import service_client
 
 
-class DatabaseLimitsClientJSON(rest_client.RestClient):
+class DatabaseLimitsClientJSON(service_client.ServiceClient):
 
     def list_db_limits(self, params=None):
         """List all limits."""
@@ -30,4 +27,4 @@
             url += '?%s' % urllib.urlencode(params)
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        return resp, self._parse_resp(body)
+        return service_client.ResponseBodyList(resp, self._parse_resp(body))
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index c3388bb..aa2fef7 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -43,4 +43,4 @@
 
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        return resp, self._parse_resp(body)
+        return service_client.ResponseBodyList(resp, self._parse_resp(body))
diff --git a/tempest/services/identity/json/__init__.py b/tempest/services/identity/v2/__init__.py
similarity index 100%
copy from tempest/services/identity/json/__init__.py
copy to tempest/services/identity/v2/__init__.py
diff --git a/tempest/services/identity/json/__init__.py b/tempest/services/identity/v2/json/__init__.py
similarity index 100%
rename from tempest/services/identity/json/__init__.py
rename to tempest/services/identity/v2/json/__init__.py
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
similarity index 96%
rename from tempest/services/identity/json/identity_client.py
rename to tempest/services/identity/v2/json/identity_client.py
index d4f57e0..6c4a6b4 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -11,23 +11,13 @@
 #    under the License.
 
 import json
+from tempest_lib import exceptions as lib_exc
 
 from tempest.common import service_client
-from tempest import config
-from tempest import exceptions
-
-CONF = config.CONF
 
 
 class IdentityClientJSON(service_client.ServiceClient):
 
-    def __init__(self, auth_provider):
-        super(IdentityClientJSON, self).__init__(
-            auth_provider,
-            CONF.identity.catalog_type,
-            CONF.identity.region,
-            endpoint_type='adminURL')
-
     def has_admin_extensions(self):
         """
         Returns True if the KSADM Admin Extensions are supported
@@ -134,7 +124,7 @@
         for tenant in tenants:
             if tenant['name'] == tenant_name:
                 return tenant
-        raise exceptions.NotFound('No such tenant')
+        raise lib_exc.NotFound('No such tenant')
 
     def update_tenant(self, tenant_id, **kwargs):
         """Updates a tenant."""
@@ -227,7 +217,7 @@
         for user in users:
             if user['name'] == username:
                 return user
-        raise exceptions.NotFound('No such user')
+        raise lib_exc.NotFound('No such user')
 
     def create_service(self, name, type, **kwargs):
         """Create a service."""
diff --git a/tempest/services/identity/json/token_client.py b/tempest/services/identity/v2/json/token_client.py
similarity index 84%
rename from tempest/services/identity/json/token_client.py
rename to tempest/services/identity/v2/json/token_client.py
index 93936bc..e61ac84 100644
--- a/tempest/services/identity/json/token_client.py
+++ b/tempest/services/identity/v2/json/token_client.py
@@ -13,19 +13,21 @@
 #    under the License.
 
 import json
+from tempest_lib.common import rest_client
+from tempest_lib import exceptions as lib_exc
 
 from tempest.common import service_client
-from tempest import config
 from tempest import exceptions
 
-CONF = config.CONF
 
+class TokenClientJSON(rest_client.RestClient):
 
-class TokenClientJSON(service_client.ServiceClient):
-
-    def __init__(self):
-        super(TokenClientJSON, self).__init__(None, None, None)
-        auth_url = CONF.identity.uri
+    def __init__(self, auth_url, disable_ssl_certificate_validation=None,
+                 ca_certs=None, trace_requests=None):
+        dscv = disable_ssl_certificate_validation
+        super(TokenClientJSON, self).__init__(
+            None, None, None, disable_ssl_certificate_validation=dscv,
+            ca_certs=ca_certs, trace_requests=trace_requests)
 
         # Normalize URI to ensure /tokens is in it.
         if 'tokens' not in auth_url:
@@ -87,7 +89,7 @@
 
         if resp.status in [401, 403]:
             resp_body = json.loads(resp_body)
-            raise exceptions.Unauthorized(resp_body['error']['message'])
+            raise lib_exc.Unauthorized(resp_body['error']['message'])
         elif resp.status not in [200, 201]:
             raise exceptions.IdentityError(
                 'Unexpected status code {0}'.format(resp.status))
diff --git a/tempest/services/identity/v3/json/base.py b/tempest/services/identity/v3/json/base.py
deleted file mode 100644
index cba480a..0000000
--- a/tempest/services/identity/v3/json/base.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2014 NEC Corporation.  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.
-
-from tempest.common import service_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class IdentityV3Client(service_client.ServiceClient):
-    """
-    Base identity v3 client class
-    """
-
-    def __init__(self, auth_provider):
-        super(IdentityV3Client, self).__init__(
-            auth_provider,
-            CONF.identity.catalog_type,
-            CONF.identity.region,
-            endpoint_type='adminURL')
-        self.api_version = "v3"
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/services/identity/v3/json/credentials_client.py
index 1289e48..0a614cd 100644
--- a/tempest/services/identity/v3/json/credentials_client.py
+++ b/tempest/services/identity/v3/json/credentials_client.py
@@ -16,10 +16,10 @@
 import json
 
 from tempest.common import service_client
-from tempest.services.identity.v3.json import base
 
 
-class CredentialsClientJSON(base.IdentityV3Client):
+class CredentialsClientJSON(service_client.ServiceClient):
+    api_version = "v3"
 
     def create_credential(self, access_key, secret_key, user_id, project_id):
         """Creates a credential."""
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
index d71836e..5b7e812 100644
--- a/tempest/services/identity/v3/json/endpoints_client.py
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -16,10 +16,10 @@
 import json
 
 from tempest.common import service_client
-from tempest.services.identity.v3.json import base
 
 
-class EndPointClientJSON(base.IdentityV3Client):
+class EndPointClientJSON(service_client.ServiceClient):
+    api_version = "v3"
 
     def list_endpoints(self):
         """GET endpoints."""
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index f3d9d2d..be5aa80 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -17,13 +17,10 @@
 import urllib
 
 from tempest.common import service_client
-from tempest import config
-from tempest.services.identity.v3.json import base
-
-CONF = config.CONF
 
 
-class IdentityV3ClientJSON(base.IdentityV3Client):
+class IdentityV3ClientJSON(service_client.ServiceClient):
+    api_version = "v3"
 
     def create_user(self, user_name, password=None, project_id=None,
                     email=None, domain_id='default', **kwargs):
diff --git a/tempest/services/identity/v3/json/policy_client.py b/tempest/services/identity/v3/json/policy_client.py
index 25931c8..8c9c9ce 100644
--- a/tempest/services/identity/v3/json/policy_client.py
+++ b/tempest/services/identity/v3/json/policy_client.py
@@ -16,10 +16,10 @@
 import json
 
 from tempest.common import service_client
-from tempest.services.identity.v3.json import base
 
 
-class PolicyClientJSON(base.IdentityV3Client):
+class PolicyClientJSON(service_client.ServiceClient):
+    api_version = "v3"
 
     def create_policy(self, blob, type):
         """Creates a Policy."""
diff --git a/tempest/services/identity/v3/json/region_client.py b/tempest/services/identity/v3/json/region_client.py
index 482cbc6..faaf43c 100644
--- a/tempest/services/identity/v3/json/region_client.py
+++ b/tempest/services/identity/v3/json/region_client.py
@@ -17,10 +17,10 @@
 import urllib
 
 from tempest.common import service_client
-from tempest.services.identity.v3.json import base
 
 
-class RegionClientJSON(base.IdentityV3Client):
+class RegionClientJSON(service_client.ServiceClient):
+    api_version = "v3"
 
     def create_region(self, description, **kwargs):
         """Create region."""
diff --git a/tempest/services/identity/v3/json/service_client.py b/tempest/services/identity/v3/json/service_client.py
index 2e2df13..e039dc6 100644
--- a/tempest/services/identity/v3/json/service_client.py
+++ b/tempest/services/identity/v3/json/service_client.py
@@ -16,10 +16,10 @@
 import json
 
 from tempest.common import service_client
-from tempest.services.identity.v3.json import base
 
 
-class ServiceClientJSON(base.IdentityV3Client):
+class ServiceClientJSON(service_client.ServiceClient):
+    api_version = "v3"
 
     def update_service(self, service_id, **kwargs):
         """Updates a service."""
diff --git a/tempest/services/identity/v3/json/token_client.py b/tempest/services/identity/v3/json/token_client.py
index 14c4a0a..b0824a7 100644
--- a/tempest/services/identity/v3/json/token_client.py
+++ b/tempest/services/identity/v3/json/token_client.py
@@ -13,19 +13,21 @@
 #    under the License.
 
 import json
+from tempest_lib.common import rest_client
+from tempest_lib import exceptions as lib_exc
 
 from tempest.common import service_client
-from tempest import config
 from tempest import exceptions
 
-CONF = config.CONF
 
+class V3TokenClientJSON(rest_client.RestClient):
 
-class V3TokenClientJSON(service_client.ServiceClient):
-
-    def __init__(self):
-        super(V3TokenClientJSON, self).__init__(None, None, None)
-        auth_url = CONF.identity.uri_v3
+    def __init__(self, auth_url, disable_ssl_certificate_validation=None,
+                 ca_certs=None, trace_requests=None):
+        dscv = disable_ssl_certificate_validation
+        super(V3TokenClientJSON, self).__init__(
+            None, None, None, disable_ssl_certificate_validation=dscv,
+            ca_certs=ca_certs, trace_requests=trace_requests)
         if not auth_url:
             raise exceptions.InvalidConfiguration('you must specify a v3 uri '
                                                   'if using the v3 identity '
@@ -35,23 +37,22 @@
 
         self.auth_url = auth_url
 
-    def auth(self, user=None, password=None, tenant=None, user_type='id',
-             domain=None, token=None):
+    def auth(self, user=None, password=None, project=None, user_type='id',
+             user_domain=None, project_domain=None, token=None):
         """
         :param user: user id or name, as specified in user_type
-        :param domain: the user and tenant domain
+        :param user_domain: the user domain
+        :param project_domain: the project domain
         :param token: a token to re-scope.
 
         Accepts different combinations of credentials. Restrictions:
-        - tenant and domain are only name (no id)
-        - user domain and tenant domain are assumed identical
-        - domain scope is not supported here
+        - project and domain are only name (no id)
         Sample sample valid combinations:
         - token
-        - token, tenant, domain
+        - token, project, project_domain
         - user_id, password
-        - username, password, domain
-        - username, password, tenant, domain
+        - username, password, user_domain
+        - username, password, project, user_domain, project_domain
         Validation is left to the server side.
         """
         creds = {
@@ -78,13 +79,13 @@
                 id_obj['password']['user']['id'] = user
             else:
                 id_obj['password']['user']['name'] = user
-            if domain is not None:
-                _domain = dict(name=domain)
+            if user_domain is not None:
+                _domain = dict(name=user_domain)
                 id_obj['password']['user']['domain'] = _domain
-        if tenant is not None:
-            _domain = dict(name=domain)
-            project = dict(name=tenant, domain=_domain)
-            scope = dict(project=project)
+        if project is not None:
+            _domain = dict(name=project_domain)
+            _project = dict(name=project, domain=_domain)
+            scope = dict(project=_project)
             creds['auth']['scope'] = scope
 
         body = json.dumps(creds)
@@ -112,21 +113,22 @@
 
         if resp.status in [401, 403]:
             resp_body = json.loads(resp_body)
-            raise exceptions.Unauthorized(resp_body['error']['message'])
+            raise lib_exc.Unauthorized(resp_body['error']['message'])
         elif resp.status not in [200, 201, 204]:
             raise exceptions.IdentityError(
                 'Unexpected status code {0}'.format(resp.status))
 
         return resp, json.loads(resp_body)
 
-    def get_token(self, user, password, tenant, domain='Default',
-                  auth_data=False):
+    def get_token(self, user, password, project=None, project_domain='Default',
+                  user_domain='Default', auth_data=False):
         """
         :param user: username
         Returns (token id, token data) for supplied credentials
         """
-        body = self.auth(user, password, tenant, user_type='name',
-                         domain=domain)
+        body = self.auth(user, password, project, user_type='name',
+                         user_domain=user_domain,
+                         project_domain=project_domain)
 
         token = body.response.get('x-subject-token')
         if auth_data:
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index a7b8f63..50f75b3 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -20,29 +20,37 @@
 import time
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.common import glance_http
 from tempest.common import service_client
 from tempest.common.utils import misc as misc_utils
-from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 
-CONF = config.CONF
-
 LOG = logging.getLogger(__name__)
 
 
 class ImageClientJSON(service_client.ServiceClient):
 
-    def __init__(self, auth_provider):
+    def __init__(self, auth_provider, catalog_type, region, endpoint_type=None,
+                 build_interval=None, build_timeout=None,
+                 disable_ssl_certificate_validation=None,
+                 ca_certs=None, **kwargs):
         super(ImageClientJSON, self).__init__(
             auth_provider,
-            CONF.image.catalog_type,
-            CONF.image.region or CONF.identity.region,
-            endpoint_type=CONF.image.endpoint_type,
-            build_interval=CONF.image.build_interval,
-            build_timeout=CONF.image.build_timeout)
+            catalog_type,
+            region,
+            endpoint_type=endpoint_type,
+            build_interval=build_interval,
+            build_timeout=build_timeout,
+            disable_ssl_certificate_validation=(
+                disable_ssl_certificate_validation),
+            ca_certs=ca_certs,
+            **kwargs)
         self._http = None
+        self.dscv = disable_ssl_certificate_validation
+        self.ca_certs = ca_certs
 
     def _image_meta_from_headers(self, headers):
         meta = {'properties': {}}
@@ -110,11 +118,10 @@
             return None
 
     def _get_http(self):
-        dscv = CONF.identity.disable_ssl_certificate_validation
-        ca_certs = CONF.identity.ca_certificates_file
         return glance_http.HTTPClient(auth_provider=self.auth_provider,
                                       filters=self.filters,
-                                      insecure=dscv, ca_certs=ca_certs)
+                                      insecure=self.dscv,
+                                      ca_certs=self.ca_certs)
 
     def _create_with_data(self, headers, data):
         resp, body_iter = self.http.raw_request('POST', '/v1/images',
@@ -136,8 +143,7 @@
     @property
     def http(self):
         if self._http is None:
-            if CONF.service_available.glance:
-                self._http = self._get_http()
+            self._http = self._get_http()
         return self._http
 
     def create_image(self, name, container_format, disk_format, **kwargs):
@@ -237,13 +243,12 @@
         url = 'v1/images/%s' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        # We can't return a ResponseBody because the body is a string
-        return resp, body
+        return service_client.ResponseBodyData(resp, body)
 
     def is_resource_deleted(self, id):
         try:
             self.get_image_meta(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 4b1d52d..e55a824 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -17,33 +17,38 @@
 import urllib
 
 import jsonschema
+from tempest_lib import exceptions as lib_exc
 
 from tempest.common import glance_http
 from tempest.common import service_client
-from tempest import config
-from tempest import exceptions
-
-CONF = config.CONF
 
 
 class ImageClientV2JSON(service_client.ServiceClient):
 
-    def __init__(self, auth_provider):
+    def __init__(self, auth_provider, catalog_type, region, endpoint_type=None,
+                 build_interval=None, build_timeout=None,
+                 disable_ssl_certificate_validation=None, ca_certs=None,
+                 **kwargs):
         super(ImageClientV2JSON, self).__init__(
             auth_provider,
-            CONF.image.catalog_type,
-            CONF.image.region or CONF.identity.region,
-            endpoint_type=CONF.image.endpoint_type,
-            build_interval=CONF.image.build_interval,
-            build_timeout=CONF.image.build_timeout)
+            catalog_type,
+            region,
+            endpoint_type=endpoint_type,
+            build_interval=build_interval,
+            build_timeout=build_timeout,
+            disable_ssl_certificate_validation=(
+                disable_ssl_certificate_validation),
+            ca_certs=ca_certs,
+            **kwargs)
         self._http = None
+        self.dscv = disable_ssl_certificate_validation
+        self.ca_certs = ca_certs
 
     def _get_http(self):
-        dscv = CONF.identity.disable_ssl_certificate_validation
-        ca_certs = CONF.identity.ca_certificates_file
         return glance_http.HTTPClient(auth_provider=self.auth_provider,
                                       filters=self.filters,
-                                      insecure=dscv, ca_certs=ca_certs)
+                                      insecure=self.dscv,
+                                      ca_certs=self.ca_certs)
 
     def _validate_schema(self, body, type='image'):
         if type in ['image', 'images']:
@@ -56,8 +61,7 @@
     @property
     def http(self):
         if self._http is None:
-            if CONF.service_available.glance:
-                self._http = self._get_http()
+            self._http = self._get_http()
         return self._http
 
     def update_image(self, image_id, patch):
@@ -120,7 +124,7 @@
     def is_resource_deleted(self, id):
         try:
             self.get_image(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
@@ -141,8 +145,7 @@
         url = 'v2/images/%s/file' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        # We can't return a ResponseBody because the body is a string
-        return resp, body
+        return service_client.ResponseBodyData(resp, body)
 
     def add_image_tag(self, image_id, tag):
         url = 'v2/images/%s/tags/%s' % (image_id, tag)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index e92708c..87f1332 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -14,6 +14,8 @@
 import time
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.common import service_client
 from tempest.common.utils import misc
 from tempest import exceptions
@@ -211,7 +213,7 @@
             getattr(self, method)(id)
         except AttributeError:
             raise Exception("Unknown resource type %s " % resource_type)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
@@ -260,9 +262,8 @@
         # expecting response in form
         # {'resources': [ res1, res2] } => when pagination disabled
         # {'resources': [..], 'resources_links': {}} => if pagination enabled
-        pagination_suffix = "_links"
         for k in res.keys():
-            if k[-len(pagination_suffix):] == pagination_suffix:
+            if k.endswith("_links"):
                 continue
             return res[k]
 
@@ -318,6 +319,8 @@
                 cur_gw_info.pop('enable_snat', None)
         update_body['external_gateway_info'] = kwargs.get(
             'external_gateway_info', body['router']['external_gateway_info'])
+        if 'distributed' in kwargs:
+            update_body['distributed'] = kwargs['distributed']
         update_body = dict(router=update_body)
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index c813977..1a4c5d9 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -18,6 +18,8 @@
 import time
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.common import service_client
 from tempest import exceptions
 
@@ -159,7 +161,7 @@
             try:
                 body = self.get_resource(
                     stack_identifier, resource_name)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 # ignore this, as the resource may not have
                 # been created yet
                 pass
@@ -194,7 +196,7 @@
         while True:
             try:
                 body = self.get_stack(stack_identifier)
-            except exceptions.NotFound:
+            except lib_exc.NotFound:
                 if status == 'DELETE_COMPLETE':
                     return
             stack_name = body['stack_name']
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index dd899e4..a249625 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -127,7 +127,7 @@
         resp, body = self.get(uri)
         self.expected_success(200, resp.status)
         body = self.deserialize(body)
-        return resp, body
+        return service_client.ResponseBodyData(resp, body)
 
     def alarm_set_state(self, alarm_id, state):
         uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
@@ -135,4 +135,4 @@
         resp, body = self.put(uri, body)
         self.expected_success(200, resp.status)
         body = self.deserialize(body)
-        return resp, body
+        return service_client.ResponseBodyData(resp, body)
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
index 19d320f..616f8e4 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
 #
-# Author: Sylvain Baubeau <sylvain.baubeau@enovance.com>
-#
 #    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
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/json/admin/volume_types_client.py
index 6049eb6..c905155 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/json/admin/volume_types_client.py
@@ -19,7 +19,6 @@
 from tempest_lib import exceptions as lib_exc
 
 from tempest.common import service_client
-from tempest import exceptions
 
 
 class BaseVolumeTypesClientJSON(service_client.ServiceClient):
@@ -42,7 +41,7 @@
             else:
                 msg = (" resource value is either not defined or incorrect.")
                 raise lib_exc.UnprocessableEntity(msg)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
diff --git a/tempest/services/volume/json/qos_client.py b/tempest/services/volume/json/qos_client.py
index 6aa56f7..14ff506 100644
--- a/tempest/services/volume/json/qos_client.py
+++ b/tempest/services/volume/json/qos_client.py
@@ -27,7 +27,7 @@
     def is_resource_deleted(self, qos_id):
         try:
             self.get_qos(qos_id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index 100b34c..8430b63 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -14,6 +14,8 @@
 import time
 import urllib
 
+from tempest_lib import exceptions as lib_exc
+
 from tempest.common import service_client
 from tempest import exceptions
 from tempest.openstack.common import log as logging
@@ -127,7 +129,7 @@
     def is_resource_deleted(self, id):
         try:
             self.get_snapshot(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index d834905..059664c 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -17,11 +17,10 @@
 import time
 import urllib
 
-from tempest.common import service_client
-from tempest import config
-from tempest import exceptions
+from tempest_lib import exceptions as lib_exc
 
-CONF = config.CONF
+from tempest.common import service_client
+from tempest import exceptions
 
 
 class BaseVolumesClientJSON(service_client.ServiceClient):
@@ -31,6 +30,12 @@
 
     create_resp = 200
 
+    def __init__(self, auth_provider, service, region,
+                 default_volume_size=1, **kwargs):
+        super(BaseVolumesClientJSON, self).__init__(
+            auth_provider, service, region, **kwargs)
+        self.default_volume_size = default_volume_size
+
     def get_attachment_from_volume(self, volume):
         """Return the element 'attachment' from input volumes."""
         return volume['attachments'][0]
@@ -77,10 +82,8 @@
         snapshot_id: When specified the volume is created from this snapshot
         imageRef: When specified the volume is created from this image
         """
-        # for bug #1293885:
-        # If no size specified, read volume size from CONF
         if size is None:
-            size = CONF.volume.volume_size
+            size = self.default_volume_size
         post_body = {'size': size}
         post_body.update(kwargs)
         post_body = json.dumps({'volume': post_body})
@@ -181,7 +184,7 @@
     def is_resource_deleted(self, id):
         try:
             self.get_volume(id)
-        except exceptions.NotFound:
+        except lib_exc.NotFound:
             return True
         return False
 
@@ -333,6 +336,14 @@
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, body)
 
+    def retype_volume(self, volume_id, volume_type, **kwargs):
+        """Updates volume with new volume type."""
+        post_body = {'new_type': volume_type}
+        post_body.update(kwargs)
+        post_body = json.dumps({'os-retype': post_body})
+        resp, body = self.post('volumes/%s/action' % volume_id, post_body)
+        self.expected_success(202, resp.status)
+
 
 class VolumesClientJSON(BaseVolumesClientJSON):
     """
diff --git a/tempest/stress/actions/server_create_destroy.py b/tempest/stress/actions/server_create_destroy.py
index 34e299d..d0e4eea 100644
--- a/tempest/stress/actions/server_create_destroy.py
+++ b/tempest/stress/actions/server_create_destroy.py
@@ -28,7 +28,7 @@
     def run(self):
         name = data_utils.rand_name("instance")
         self.logger.info("creating %s" % name)
-        _, server = self.manager.servers_client.create_server(
+        server = self.manager.servers_client.create_server(
             name, self.image, self.flavor)
         server_id = server['id']
         self.manager.servers_client.wait_for_server_status(server_id,
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index c473df6..b2c612e 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -74,9 +74,9 @@
         self.logger.info("creating %s" % name)
         vm_args = self.vm_extra_args.copy()
         vm_args['security_groups'] = [self.sec_grp]
-        _, server = servers_client.create_server(name, self.image,
-                                                 self.flavor,
-                                                 **vm_args)
+        server = servers_client.create_server(name, self.image,
+                                              self.flavor,
+                                              **vm_args)
         self.server_id = server['id']
         if self.wait_after_vm_create:
             self.manager.servers_client.wait_for_server_status(self.server_id,
@@ -104,7 +104,7 @@
 
     def _create_floating_ip(self):
         floating_cli = self.manager.floating_ips_client
-        _, self.floating = floating_cli.create_floating_ip(self.floating_pool)
+        self.floating = floating_cli.create_floating_ip(self.floating_pool)
 
     def _destroy_floating_ip(self):
         cli = self.manager.floating_ips_client
@@ -144,7 +144,7 @@
         cli = self.manager.floating_ips_client
 
         def func():
-            _, floating = cli.get_floating_ip_details(self.floating['id'])
+            floating = cli.get_floating_ip_details(self.floating['id'])
             return floating['instance_id'] is None
 
         if not tempest.test.call_until_true(func, self.check_timeout,
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index 9c4070f..2e1d623 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -28,7 +28,7 @@
         # Step 1: create volume
         name = data_utils.rand_name("volume")
         self.logger.info("creating volume: %s" % name)
-        _, volume = self.manager.volumes_client.create_volume(
+        volume = self.manager.volumes_client.create_volume(
             size=1,
             display_name=name)
         self.manager.volumes_client.wait_for_volume_status(volume['id'],
@@ -38,7 +38,7 @@
         # Step 2: create vm instance
         vm_name = data_utils.rand_name("instance")
         self.logger.info("creating vm: %s" % vm_name)
-        _, server = self.manager.servers_client.create_server(
+        server = self.manager.servers_client.create_server(
             vm_name, self.image, self.flavor)
         server_id = server['id']
         self.manager.servers_client.wait_for_server_status(server_id, 'ACTIVE')
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index 3c052ac..c013af3 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -36,9 +36,9 @@
         vm_args = self.vm_extra_args.copy()
         vm_args['security_groups'] = [self.sec_grp]
         vm_args['key_name'] = self.key['name']
-        _, server = servers_client.create_server(name, self.image,
-                                                 self.flavor,
-                                                 **vm_args)
+        server = servers_client.create_server(name, self.image,
+                                              self.flavor,
+                                              **vm_args)
         self.server_id = server['id']
         self.manager.servers_client.wait_for_server_status(self.server_id,
                                                            'ACTIVE')
@@ -65,7 +65,7 @@
 
     def _create_floating_ip(self):
         floating_cli = self.manager.floating_ips_client
-        _, self.floating = floating_cli.create_floating_ip(self.floating_pool)
+        self.floating = floating_cli.create_floating_ip(self.floating_pool)
 
     def _destroy_floating_ip(self):
         cli = self.manager.floating_ips_client
@@ -77,7 +77,7 @@
         name = data_utils.rand_name("volume")
         self.logger.info("creating volume: %s" % name)
         volumes_client = self.manager.volumes_client
-        _, self.volume = volumes_client.create_volume(
+        self.volume = volumes_client.create_volume(
             size=1,
             display_name=name)
         volumes_client.wait_for_volume_status(self.volume['id'],
@@ -95,7 +95,7 @@
         cli = self.manager.floating_ips_client
 
         def func():
-            _, floating = cli.get_floating_ip_details(self.floating['id'])
+            floating = cli.get_floating_ip_details(self.floating['id'])
             return floating['instance_id'] is None
 
         if not tempest.test.call_until_true(func, CONF.compute.build_timeout,
diff --git a/tempest/stress/cleanup.py b/tempest/stress/cleanup.py
index b52eca9..161d93f 100644
--- a/tempest/stress/cleanup.py
+++ b/tempest/stress/cleanup.py
@@ -23,7 +23,7 @@
 def cleanup():
     admin_manager = clients.AdminManager()
 
-    _, body = admin_manager.servers_client.list_servers({"all_tenants": True})
+    body = admin_manager.servers_client.list_servers({"all_tenants": True})
     LOG.info("Cleanup::remove %s servers" % len(body['servers']))
     for s in body['servers']:
         try:
@@ -55,7 +55,7 @@
         except Exception:
             pass
 
-    _, floating_ips = admin_manager.floating_ips_client.list_floating_ips()
+    floating_ips = admin_manager.floating_ips_client.list_floating_ips()
     LOG.info("Cleanup::remove %s floating ips" % len(floating_ips))
     for f in floating_ips:
         try:
@@ -95,7 +95,7 @@
         except Exception:
             pass
 
-    _, vols = admin_manager.volumes_client.list_volumes({"all_tenants": True})
+    vols = admin_manager.volumes_client.list_volumes({"all_tenants": True})
     LOG.info("Cleanup::remove %s volumes" % len(vols))
     for v in vols:
         try:
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 49fac3d..1c27815 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -19,8 +19,8 @@
 
 from six import moves
 
-from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common import ssh
 from tempest.common.utils import data_utils
 from tempest import config
@@ -148,9 +148,9 @@
                                             password,
                                             tenant['id'],
                                             "email")
-                creds = auth.get_credentials(username=username,
-                                             password=password,
-                                             tenant_name=tenant_name)
+                creds = cred_provider.get_credentials(username=username,
+                                                      password=password,
+                                                      tenant_name=tenant_name)
                 manager = clients.Manager(credentials=creds)
 
             test_obj = importutils.import_class(test['action'])
diff --git a/tempest/test.py b/tempest/test.py
index 28e1e2c..f04aff7 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -24,6 +24,7 @@
 import uuid
 
 import fixtures
+import six
 import testscenarios
 import testtools
 
@@ -62,6 +63,23 @@
     return decorator
 
 
+def idempotent_id(id):
+    """Stub for metadata decorator"""
+    if not isinstance(id, six.string_types):
+        raise TypeError('Test idempotent_id must be string not %s'
+                        '' % type(id).__name__)
+    uuid.UUID(id)
+
+    def decorator(f):
+        f = testtools.testcase.attr('id-%s' % id)(f)
+        if f.__doc__:
+            f.__doc__ = 'Test idempotent id: %s\n%s' % (id, f.__doc__)
+        else:
+            f.__doc__ = 'Test idempotent id: %s' % id
+        return f
+    return decorator
+
+
 def get_service_list():
     service_list = {
         'compute': CONF.service_available.nova,
@@ -359,7 +377,7 @@
                                                    level=None))
 
     @classmethod
-    def get_client_manager(cls, interface=None):
+    def get_client_manager(cls):
         """
         Returns an OpenStack client manager
         """
@@ -373,12 +391,7 @@
             )
 
         creds = cls.isolated_creds.get_primary_creds()
-        params = dict(credentials=creds, service=cls._service)
-        if getattr(cls, '_interface', None):
-            interface = cls._interface
-        if interface:
-            params['interface'] = interface
-        os = clients.Manager(**params)
+        os = clients.Manager(credentials=creds, service=cls._service)
         return os
 
     @classmethod
@@ -394,13 +407,12 @@
         """
         Returns an instance of the Identity Admin API client
         """
-        os = clients.AdminManager(interface=cls._interface,
-                                  service=cls._service)
+        os = clients.AdminManager(service=cls._service)
         admin_client = os.identity_client
         return admin_client
 
     @classmethod
-    def set_network_resources(self, network=False, router=False, subnet=False,
+    def set_network_resources(cls, network=False, router=False, subnet=False,
                               dhcp=False):
         """Specify which network resources should be created
 
@@ -413,8 +425,8 @@
         # in order to ensure that even if it's called multiple times in
         # a chain of overloaded methods, the attribute is set only
         # in the leaf class
-        if not self.network_resources:
-            self.network_resources = {
+        if not cls.network_resources:
+            cls.network_resources = {
                 'network': network,
                 'router': router,
                 'subnet': subnet,
@@ -436,8 +448,7 @@
         super(NegativeAutoTest, cls).setUpClass()
         os = cls.get_client_manager()
         cls.client = os.negative_client
-        os_admin = clients.AdminManager(interface=cls._interface,
-                                        service=cls._service)
+        os_admin = clients.AdminManager(service=cls._service)
         cls.admin_client = os_admin.negative_client
 
     @staticmethod
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 1abe29a..17e2550 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -282,8 +282,8 @@
 
     def test_verify_extensions_nova(self):
         def fake_list_extensions():
-            return (None, [{'alias': 'fake1'}, {'alias': 'fake2'},
-                           {'alias': 'not_fake'}])
+            return ([{'alias': 'fake1'}, {'alias': 'fake2'},
+                     {'alias': 'not_fake'}])
         fake_os = mock.MagicMock()
         fake_os.extensions_client.list_extensions = fake_list_extensions
         self.useFixture(mockpatch.PatchObject(
@@ -303,9 +303,9 @@
 
     def test_verify_extensions_nova_all(self):
         def fake_list_extensions():
-            return (None, {'extensions': [{'alias': 'fake1'},
-                                          {'alias': 'fake2'},
-                                          {'alias': 'not_fake'}]})
+            return ({'extensions': [{'alias': 'fake1'},
+                                    {'alias': 'fake2'},
+                                    {'alias': 'not_fake'}]})
         fake_os = mock.MagicMock()
         fake_os.extensions_client.list_extensions = fake_list_extensions
         self.useFixture(mockpatch.PatchObject(
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index f45f2cf..1e6b651 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -24,7 +24,7 @@
 from tempest.common import accounts
 from tempest import config
 from tempest import exceptions
-from tempest.services.identity.json import token_client
+from tempest.services.identity.v2.json import token_client
 from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests import fake_identity
@@ -73,7 +73,8 @@
         test_account_class = accounts.Accounts('test_name')
         hash_list = self._get_hash_list(self.test_accounts)
         test_cred_dict = self.test_accounts[3]
-        test_creds = auth.get_credentials(**test_cred_dict)
+        test_creds = auth.get_credentials(fake_identity.FAKE_AUTH_URL,
+                                          **test_cred_dict)
         results = test_account_class.get_hash(test_creds)
         self.assertEqual(hash_list[3], results)
 
@@ -128,8 +129,9 @@
         # Emulate all lcoks in list are in use
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
         test_account_class = accounts.Accounts('test_name')
-        self.assertRaises(exceptions.InvalidConfiguration,
-                          test_account_class._get_free_hash, hash_list)
+        with mock.patch('__builtin__.open', mock.mock_open(), create=True):
+            self.assertRaises(exceptions.InvalidConfiguration,
+                              test_account_class._get_free_hash, hash_list)
 
     @mock.patch('tempest.openstack.common.lockutils.lock')
     def test_get_free_hash_some_in_use_accounts(self, lock_mock):
@@ -151,7 +153,7 @@
             test_account_class._get_free_hash(hash_list)
             lock_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
                                      hash_list[3])
-            open_mock.assert_called_once_with(lock_path, 'w')
+            open_mock.assert_has_calls([mock.call(lock_path, 'w')])
 
     @mock.patch('tempest.openstack.common.lockutils.lock')
     def test_remove_hash_last_account(self, lock_mock):
diff --git a/tempest/tests/common/test_cred_provider.py b/tempest/tests/common/test_cred_provider.py
new file mode 100644
index 0000000..3f7c0f8
--- /dev/null
+++ b/tempest/tests/common/test_cred_provider.py
@@ -0,0 +1,97 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from oslo.config import cfg
+
+from tempest import auth
+from tempest.common import cred_provider
+from tempest.common import tempest_fixtures as fixtures
+from tempest.services.identity.v2.json import token_client as v2_client
+from tempest.services.identity.v3.json import token_client as v3_client
+from tempest.tests import fake_identity
+# Note: eventually the auth module will move to tempest-lib, and so wil its
+# unit tests. *CredentialsTests will be imported from tempest-lib then.
+from tempest.tests import test_credentials as test_creds
+
+
+class ConfiguredV2CredentialsTests(test_creds.CredentialsTests):
+    attributes = {
+        'username': 'fake_username',
+        'password': 'fake_password',
+        'tenant_name': 'fake_tenant_name'
+    }
+
+    identity_response = fake_identity._fake_v2_response
+    credentials_class = auth.KeystoneV2Credentials
+    tokenclient_class = v2_client.TokenClientJSON
+    identity_version = 'v2'
+
+    def setUp(self):
+        super(ConfiguredV2CredentialsTests, self).setUp()
+        self.stubs.Set(self.tokenclient_class, 'raw_request',
+                       self.identity_response)
+
+    def _verify_credentials(self, credentials_class, filled=True,
+                            identity_version=None):
+        for ctype in cred_provider.CREDENTIAL_TYPES:
+            if identity_version is None:
+                creds = cred_provider.get_configured_credentials(
+                    credential_type=ctype, fill_in=filled)
+            else:
+                creds = cred_provider.get_configured_credentials(
+                    credential_type=ctype, fill_in=filled,
+                    identity_version=identity_version)
+            self._check(creds, credentials_class, filled)
+
+    def test_get_configured_credentials(self):
+        self.useFixture(fixtures.LockFixture('auth_version'))
+        self._verify_credentials(credentials_class=self.credentials_class)
+
+    def test_get_configured_credentials_unfilled(self):
+        self.useFixture(fixtures.LockFixture('auth_version'))
+        self._verify_credentials(credentials_class=self.credentials_class,
+                                 filled=False)
+
+    def test_get_configured_credentials_version(self):
+        # version specified and not loaded from config
+        self.useFixture(fixtures.LockFixture('auth_version'))
+        self._verify_credentials(credentials_class=self.credentials_class,
+                                 identity_version=self.identity_version)
+
+    def test_is_valid(self):
+        creds = self._get_credentials()
+        self.assertTrue(creds.is_valid())
+
+
+class ConfiguredV3CredentialsTests(ConfiguredV2CredentialsTests):
+    attributes = {
+        'username': 'fake_username',
+        'password': 'fake_password',
+        'project_name': 'fake_project_name',
+        'user_domain_name': 'fake_domain_name'
+    }
+
+    credentials_class = auth.KeystoneV3Credentials
+    identity_response = fake_identity._fake_v3_response
+    tokenclient_class = v3_client.V3TokenClientJSON
+    identity_version = 'v3'
+
+    def setUp(self):
+        super(ConfiguredV3CredentialsTests, self).setUp()
+        # Additional config items reset by cfg fixture after each test
+        cfg.CONF.set_default('auth_version', 'v3', group='identity')
+        # Identity group items
+        for prefix in ['', 'alt_', 'admin_']:
+            cfg.CONF.set_default(prefix + 'domain_name', 'fake_domain_name',
+                                 group='identity')
diff --git a/tempest/tests/common/test_custom_matchers.py b/tempest/tests/common/test_custom_matchers.py
index 57217e3..2656a47 100644
--- a/tempest/tests/common/test_custom_matchers.py
+++ b/tempest/tests/common/test_custom_matchers.py
@@ -63,4 +63,4 @@
          "  b: expected 2, actual None\n",
          {'a': 1, 'b': None, 'foo': 1},
          matches_matcher)
-    ]
\ No newline at end of file
+    ]
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index 2b31d6b..9bb58b0 100644
--- a/tempest/tests/common/test_service_clients.py
+++ b/tempest/tests/common/test_service_clients.py
@@ -43,8 +43,20 @@
 from tempest.services.compute.json import tenant_usages_client
 from tempest.services.compute.json import volumes_extensions_client \
     as compute_volumes_extensions_client
+from tempest.services.data_processing.v1_1 import data_processing_client
 from tempest.services.database.json import flavors_client as db_flavor_client
 from tempest.services.database.json import versions_client as db_version_client
+from tempest.services.identity.v2.json import identity_client as \
+    identity_v2_identity_client
+from tempest.services.identity.v3.json import credentials_client
+from tempest.services.identity.v3.json import endpoints_client
+from tempest.services.identity.v3.json import identity_client as \
+    identity_v3_identity_client
+from tempest.services.identity.v3.json import policy_client
+from tempest.services.identity.v3.json import region_client
+from tempest.services.identity.v3.json import service_client
+from tempest.services.image.v1.json import image_client
+from tempest.services.image.v2.json import image_client as image_v2_client
 from tempest.services.messaging.json import messaging_client
 from tempest.services.network.json import network_client
 from tempest.services.object_storage import account_client
@@ -117,6 +129,7 @@
             services_client.ServicesClientJSON,
             tenant_usages_client.TenantUsagesClientJSON,
             compute_volumes_extensions_client.VolumesExtensionsClientJSON,
+            data_processing_client.DataProcessingClient,
             db_flavor_client.DatabaseFlavorsClientJSON,
             db_version_client.DatabaseVersionsClientJSON,
             messaging_client.MessagingClientJSON,
@@ -146,6 +159,15 @@
             volume_v2_qos_client.QosSpecsV2ClientJSON,
             volume_v2_snapshots_client.SnapshotsV2ClientJSON,
             volume_v2_volumes_client.VolumesV2ClientJSON,
+            identity_v2_identity_client.IdentityClientJSON,
+            credentials_client.CredentialsClientJSON,
+            endpoints_client.EndPointClientJSON,
+            identity_v3_identity_client.IdentityV3ClientJSON,
+            policy_client.PolicyClientJSON,
+            region_client.RegionClientJSON,
+            service_client.ServiceClientJSON,
+            image_client.ImageClientJSON,
+            image_v2_client.ImageClientV2JSON
         ]
 
         for client in test_clients:
diff --git a/tempest/tests/fake_identity.py b/tempest/tests/fake_identity.py
index 97098e1..ad78f85 100644
--- a/tempest/tests/fake_identity.py
+++ b/tempest/tests/fake_identity.py
@@ -17,6 +17,7 @@
 
 import httplib2
 
+FAKE_AUTH_URL = 'http://fake_uri.com/auth'
 
 TOKEN = "fake_token"
 ALT_TOKEN = "alt_fake_token"
diff --git a/tempest/tests/negative/test_negative_auto_test.py b/tempest/tests/negative/test_negative_auto_test.py
index fb1da43..7a127cd 100644
--- a/tempest/tests/negative/test_negative_auto_test.py
+++ b/tempest/tests/negative/test_negative_auto_test.py
@@ -21,7 +21,6 @@
 
 class TestNegativeAutoTest(base.TestCase):
     # Fake entries
-    _interface = 'json'
     _service = 'compute'
 
     fake_input_desc = {"name": "list-flavors-with-detail",
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index 90bb8a7..f54ff4f 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -21,7 +21,7 @@
 from tempest import auth
 from tempest import config
 from tempest import exceptions
-from tempest.services.identity.json import token_client as v2_client
+from tempest.services.identity.v2.json import token_client as v2_client
 from tempest.services.identity.v3.json import token_client as v3_client
 from tempest.tests import base
 from tempest.tests import fake_config
@@ -30,11 +30,7 @@
 from tempest.tests import fake_identity
 
 
-def fake_get_default_credentials(credential_type, fill_in=True):
-    return fake_credentials.FakeCredentials()
-
-
-def fake_get_credentials(credential_type=None, fill_in=True, **kwargs):
+def fake_get_credentials(fill_in=True, identity_version='v2', **kwargs):
     return fake_credentials.FakeCredentials()
 
 
@@ -42,11 +38,11 @@
     _auth_provider_class = None
     credentials = fake_credentials.FakeCredentials()
 
-    def _auth(self, credentials, **params):
+    def _auth(self, credentials, auth_url, **params):
         """
         returns auth method according to keystone
         """
-        return self._auth_provider_class(credentials, **params)
+        return self._auth_provider_class(credentials, auth_url, **params)
 
     def setUp(self):
         super(BaseAuthTestsSetUp, self).setUp()
@@ -54,9 +50,8 @@
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.fake_http = fake_http.fake_httplib2(return_type=200)
         self.stubs.Set(auth, 'get_credentials', fake_get_credentials)
-        self.stubs.Set(auth, 'get_default_credentials',
-                       fake_get_default_credentials)
-        self.auth_provider = self._auth(self.credentials)
+        self.auth_provider = self._auth(self.credentials,
+                                        fake_identity.FAKE_AUTH_URL)
 
 
 class TestBaseAuthProvider(BaseAuthTestsSetUp):
@@ -84,14 +79,15 @@
 
     _auth_provider_class = FakeAuthProviderImpl
 
+    def _auth(self, credentials, auth_url, **params):
+        """
+        returns auth method according to keystone
+        """
+        return self._auth_provider_class(credentials, **params)
+
     def test_check_credentials_bad_type(self):
         self.assertFalse(self.auth_provider.check_credentials([]))
 
-    def test_instantiate_with_dict(self):
-        # Dict credentials are only supported for backward compatibility
-        auth_provider = self._auth(credentials={})
-        self.assertIsInstance(auth_provider.credentials, auth.Credentials)
-
     def test_auth_data_property_when_cache_exists(self):
         self.auth_provider.cache = 'foo'
         self.useFixture(mockpatch.PatchObject(self.auth_provider,
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index 6e447d6..350b190 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -15,13 +15,11 @@
 
 import copy
 
-from oslo.config import cfg
-
 from tempest import auth
 from tempest.common import tempest_fixtures as fixtures
 from tempest import config
 from tempest import exceptions
-from tempest.services.identity.json import token_client as v2_client
+from tempest.services.identity.v2.json import token_client as v2_client
 from tempest.services.identity.v3.json import token_client as v3_client
 from tempest.tests import base
 from tempest.tests import fake_config
@@ -37,6 +35,18 @@
             attributes = self.attributes
         return self.credentials_class(**attributes)
 
+    def _check(self, credentials, credentials_class, filled):
+        # Check the right version of credentials has been returned
+        self.assertIsInstance(credentials, credentials_class)
+        # Check the id attributes are filled in
+        attributes = [x for x in credentials.ATTRIBUTES if (
+            '_id' in x and x != 'domain_id')]
+        for attr in attributes:
+            if filled:
+                self.assertIsNotNone(getattr(credentials, attr))
+            else:
+                self.assertIsNone(getattr(credentials, attr))
+
     def setUp(self):
         super(CredentialsTests, self).setUp()
         self.useFixture(fake_config.ConfigFixture())
@@ -51,18 +61,6 @@
                           self._get_credentials,
                           attributes=dict(invalid='fake'))
 
-    def test_default(self):
-        self.useFixture(fixtures.LockFixture('auth_version'))
-        for ctype in self.credentials_class.TYPES:
-            self.assertRaises(NotImplementedError,
-                              self.credentials_class.get_default,
-                              credentials_type=ctype)
-
-    def test_invalid_default(self):
-        self.assertRaises(exceptions.InvalidCredentials,
-                          auth.Credentials.get_default,
-                          credentials_type='invalid_type')
-
     def test_is_valid(self):
         creds = self._get_credentials()
         self.assertRaises(NotImplementedError, creds.is_valid)
@@ -78,39 +76,19 @@
     identity_response = fake_identity._fake_v2_response
     credentials_class = auth.KeystoneV2Credentials
     tokenclient_class = v2_client.TokenClientJSON
+    identity_version = 'v2'
 
     def setUp(self):
         super(KeystoneV2CredentialsTests, self).setUp()
         self.stubs.Set(self.tokenclient_class, 'raw_request',
                        self.identity_response)
 
-    def _verify_credentials(self, credentials_class, filled=True,
-                            creds_dict=None):
-
-        def _check(credentials):
-            # Check the right version of credentials has been returned
-            self.assertIsInstance(credentials, credentials_class)
-            # Check the id attributes are filled in
-            attributes = [x for x in credentials.ATTRIBUTES if (
-                '_id' in x and x != 'domain_id')]
-            for attr in attributes:
-                if filled:
-                    self.assertIsNotNone(getattr(credentials, attr))
-                else:
-                    self.assertIsNone(getattr(credentials, attr))
-
-        if creds_dict is None:
-            for ctype in auth.Credentials.TYPES:
-                creds = auth.get_default_credentials(credential_type=ctype,
-                                                     fill_in=filled)
-                _check(creds)
-        else:
-            creds = auth.get_credentials(fill_in=filled, **creds_dict)
-            _check(creds)
-
-    def test_get_default_credentials(self):
-        self.useFixture(fixtures.LockFixture('auth_version'))
-        self._verify_credentials(credentials_class=self.credentials_class)
+    def _verify_credentials(self, credentials_class, creds_dict, filled=True):
+        creds = auth.get_credentials(fake_identity.FAKE_AUTH_URL,
+                                     fill_in=filled,
+                                     identity_version=self.identity_version,
+                                     **creds_dict)
+        self._check(creds, credentials_class, filled)
 
     def test_get_credentials(self):
         self.useFixture(fixtures.LockFixture('auth_version'))
@@ -120,8 +98,8 @@
     def test_get_credentials_not_filled(self):
         self.useFixture(fixtures.LockFixture('auth_version'))
         self._verify_credentials(credentials_class=self.credentials_class,
-                                 filled=False,
-                                 creds_dict=self.attributes)
+                                 creds_dict=self.attributes,
+                                 filled=False)
 
     def test_is_valid(self):
         creds = self._get_credentials()
@@ -144,15 +122,6 @@
         # credential requirements
         self._test_is_not_valid('tenant_name')
 
-    def test_default(self):
-        self.useFixture(fixtures.LockFixture('auth_version'))
-        for ctype in self.credentials_class.TYPES:
-            creds = self.credentials_class.get_default(credentials_type=ctype)
-            for attr in self.attributes.keys():
-                # Default configuration values related to credentials
-                # are defined as fake_* in fake_config.py
-                self.assertEqual(getattr(creds, attr), 'fake_' + attr)
-
     def test_reset_all_attributes(self):
         creds = self._get_credentials()
         initial_creds = copy.deepcopy(creds)
@@ -189,28 +158,7 @@
     credentials_class = auth.KeystoneV3Credentials
     identity_response = fake_identity._fake_v3_response
     tokenclient_class = v3_client.V3TokenClientJSON
-
-    def setUp(self):
-        super(KeystoneV3CredentialsTests, self).setUp()
-        # Additional config items reset by cfg fixture after each test
-        cfg.CONF.set_default('auth_version', 'v3', group='identity')
-        # Identity group items
-        for prefix in ['', 'alt_', 'admin_']:
-            cfg.CONF.set_default(prefix + 'domain_name', 'fake_domain_name',
-                                 group='identity')
-
-    def test_default(self):
-        self.useFixture(fixtures.LockFixture('auth_version'))
-        for ctype in self.credentials_class.TYPES:
-            creds = self.credentials_class.get_default(credentials_type=ctype)
-            for attr in self.attributes.keys():
-                if attr == 'project_name':
-                    config_value = 'fake_tenant_name'
-                elif attr == 'user_domain_name':
-                    config_value = 'fake_domain_name'
-                else:
-                    config_value = 'fake_' + attr
-                self.assertEqual(getattr(creds, attr), config_value)
+    identity_version = 'v3'
 
     def test_is_not_valid(self):
         # NOTE(mtreinish) For a Keystone V3 credential object a project name
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index 1f1835e..5149ba6 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -12,6 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
 
 import mock
 from oslo.config import cfg
@@ -64,6 +65,43 @@
         self._test_attr_helper(expected_attrs=['foo'], type=['foo', 'foo'])
 
 
+class TestIdempotentIdDecorator(BaseDecoratorsTest):
+
+    def _test_helper(self, _id, **decorator_args):
+        @test.idempotent_id(_id)
+        def foo():
+            """Docstring"""
+            pass
+
+        return foo
+
+    def _test_helper_without_doc(self, _id, **decorator_args):
+        @test.idempotent_id(_id)
+        def foo():
+            pass
+
+        return foo
+
+    def test_positive(self):
+        _id = str(uuid.uuid4())
+        foo = self._test_helper(_id)
+        self.assertIn('id-%s' % _id, getattr(foo, '__testtools_attrs'))
+        self.assertTrue(foo.__doc__.startswith('Test idempotent id: %s' % _id))
+
+    def test_positive_without_doc(self):
+        _id = str(uuid.uuid4())
+        foo = self._test_helper_without_doc(_id)
+        self.assertTrue(foo.__doc__.startswith('Test idempotent id: %s' % _id))
+
+    def test_idempotent_id_not_str(self):
+        _id = 42
+        self.assertRaises(TypeError, self._test_helper, _id)
+
+    def test_idempotent_id_not_valid_uuid(self):
+        _id = '42'
+        self.assertRaises(ValueError, self._test_helper, _id)
+
+
 class TestServicesDecorator(BaseDecoratorsTest):
     def _test_services_helper(self, *decorator_args):
         class TestFoo(test.BaseTestCase):
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index 6c80496..ab76a93 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -20,8 +20,9 @@
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common.fixture import mockpatch
-from tempest.services.identity.json import identity_client as json_iden_client
-from tempest.services.identity.json import token_client as json_token_client
+from tempest.services.identity.v2.json import identity_client as \
+    json_iden_client
+from tempest.services.identity.v2.json import token_client as json_token_client
 from tempest.services.network.json import network_client as json_network_client
 from tempest.tests import base
 from tempest.tests import fake_config
@@ -175,10 +176,10 @@
         self._mock_list_roles('123456', 'admin')
         iso_creds.get_admin_creds()
         user_mock = self.patch(
-            'tempest.services.identity.json.identity_client.'
+            'tempest.services.identity.v2.json.identity_client.'
             'IdentityClientJSON.delete_user')
         tenant_mock = self.patch(
-            'tempest.services.identity.json.identity_client.'
+            'tempest.services.identity.v2.json.identity_client.'
             'IdentityClientJSON.delete_tenant')
         iso_creds.clear_isolated_creds()
         # Verify user delete calls
@@ -293,9 +294,9 @@
         router_fix = self._mock_router_create('123456', 'fake_admin_router')
         self._mock_list_roles('123456', 'admin')
         iso_creds.get_admin_creds()
-        self.patch('tempest.services.identity.json.identity_client.'
+        self.patch('tempest.services.identity.v2.json.identity_client.'
                    'IdentityClientJSON.delete_user')
-        self.patch('tempest.services.identity.json.identity_client.'
+        self.patch('tempest.services.identity.v2.json.identity_client.'
                    'IdentityClientJSON.delete_tenant')
         net = mock.patch.object(iso_creds.network_admin_client,
                                 'delete_network')
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index edd9de1..5b2ed70 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -201,10 +201,14 @@
             raise cls.skipException("The EC2 API is not available")
 
     @classmethod
+    def setup_credentials(cls):
+        super(BotoTestCase, cls).setup_credentials()
+        cls.os = cls.get_client_manager()
+
+    @classmethod
     def resource_setup(cls):
         super(BotoTestCase, cls).resource_setup()
         cls.conclusion = decision_maker()
-        cls.os = cls.get_client_manager()
         # The trash contains cleanup functions and paramaters in tuples
         # (function, *args, **kwargs)
         cls._resource_trash_bin = {}
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 707590e..39767a4 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -18,6 +18,7 @@
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 from tempest.thirdparty.boto.utils import s3
 from tempest.thirdparty.boto.utils import wait
@@ -30,13 +31,17 @@
 class InstanceRunTest(boto_test.BotoTestCase):
 
     @classmethod
+    def setup_clients(cls):
+        super(InstanceRunTest, cls).setup_clients()
+        cls.s3_client = cls.os.s3_client
+        cls.ec2_client = cls.os.ec2api_client
+
+    @classmethod
     def resource_setup(cls):
         super(InstanceRunTest, cls).resource_setup()
         if not cls.conclusion['A_I_IMAGES_READY']:
             raise cls.skipException("".join(("EC2 ", cls.__name__,
                                     ": requires ami/aki/ari manifest")))
-        cls.s3_client = cls.os.s3_client
-        cls.ec2_client = cls.os.ec2api_client
         cls.zone = CONF.boto.aws_zone
         cls.materials_path = CONF.boto.s3_materials_path
         ami_manifest = CONF.boto.ami_manifest
@@ -87,6 +92,7 @@
             self.assertInstanceStateWait(instance, '_GONE')
         self.cancelResourceCleanUp(rcuk)
 
+    @test.idempotent_id('c881fbb7-d56e-4054-9d76-1c3a60a207b0')
     def test_run_idempotent_instances(self):
         # EC2 run instances idempotently
 
@@ -119,6 +125,7 @@
         self._terminate_reservation(reservation_1, rcuk_1)
         self._terminate_reservation(reservation_2, rcuk_2)
 
+    @test.idempotent_id('2ea26a39-f96c-48fc-8374-5c10ec184c67')
     def test_run_stop_terminate_instance(self):
         # EC2 run, stop and terminate instance
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -141,6 +148,7 @@
 
         self._terminate_reservation(reservation, rcuk)
 
+    @test.idempotent_id('3d77225a-5cec-4e54-a017-9ebf11a266e6')
     def test_run_stop_terminate_instance_with_tags(self):
         # EC2 run, stop and terminate instance with tags
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -193,6 +201,7 @@
 
         self._terminate_reservation(reservation, rcuk)
 
+    @test.idempotent_id('252945b5-3294-4fda-ae21-928a42f63f76')
     def test_run_terminate_instance(self):
         # EC2 run, terminate immediately
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -205,6 +214,7 @@
             instance.terminate()
         self.assertInstanceStateWait(instance, '_GONE')
 
+    @test.idempotent_id('ab836c29-737b-4101-9fb9-87045eaf89e9')
     def test_compute_with_volumes(self):
         # EC2 1. integration test (not strict)
         image_ami = self.ec2_client.get_image(self.images["ami"]["image_id"])
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index be5db55..acf797a 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
@@ -25,12 +26,17 @@
 class EC2KeysTest(boto_test.BotoTestCase):
 
     @classmethod
+    def setup_clients(cls):
+        super(EC2KeysTest, cls).setup_clients()
+        cls.client = cls.os.ec2api_client
+
+    @classmethod
     def resource_setup(cls):
         super(EC2KeysTest, cls).resource_setup()
-        cls.client = cls.os.ec2api_client
         cls.ec = cls.ec2_error_code
 
 # TODO(afazekas): merge create, delete, get test cases
+    @test.idempotent_id('54236804-01b7-4cfe-a6f9-bce1340feec8')
     def test_create_ec2_keypair(self):
         # EC2 create KeyPair
         key_name = data_utils.rand_name("keypair-")
@@ -39,6 +45,7 @@
         self.assertTrue(compare_key_pairs(keypair,
                         self.client.get_key_pair(key_name)))
 
+    @test.idempotent_id('3283b898-f90c-4952-b238-3e42b8c3f34f')
     def test_delete_ec2_keypair(self):
         # EC2 delete KeyPair
         key_name = data_utils.rand_name("keypair-")
@@ -46,6 +53,7 @@
         self.client.delete_key_pair(key_name)
         self.assertIsNone(self.client.get_key_pair(key_name))
 
+    @test.idempotent_id('fd89bd26-4d4d-4cf3-a303-65dd9158fcdc')
     def test_get_ec2_keypair(self):
         # EC2 get KeyPair
         key_name = data_utils.rand_name("keypair-")
@@ -54,6 +62,7 @@
         self.assertTrue(compare_key_pairs(keypair,
                         self.client.get_key_pair(key_name)))
 
+    @test.idempotent_id('daa73da1-e11c-4558-8d76-a716be79a401')
     def test_duplicate_ec2_keypair(self):
         # EC2 duplicate KeyPair
         key_name = data_utils.rand_name("keypair-")
diff --git a/tempest/thirdparty/boto/test_ec2_network.py b/tempest/thirdparty/boto/test_ec2_network.py
index 132a5a8..ce20156 100644
--- a/tempest/thirdparty/boto/test_ec2_network.py
+++ b/tempest/thirdparty/boto/test_ec2_network.py
@@ -13,17 +13,19 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
 class EC2NetworkTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(EC2NetworkTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(EC2NetworkTest, cls).setup_clients()
         cls.ec2_client = cls.os.ec2api_client
 
     # Note(afazekas): these tests for things duable without an instance
+    @test.idempotent_id('48b912af-9403-4b4f-aa69-fa76d690a81f')
     def test_disassociate_not_associated_floating_ip(self):
         # EC2 disassociate not associated floating ip
         ec2_codes = self.ec2_error_code
diff --git a/tempest/thirdparty/boto/test_ec2_security_groups.py b/tempest/thirdparty/boto/test_ec2_security_groups.py
index fb3d32b..7f9568b 100644
--- a/tempest/thirdparty/boto/test_ec2_security_groups.py
+++ b/tempest/thirdparty/boto/test_ec2_security_groups.py
@@ -14,16 +14,18 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
 class EC2SecurityGroupTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(EC2SecurityGroupTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(EC2SecurityGroupTest, cls).setup_clients()
         cls.client = cls.os.ec2api_client
 
+    @test.idempotent_id('519b566e-0c38-4629-905e-7d6b6355f524')
     def test_create_authorize_security_group(self):
         # EC2 Create, authorize/revoke security group
         group_name = data_utils.rand_name("securty_group-")
diff --git a/tempest/thirdparty/boto/test_ec2_volumes.py b/tempest/thirdparty/boto/test_ec2_volumes.py
index 9cee8a4..318e8e3 100644
--- a/tempest/thirdparty/boto/test_ec2_volumes.py
+++ b/tempest/thirdparty/boto/test_ec2_volumes.py
@@ -15,6 +15,7 @@
 
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 CONF = config.CONF
@@ -29,16 +30,23 @@
 class EC2VolumesTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(EC2VolumesTest, cls).resource_setup()
-
+    def skip_checks(cls):
+        super(EC2VolumesTest, cls).skip_checks()
         if not CONF.service_available.cinder:
             skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
+    @classmethod
+    def setup_clients(cls):
+        super(EC2VolumesTest, cls).setup_clients()
         cls.client = cls.os.ec2api_client
+
+    @classmethod
+    def resource_setup(cls):
+        super(EC2VolumesTest, cls).resource_setup()
         cls.zone = CONF.boto.aws_zone
 
+    @test.idempotent_id('663f0077-c743-48ad-8ae0-46821cbc0918')
     def test_create_get_delete(self):
         # EC2 Create, get, delete Volume
         volume = self.client.create_volume(1, self.zone)
@@ -51,6 +59,7 @@
         self.client.delete_volume(volume.id)
         self.cancelResourceCleanUp(cuk)
 
+    @test.idempotent_id('c6b60d7a-1af7-4f8e-af21-d539d9496149')
     def test_create_volume_from_snapshot(self):
         # EC2 Create volume from snapshot
         volume = self.client.create_volume(1, self.zone)
diff --git a/tempest/thirdparty/boto/test_s3_buckets.py b/tempest/thirdparty/boto/test_s3_buckets.py
index 342fc0e..bf04803 100644
--- a/tempest/thirdparty/boto/test_s3_buckets.py
+++ b/tempest/thirdparty/boto/test_s3_buckets.py
@@ -14,16 +14,18 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
 class S3BucketsTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(S3BucketsTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(S3BucketsTest, cls).setup_clients()
         cls.client = cls.os.s3_client
 
+    @test.idempotent_id('4678525d-8da0-4518-81c1-f1f67d595b00')
     def test_create_and_get_delete_bucket(self):
         # S3 Create, get and delete bucket
         bucket_name = data_utils.rand_name("s3bucket-")
diff --git a/tempest/thirdparty/boto/test_s3_ec2_images.py b/tempest/thirdparty/boto/test_s3_ec2_images.py
index f5dec95..21ea984 100644
--- a/tempest/thirdparty/boto/test_s3_ec2_images.py
+++ b/tempest/thirdparty/boto/test_s3_ec2_images.py
@@ -17,6 +17,7 @@
 
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 from tempest.thirdparty.boto.utils import s3
 
@@ -26,13 +27,17 @@
 class S3ImagesTest(boto_test.BotoTestCase):
 
     @classmethod
+    def setup_clients(cls):
+        super(S3ImagesTest, cls).setup_clients()
+        cls.s3_client = cls.os.s3_client
+        cls.images_client = cls.os.ec2api_client
+
+    @classmethod
     def resource_setup(cls):
         super(S3ImagesTest, cls).resource_setup()
         if not cls.conclusion['A_I_IMAGES_READY']:
             raise cls.skipException("".join(("EC2 ", cls.__name__,
                                     ": requires ami/aki/ari manifest")))
-        cls.s3_client = cls.os.s3_client
-        cls.images_client = cls.os.ec2api_client
         cls.materials_path = CONF.boto.s3_materials_path
         cls.ami_manifest = CONF.boto.ami_manifest
         cls.aki_manifest = CONF.boto.aki_manifest
@@ -47,6 +52,7 @@
                                cls.bucket_name)
         s3.s3_upload_dir(bucket, cls.materials_path)
 
+    @test.idempotent_id('f9d360a5-0188-4c77-9db2-4c34c28d12a5')
     def test_register_get_deregister_ami_image(self):
         # Register and deregister ami image
         image = {"name": data_utils.rand_name("ami-name-"),
@@ -70,6 +76,7 @@
             self.images_client.get_all_images()))
         self.cancelResourceCleanUp(image["cleanUp"])
 
+    @test.idempotent_id('42cca5b0-453b-4618-b99f-dbc039db426f')
     def test_register_get_deregister_aki_image(self):
         # Register and deregister aki image
         image = {"name": data_utils.rand_name("aki-name-"),
@@ -93,6 +100,7 @@
             self.images_client.get_all_images()))
         self.cancelResourceCleanUp(image["cleanUp"])
 
+    @test.idempotent_id('1359e860-841c-43bb-80f3-bb389cbfd81d')
     def test_register_get_deregister_ari_image(self):
         # Register and deregister ari image
         image = {"name": data_utils.rand_name("ari-name-"),
diff --git a/tempest/thirdparty/boto/test_s3_objects.py b/tempest/thirdparty/boto/test_s3_objects.py
index 43774c2..2d8152d 100644
--- a/tempest/thirdparty/boto/test_s3_objects.py
+++ b/tempest/thirdparty/boto/test_s3_objects.py
@@ -18,16 +18,18 @@
 import boto.s3.key
 
 from tempest.common.utils import data_utils
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
 class S3BucketsTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(S3BucketsTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(S3BucketsTest, cls).setup_clients()
         cls.client = cls.os.s3_client
 
+    @test.idempotent_id('4eea567a-b46a-405b-a475-6097e1faebde')
     def test_create_get_delete_object(self):
         # S3 Create, get and delete object
         bucket_name = data_utils.rand_name("s3bucket-")
diff --git a/test-requirements.txt b/test-requirements.txt
index 6eefeee..6a9111e 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,7 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-hacking>=0.9.2,<0.10
+hacking<0.11,>=0.10.0
 # needed for doc build
 sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
 python-subunit>=0.0.18
diff --git a/tools/check_uuid.py b/tools/check_uuid.py
new file mode 100644
index 0000000..541e6c3
--- /dev/null
+++ b/tools/check_uuid.py
@@ -0,0 +1,354 @@
+# Copyright 2014 Mirantis, Inc.
+#
+# 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 argparse
+import ast
+import importlib
+import inspect
+import os
+import sys
+import unittest
+import urllib
+import uuid
+
+DECORATOR_MODULE = 'test'
+DECORATOR_NAME = 'idempotent_id'
+DECORATOR_IMPORT = 'tempest.%s' % DECORATOR_MODULE
+IMPORT_LINE = 'from tempest import %s' % DECORATOR_MODULE
+DECORATOR_TEMPLATE = "@%s.%s('%%s')" % (DECORATOR_MODULE,
+                                        DECORATOR_NAME)
+UNIT_TESTS_EXCLUDE = 'tempest.tests'
+
+
+class SourcePatcher(object):
+
+    """"Lazy patcher for python source files"""
+
+    def __init__(self):
+        self.source_files = None
+        self.patches = None
+        self.clear()
+
+    def clear(self):
+        """Clear inner state"""
+        self.source_files = {}
+        self.patches = {}
+
+    @staticmethod
+    def _quote(s):
+        return urllib.quote(s)
+
+    @staticmethod
+    def _unquote(s):
+        return urllib.unquote(s)
+
+    def add_patch(self, filename, patch, line_no):
+        """Add lazy patch"""
+        if filename not in self.source_files:
+            with open(filename) as f:
+                self.source_files[filename] = self._quote(f.read())
+        patch_id = str(uuid.uuid4())
+        if not patch.endswith('\n'):
+            patch += '\n'
+        self.patches[patch_id] = self._quote(patch)
+        lines = self.source_files[filename].split(self._quote('\n'))
+        lines[line_no - 1] = ''.join(('{%s:s}' % patch_id, lines[line_no - 1]))
+        self.source_files[filename] = self._quote('\n').join(lines)
+
+    def _save_changes(self, filename, source):
+        print('%s fixed' % filename)
+        with open(filename, 'w') as f:
+            f.write(source)
+
+    def apply_patches(self):
+        """Apply all patches"""
+        for filename in self.source_files:
+            patched_source = self._unquote(
+                self.source_files[filename].format(**self.patches)
+            )
+            self._save_changes(filename, patched_source)
+        self.clear()
+
+
+class TestChecker(object):
+
+    def __init__(self, package):
+        self.package = package
+        self.base_path = os.path.abspath(os.path.dirname(package.__file__))
+
+    def _path_to_package(self, path):
+        relative_path = path[len(self.base_path) + 1:]
+        if relative_path:
+            return '.'.join((self.package.__name__,) +
+                            tuple(relative_path.split('/')))
+        else:
+            return self.package.__name__
+
+    def _modules_search(self):
+        """Recursive search for python modules in base package"""
+        modules = []
+        for root, dirs, files in os.walk(self.base_path):
+            if not os.path.exists(os.path.join(root, '__init__.py')):
+                continue
+            root_package = self._path_to_package(root)
+            for item in files:
+                if item.endswith('.py'):
+                    module_name = '.'.join((root_package,
+                                           os.path.splitext(item)[0]))
+                    if not module_name.startswith(UNIT_TESTS_EXCLUDE):
+                        modules.append(module_name)
+        return modules
+
+    @staticmethod
+    def _get_idempotent_id(test_node):
+        """
+        Return key-value dict with all metadata from @test.idempotent_id
+        decorators for test method
+        """
+        idempotent_id = None
+        for decorator in test_node.decorator_list:
+            if (hasattr(decorator, 'func') and
+                    decorator.func.attr == DECORATOR_NAME and
+                    decorator.func.value.id == DECORATOR_MODULE):
+                for arg in decorator.args:
+                    idempotent_id = ast.literal_eval(arg)
+        return idempotent_id
+
+    @staticmethod
+    def _is_decorator(line):
+        return line.strip().startswith('@')
+
+    @staticmethod
+    def _is_def(line):
+        return line.strip().startswith('def ')
+
+    def _add_uuid_to_test(self, patcher, test_node, source_path):
+        with open(source_path) as src:
+            src_lines = src.read().split('\n')
+        lineno = test_node.lineno
+        insert_position = lineno
+        while True:
+            if (self._is_def(src_lines[lineno - 1]) or
+                    (self._is_decorator(src_lines[lineno - 1]) and
+                        (DECORATOR_TEMPLATE.split('(')[0] <=
+                            src_lines[lineno - 1].strip().split('(')[0]))):
+                insert_position = lineno
+                break
+            lineno += 1
+        patcher.add_patch(
+            source_path,
+            ' ' * test_node.col_offset + DECORATOR_TEMPLATE % uuid.uuid4(),
+            insert_position
+        )
+
+    @staticmethod
+    def _is_test_case(module, node):
+        if (node.__class__ is ast.ClassDef and
+                hasattr(module, node.name) and
+                inspect.isclass(getattr(module, node.name))):
+            return issubclass(getattr(module, node.name), unittest.TestCase)
+
+    @staticmethod
+    def _is_test_method(node):
+        return (node.__class__ is ast.FunctionDef
+                and node.name.startswith('test_'))
+
+    @staticmethod
+    def _next_node(body, node):
+        if body.index(node) < len(body):
+            return body[body.index(node) + 1]
+
+    @staticmethod
+    def _import_name(node):
+        if type(node) == ast.Import:
+            return node.names[0].name
+        elif type(node) == ast.ImportFrom:
+            return '%s.%s' % (node.module, node.names[0].name)
+
+    def _add_import_for_test_uuid(self, patcher, src_parsed, source_path):
+        with open(source_path) as f:
+            src_lines = f.read().split('\n')
+        line_no = 0
+        tempest_imports = [node for node in src_parsed.body
+                           if self._import_name(node) and
+                           'tempest.' in self._import_name(node)]
+        if not tempest_imports:
+            import_snippet = '\n'.join(('', IMPORT_LINE, ''))
+        else:
+            for node in tempest_imports:
+                if self._import_name(node) < DECORATOR_IMPORT:
+                    continue
+                else:
+                    line_no = node.lineno
+                    import_snippet = IMPORT_LINE
+                    break
+            else:
+                line_no = tempest_imports[-1].lineno
+                while True:
+                    if (not src_lines[line_no - 1] or
+                            getattr(self._next_node(src_parsed.body,
+                                                    tempest_imports[-1]),
+                                    'lineno') == line_no or
+                            line_no == len(src_lines)):
+                        break
+                    line_no += 1
+                import_snippet = '\n'.join((IMPORT_LINE, ''))
+        patcher.add_patch(source_path, import_snippet, line_no)
+
+    def get_tests(self):
+        """Get test methods with sources from base package with metadata"""
+        tests = {}
+        for module_name in self._modules_search():
+            tests[module_name] = {}
+            module = importlib.import_module(module_name)
+            source_path = '.'.join(
+                (os.path.splitext(module.__file__)[0], 'py')
+            )
+            with open(source_path, 'r') as f:
+                source = f.read()
+            tests[module_name]['source_path'] = source_path
+            tests[module_name]['tests'] = {}
+            source_parsed = ast.parse(source)
+            tests[module_name]['ast'] = source_parsed
+            tests[module_name]['import_valid'] = (
+                hasattr(module, DECORATOR_MODULE) and
+                inspect.ismodule(getattr(module, DECORATOR_MODULE))
+            )
+            test_cases = (node for node in source_parsed.body
+                          if self._is_test_case(module, node))
+            for node in test_cases:
+                for subnode in filter(self._is_test_method, node.body):
+                        test_name = '%s.%s' % (node.name, subnode.name)
+                        tests[module_name]['tests'][test_name] = subnode
+        return tests
+
+    @staticmethod
+    def _filter_tests(function, tests):
+        """Filter tests with condition 'function(test_node) == True'"""
+        result = {}
+        for module_name in tests:
+            for test_name in tests[module_name]['tests']:
+                if function(module_name, test_name, tests):
+                    if module_name not in result:
+                        result[module_name] = {
+                            'ast': tests[module_name]['ast'],
+                            'source_path': tests[module_name]['source_path'],
+                            'import_valid': tests[module_name]['import_valid'],
+                            'tests': {}
+                        }
+                    result[module_name]['tests'][test_name] = \
+                        tests[module_name]['tests'][test_name]
+        return result
+
+    def find_untagged(self, tests):
+        """Filter all tests without uuid in metadata"""
+        def check_uuid_in_meta(module_name, test_name, tests):
+            idempotent_id = self._get_idempotent_id(
+                tests[module_name]['tests'][test_name])
+            return not idempotent_id
+        return self._filter_tests(check_uuid_in_meta, tests)
+
+    def report_collisions(self, tests):
+        """Reports collisions if there are any. Returns true if
+        collisions exist.
+        """
+        uuids = {}
+
+        def report(module_name, test_name, tests):
+            test_uuid = self._get_idempotent_id(
+                tests[module_name]['tests'][test_name])
+            if not test_uuid:
+                return
+            if test_uuid in uuids:
+                error_str = "%s:%s\n uuid %s collision: %s<->%s\n%s:%s\n" % (
+                    tests[module_name]['source_path'],
+                    tests[module_name]['tests'][test_name].lineno,
+                    test_uuid,
+                    test_name,
+                    uuids[test_uuid]['test_name'],
+                    uuids[test_uuid]['source_path'],
+                    uuids[test_uuid]['test_node'].lineno,
+                )
+                print(error_str)
+                return True
+            else:
+                uuids[test_uuid] = {
+                    'module': module_name,
+                    'test_name': test_name,
+                    'test_node': tests[module_name]['tests'][test_name],
+                    'source_path': tests[module_name]['source_path']
+                }
+        return bool(self._filter_tests(report, tests))
+
+    def report_untagged(self, tests):
+        """Reports untagged tests if there are any. Returns true if
+        untagged tests exist.
+        """
+        def report(module_name, test_name, tests):
+            error_str = "%s:%s\nmissing @test.idempotent_id('...')\n%s\n" % (
+                tests[module_name]['source_path'],
+                tests[module_name]['tests'][test_name].lineno,
+                test_name
+            )
+            print(error_str)
+            return True
+        return bool(self._filter_tests(report, tests))
+
+    def fix_tests(self, tests):
+        """Add uuids to all tests specified in tests and
+        fix it in source files
+        """
+        patcher = SourcePatcher()
+        for module_name in tests:
+            add_import_once = True
+            for test_name in tests[module_name]['tests']:
+                if not tests[module_name]['import_valid'] and add_import_once:
+                    self._add_import_for_test_uuid(
+                        patcher,
+                        tests[module_name]['ast'],
+                        tests[module_name]['source_path']
+                    )
+                    add_import_once = False
+                self._add_uuid_to_test(
+                    patcher, tests[module_name]['tests'][test_name],
+                    tests[module_name]['source_path'])
+        patcher.apply_patches()
+
+
+def run():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--package', action='store', dest='package',
+                        default='tempest', type=str,
+                        help='Package with tests')
+    parser.add_argument('--fix', action='store_true', dest='fix_tests',
+                        help='Attempt to fix tests without UUIDs')
+    args = parser.parse_args()
+    sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+    pkg = importlib.import_module(args.package)
+    checker = TestChecker(pkg)
+    errors = False
+    tests = checker.get_tests()
+    untagged = checker.find_untagged(tests)
+    errors = checker.report_collisions(tests) or errors
+    if args.fix_tests and untagged:
+        checker.fix_tests(untagged)
+    else:
+        errors = checker.report_untagged(untagged) or errors
+    if errors:
+        sys.exit("@test.idempotent_id existence and uniqueness checks failed\n"
+                 "Run 'tox -v -euuidgen' to automatically fix tests with\n"
+                 "missing @test.idempotent_id decorators.")
+
+if __name__ == '__main__':
+    run()
diff --git a/tox.ini b/tox.ini
index 2e8b509..ef98e90 100644
--- a/tox.ini
+++ b/tox.ini
@@ -113,6 +113,11 @@
 commands =
    flake8 {posargs}
    {toxinidir}/tools/config/check_uptodate.sh
+   python tools/check_uuid.py
+
+[testenv:uuidgen]
+commands =
+   python tools/check_uuid.py --fix
 
 [hacking]
 local-check-factory = tempest.hacking.checks.factory
@@ -120,11 +125,9 @@
 
 [flake8]
 # E125 is a won't fix until https://github.com/jcrocholl/pep8/issues/126 is resolved.  For further detail see https://review.openstack.org/#/c/36788/
-# H402 skipped because some docstrings aren't sentences
 # E123 skipped because it is ignored by default in the default pep8
 # E129 skipped because it is too limiting when combined with other rules
-# H305 skipped because it is inconsistent between python versions
-# Skipped because of new hacking 0.9: H405,H904
-ignore = E125,H402,E123,E129,H404,H405,H904,H305
+# Skipped because of new hacking 0.9: H405
+ignore = E125,E123,E129,H404,H405
 show-source = True
 exclude = .git,.venv,.tox,dist,doc,openstack,*egg