Merge "Move wait_for_qos_operations method to common.waiters"
diff --git a/README.rst b/README.rst
index 3c0463b..f1dac1c 100644
--- a/README.rst
+++ b/README.rst
@@ -92,18 +92,18 @@
    be done using the :ref:`tempest_run` command. This can be done by either
    running::
 
-     $ tempest run
+    $ tempest run
 
    from the Tempest workspace directory. Or you can use the ``--workspace``
    argument to run in the workspace you created regarless of your current
    working directory. For example::
 
-     $ tempest run --workspace cloud-01
+    $ tempest run --workspace cloud-01
 
    There is also the option to use testr directly, or any `testr`_ based test
    runner, like `ostestr`_. For example, from the workspace dir run::
 
-     $ ostestr --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))'
+    $ ostestr --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))'
 
    will run the same set of tests as the default gate jobs.
 
@@ -161,9 +161,9 @@
 of the configuration.
 
 You can generate a new sample tempest.conf file, run the following
-command from the top level of the Tempest directory:
+command from the top level of the Tempest directory::
 
-  tox -egenconfig
+    $ tox -egenconfig
 
 The most important pieces that are needed are the user ids, openstack
 endpoint, and basic flavors and images needed to run tests.
@@ -257,11 +257,11 @@
 and run the tests or use tox to do the same. Tox also contains several existing
 job configurations. For example::
 
-   $ tox -efull
+    $ tox -efull
 
 which will run the same set of tests as the OpenStack gate. (it's exactly how
 the gate invokes Tempest) Or::
 
-  $ tox -esmoke
+    $ tox -esmoke
 
 to run the tests tagged as smoke.
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 6c55015..18269bf 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -61,10 +61,9 @@
 Credential Provider Mechanisms
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Tempest currently also has three different internal methods for providing
-authentication to tests: dynamic credentials, locking test accounts, and
-non-locking test accounts. Depending on which one is in use the configuration
-of Tempest is slightly different.
+Tempest currently has two different internal methods for providing authentication
+to tests: dynamic credentials and pre-provisioned credentials.
+Depending on which one is in use the configuration of Tempest is slightly different.
 
 Dynamic Credentials
 """""""""""""""""""
@@ -96,7 +95,7 @@
 accounts will be assigned a role on domain configured in
 ``default_credentials_domain_name``. This will make the accounts provisioned
 usable in a cloud where domain scoped tokens are required by keystone for
-admin operations. Note that the the initial pre-provision admin accounts,
+admin operations. Note that the initial pre-provision admin accounts,
 configured in tempest.conf, must have a role on the same domain as well, for
 Dynamic Credentials to work.
 
@@ -152,7 +151,7 @@
 ``admin_domain_scope`` as ``default_credentials_domain_name`` are configured
 properly in tempest.conf.
 
-Pre-Provisioned Credentials are also know as accounts.yaml or accounts file.
+Pre-Provisioned Credentials are also known as accounts.yaml or accounts file.
 
 Compute
 -------
diff --git a/doc/source/plugin.rst b/doc/source/plugin.rst
index d34023f..285ad5d 100644
--- a/doc/source/plugin.rst
+++ b/doc/source/plugin.rst
@@ -213,7 +213,7 @@
 * **client_names**: Name of the classes that implement service clients in the
   service clients module.
 
-Example usage of the the service clients in tests::
+Example usage of the service clients in tests::
 
    # my_creds is instance of tempest.lib.auth.Credentials
    # identity_uri is v2 or v3 depending on the configuration
diff --git a/releasenotes/notes/Tempest-library-interface-0eb680b810139a50.yaml b/releasenotes/notes/10.0.0-Tempest-library-interface-0eb680b810139a50.yaml
similarity index 100%
rename from releasenotes/notes/Tempest-library-interface-0eb680b810139a50.yaml
rename to releasenotes/notes/10.0.0-Tempest-library-interface-0eb680b810139a50.yaml
diff --git a/releasenotes/notes/start-using-reno-ed9518126fd0e1a3.yaml b/releasenotes/notes/10.0.0-start-using-reno-ed9518126fd0e1a3.yaml
similarity index 100%
rename from releasenotes/notes/start-using-reno-ed9518126fd0e1a3.yaml
rename to releasenotes/notes/10.0.0-start-using-reno-ed9518126fd0e1a3.yaml
diff --git a/releasenotes/notes/api-microversion-testing-support-2ceddd2255670932.yaml b/releasenotes/notes/11.0.0-api-microversion-testing-support-2ceddd2255670932.yaml
similarity index 100%
rename from releasenotes/notes/api-microversion-testing-support-2ceddd2255670932.yaml
rename to releasenotes/notes/11.0.0-api-microversion-testing-support-2ceddd2255670932.yaml
diff --git a/releasenotes/notes/compute-microversion-support-e0b23f960f894b9b.yaml b/releasenotes/notes/11.0.0-compute-microversion-support-e0b23f960f894b9b.yaml
similarity index 100%
rename from releasenotes/notes/compute-microversion-support-e0b23f960f894b9b.yaml
rename to releasenotes/notes/11.0.0-compute-microversion-support-e0b23f960f894b9b.yaml
diff --git a/releasenotes/notes/add-network-versions-client-d90e8334e1443f5c.yaml b/releasenotes/notes/12.1.0-add-network-versions-client-d90e8334e1443f5c.yaml
similarity index 100%
rename from releasenotes/notes/add-network-versions-client-d90e8334e1443f5c.yaml
rename to releasenotes/notes/12.1.0-add-network-versions-client-d90e8334e1443f5c.yaml
diff --git a/releasenotes/notes/add-scope-to-auth-b5a82493ea89f41e.yaml b/releasenotes/notes/12.1.0-add-scope-to-auth-b5a82493ea89f41e.yaml
similarity index 100%
rename from releasenotes/notes/add-scope-to-auth-b5a82493ea89f41e.yaml
rename to releasenotes/notes/12.1.0-add-scope-to-auth-b5a82493ea89f41e.yaml
diff --git a/releasenotes/notes/add-tempest-run-3d0aaf69c2ca4115.yaml b/releasenotes/notes/12.1.0-add-tempest-run-3d0aaf69c2ca4115.yaml
similarity index 100%
rename from releasenotes/notes/add-tempest-run-3d0aaf69c2ca4115.yaml
rename to releasenotes/notes/12.1.0-add-tempest-run-3d0aaf69c2ca4115.yaml
diff --git a/releasenotes/notes/add-tempest-workspaces-228a2ba4690b5589.yaml b/releasenotes/notes/12.1.0-add-tempest-workspaces-228a2ba4690b5589.yaml
similarity index 100%
rename from releasenotes/notes/add-tempest-workspaces-228a2ba4690b5589.yaml
rename to releasenotes/notes/12.1.0-add-tempest-workspaces-228a2ba4690b5589.yaml
diff --git a/releasenotes/notes/add_subunit_describe_calls-5498a37e6cd66c4b.yaml b/releasenotes/notes/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml
similarity index 100%
rename from releasenotes/notes/add_subunit_describe_calls-5498a37e6cd66c4b.yaml
rename to releasenotes/notes/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml
diff --git a/releasenotes/notes/bug-1486834-7ebca15836ae27a9.yaml b/releasenotes/notes/12.1.0-bug-1486834-7ebca15836ae27a9.yaml
similarity index 100%
rename from releasenotes/notes/bug-1486834-7ebca15836ae27a9.yaml
rename to releasenotes/notes/12.1.0-bug-1486834-7ebca15836ae27a9.yaml
diff --git a/releasenotes/notes/identity-clients-as-library-e663c6132fcac6c2.yaml b/releasenotes/notes/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml
similarity index 100%
rename from releasenotes/notes/identity-clients-as-library-e663c6132fcac6c2.yaml
rename to releasenotes/notes/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml
diff --git a/releasenotes/notes/image-clients-as-library-86d17caa26ce3961.yaml b/releasenotes/notes/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml
similarity index 100%
rename from releasenotes/notes/image-clients-as-library-86d17caa26ce3961.yaml
rename to releasenotes/notes/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml
diff --git a/releasenotes/notes/new-test-utils-module-adf34468c4d52719.yaml b/releasenotes/notes/12.1.0-new-test-utils-module-adf34468c4d52719.yaml
similarity index 100%
rename from releasenotes/notes/new-test-utils-module-adf34468c4d52719.yaml
rename to releasenotes/notes/12.1.0-new-test-utils-module-adf34468c4d52719.yaml
diff --git a/releasenotes/notes/remove-input-scenarios-functionality-01308e6d4307f580.yaml b/releasenotes/notes/12.1.0-remove-input-scenarios-functionality-01308e6d4307f580.yaml
similarity index 100%
rename from releasenotes/notes/remove-input-scenarios-functionality-01308e6d4307f580.yaml
rename to releasenotes/notes/12.1.0-remove-input-scenarios-functionality-01308e6d4307f580.yaml
diff --git a/releasenotes/notes/remove-integrated-horizon-bb57551c1e5f5be3.yaml b/releasenotes/notes/12.1.0-remove-integrated-horizon-bb57551c1e5f5be3.yaml
similarity index 100%
rename from releasenotes/notes/remove-integrated-horizon-bb57551c1e5f5be3.yaml
rename to releasenotes/notes/12.1.0-remove-integrated-horizon-bb57551c1e5f5be3.yaml
diff --git a/releasenotes/notes/remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml b/releasenotes/notes/12.1.0-remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml
similarity index 100%
rename from releasenotes/notes/remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml
rename to releasenotes/notes/12.1.0-remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml
diff --git a/releasenotes/notes/remove-trove-tests-666522e9113549f9.yaml b/releasenotes/notes/12.1.0-remove-trove-tests-666522e9113549f9.yaml
similarity index 100%
rename from releasenotes/notes/remove-trove-tests-666522e9113549f9.yaml
rename to releasenotes/notes/12.1.0-remove-trove-tests-666522e9113549f9.yaml
diff --git a/releasenotes/notes/routers-client-as-library-25a363379da351f6.yaml b/releasenotes/notes/12.1.0-routers-client-as-library-25a363379da351f6.yaml
similarity index 100%
rename from releasenotes/notes/routers-client-as-library-25a363379da351f6.yaml
rename to releasenotes/notes/12.1.0-routers-client-as-library-25a363379da351f6.yaml
diff --git a/releasenotes/notes/support-chunked-encoding-d71f53225f68edf3.yaml b/releasenotes/notes/12.1.0-support-chunked-encoding-d71f53225f68edf3.yaml
similarity index 100%
rename from releasenotes/notes/support-chunked-encoding-d71f53225f68edf3.yaml
rename to releasenotes/notes/12.1.0-support-chunked-encoding-d71f53225f68edf3.yaml
diff --git a/releasenotes/notes/tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml b/releasenotes/notes/12.1.0-tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml
similarity index 100%
rename from releasenotes/notes/tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml
rename to releasenotes/notes/12.1.0-tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml
diff --git a/releasenotes/notes/add-httptimeout-in-restclient-ax78061900e3f3d7.yaml b/releasenotes/notes/12.2.0-add-httptimeout-in-restclient-ax78061900e3f3d7.yaml
similarity index 100%
rename from releasenotes/notes/add-httptimeout-in-restclient-ax78061900e3f3d7.yaml
rename to releasenotes/notes/12.2.0-add-httptimeout-in-restclient-ax78061900e3f3d7.yaml
diff --git a/releasenotes/notes/add-new-identity-clients-3c3afd674a395bde.yaml b/releasenotes/notes/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml
similarity index 100%
rename from releasenotes/notes/add-new-identity-clients-3c3afd674a395bde.yaml
rename to releasenotes/notes/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml
diff --git a/releasenotes/notes/clients_module-16f3025f515bf9ec.yaml b/releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml
similarity index 100%
rename from releasenotes/notes/clients_module-16f3025f515bf9ec.yaml
rename to releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml
diff --git a/releasenotes/notes/nova_cert_default-90eb7c1e3cde624a.yaml b/releasenotes/notes/12.2.0-nova_cert_default-90eb7c1e3cde624a.yaml
similarity index 100%
rename from releasenotes/notes/nova_cert_default-90eb7c1e3cde624a.yaml
rename to releasenotes/notes/12.2.0-nova_cert_default-90eb7c1e3cde624a.yaml
diff --git a/releasenotes/notes/plugin-service-client-registration-00b19a2dd4935ba0.yaml b/releasenotes/notes/12.2.0-plugin-service-client-registration-00b19a2dd4935ba0.yaml
similarity index 100%
rename from releasenotes/notes/plugin-service-client-registration-00b19a2dd4935ba0.yaml
rename to releasenotes/notes/12.2.0-plugin-service-client-registration-00b19a2dd4935ba0.yaml
diff --git a/releasenotes/notes/remove-javelin-276f62d04f7e4a1d.yaml b/releasenotes/notes/12.2.0-remove-javelin-276f62d04f7e4a1d.yaml
similarity index 100%
rename from releasenotes/notes/remove-javelin-276f62d04f7e4a1d.yaml
rename to releasenotes/notes/12.2.0-remove-javelin-276f62d04f7e4a1d.yaml
diff --git a/releasenotes/notes/service_client_config-8a1d7b4de769c633.yaml b/releasenotes/notes/12.2.0-service_client_config-8a1d7b4de769c633.yaml
similarity index 100%
rename from releasenotes/notes/service_client_config-8a1d7b4de769c633.yaml
rename to releasenotes/notes/12.2.0-service_client_config-8a1d7b4de769c633.yaml
diff --git a/releasenotes/notes/volume-clients-as-library-9a3444dd63c134b3.yaml b/releasenotes/notes/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml
similarity index 100%
rename from releasenotes/notes/volume-clients-as-library-9a3444dd63c134b3.yaml
rename to releasenotes/notes/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml
diff --git a/releasenotes/notes/12.3.0-volume-clients-as-library-660811011be29d1a.yaml b/releasenotes/notes/12.3.0-volume-clients-as-library-660811011be29d1a.yaml
new file mode 100644
index 0000000..9e9eff6
--- /dev/null
+++ b/releasenotes/notes/12.3.0-volume-clients-as-library-660811011be29d1a.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Define the v1 and v2 types_client clients for the volume service as
+    library interfaces, allowing other projects to use these modules as
+    stable libraries without maintenance changes.
diff --git a/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
index b8a8491..9e828f6 100644
--- a/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
+++ b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
@@ -1,8 +1,15 @@
 ---
 features:
   - |
-    Define identity service clients as libraries
+    Define identity service clients as libraries.
     Add new service clients to the library interface so the other projects can use these modules as stable libraries without
     any maintenance changes.
 
       * identity_client(v2)
+      * groups_client(v3)
+      * trusts_client(v3)
+      * users_client(v3)
+      * identity_client(v3)
+      * roles_client(v3)
+      * inherited_roles_client(v3)
+      * credentials_client(v3)
diff --git a/releasenotes/notes/add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml b/releasenotes/notes/add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml
new file mode 100644
index 0000000..4886f16
--- /dev/null
+++ b/releasenotes/notes/add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml
@@ -0,0 +1,15 @@
+---
+features:
+  - |
+    Define volume service clients as libraries.
+    The following volume service clients are defined as library interface,
+    so the other projects can use these modules as stable libraries without
+    any maintenance changes.
+
+    * encryption_types_client (v1)
+    * encryption_types_client (v2)
+    * qos_clients (v1)
+    * qos_clients (v2)
+    * snapshots_client (v1)
+    * snapshots_client (v2)
+
diff --git a/releasenotes/notes/deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml b/releasenotes/notes/deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml
new file mode 100644
index 0000000..0884cfa
--- /dev/null
+++ b/releasenotes/notes/deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml
@@ -0,0 +1,4 @@
+---
+deprecations:
+  - Oslo.utils provides same method get_ipv6_addr_by_EUI64,
+    so deprecate it in Newton and remove it in Ocata.
diff --git a/releasenotes/notes/tempest-cleanup-nostandalone-39df2aafb2545d35.yaml b/releasenotes/notes/tempest-cleanup-nostandalone-39df2aafb2545d35.yaml
new file mode 100644
index 0000000..20f310d
--- /dev/null
+++ b/releasenotes/notes/tempest-cleanup-nostandalone-39df2aafb2545d35.yaml
@@ -0,0 +1,5 @@
+---
+upgrade:
+  - the already depreacted tempest-cleanup standalone command has been
+    removed. The corresponding functionalities can be accessed through
+    the unified `tempest` command (`tempest cleanup`).
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index 2c22408..0ec0e94 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -5,10 +5,10 @@
  .. toctree::
     :maxdepth: 1
 
+    unreleased
     v12.0.0
     v11.0.0
     v10.0.0
-    unreleased
 
 Indices and tables
 ==================
diff --git a/requirements.txt b/requirements.txt
index a773d16..0a5268c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,20 +6,21 @@
 jsonschema!=2.5.0,<3.0.0,>=2.0.0 # MIT
 testtools>=1.4.0 # MIT
 paramiko>=2.0 # LGPLv2.1+
-netaddr!=0.7.16,>=0.7.12 # BSD
+netaddr!=0.7.16,>=0.7.13 # BSD
 testrepository>=0.0.18 # Apache-2.0/BSD
 oslo.concurrency>=3.8.0 # Apache-2.0
 oslo.config>=3.14.0 # Apache-2.0
-oslo.i18n>=2.1.0 # Apache-2.0
-oslo.log>=1.14.0 # Apache-2.0
+oslo.log>=3.11.0 # Apache-2.0
 oslo.serialization>=1.10.0 # Apache-2.0
 oslo.utils>=3.16.0 # Apache-2.0
 six>=1.9.0 # MIT
 fixtures>=3.0.0 # Apache-2.0/BSD
 testscenarios>=0.4 # Apache-2.0/BSD
 PyYAML>=3.1.0 # MIT
+python-subunit>=0.0.18 # Apache-2.0/BSD
 stevedore>=1.16.0 # Apache-2.0
 PrettyTable<0.8,>=0.7 # BSD
 os-testr>=0.7.0 # Apache-2.0
 urllib3>=1.15.1 # MIT
 debtcollector>=1.2.0 # Apache-2.0
+unittest2 # BSD
diff --git a/run_tempest.sh b/run_tempest.sh
index af01734..414146b 100755
--- a/run_tempest.sh
+++ b/run_tempest.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash
 
+echo "WARNING: This script is deprecated and will be removed in the near future. Please migrate to tempest run or another method of launching a test runner"
+
 function usage {
   echo "Usage: $0 [OPTION]..."
   echo "Run Tempest test suite"
diff --git a/setup.cfg b/setup.cfg
index 50bf891..28e17ef 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -29,7 +29,6 @@
 console_scripts =
     verify-tempest-config = tempest.cmd.verify_tempest_config:main
     run-tempest-stress = tempest.cmd.run_stress:main
-    tempest-cleanup = tempest.cmd.cleanup:main
     tempest-account-generator = tempest.cmd.account_generator:main
     tempest = tempest.cmd.main:main
     skip-tracker = tempest.lib.cmd.skip_tracker:main
diff --git a/tempest/api/compute/admin/test_agents.py b/tempest/api/compute/admin/test_agents.py
index 4f48ad0..61359f1 100644
--- a/tempest/api/compute/admin/test_agents.py
+++ b/tempest/api/compute/admin/test_agents.py
@@ -16,7 +16,6 @@
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest.lib.common.utils import test_utils
 from tempest import test
 
 LOG = log.getLogger(__name__)
@@ -30,24 +29,16 @@
         super(AgentsAdminTestJSON, cls).setup_clients()
         cls.client = cls.os_adm.agents_client
 
-    def setUp(self):
-        super(AgentsAdminTestJSON, self).setUp()
-        params = self._param_helper(
+    @classmethod
+    def resource_setup(cls):
+        super(AgentsAdminTestJSON, cls).resource_setup()
+        cls.params_agent = cls._param_helper(
             hypervisor='common', os='linux', architecture='x86_64',
             version='7.0', url='xxx://xxxx/xxx/xxx',
             md5hash='add6bb58e139be103324d04d82d8f545')
-        body = self.client.create_agent(**params)['agent']
-        self.agent_id = body['agent_id']
 
-    def tearDown(self):
-        try:
-            test_utils.call_and_ignore_notfound_exc(
-                self.client.delete_agent, self.agent_id)
-        except Exception:
-            LOG.exception('Exception raised deleting agent %s', self.agent_id)
-        super(AgentsAdminTestJSON, self).tearDown()
-
-    def _param_helper(self, **kwargs):
+    @staticmethod
+    def _param_helper(**kwargs):
         rand_key = 'architecture'
         if rand_key in kwargs:
             # NOTE: The rand_name is for avoiding agent conflicts.
@@ -71,33 +62,42 @@
 
     @test.idempotent_id('dc9ffd51-1c50-4f0e-a820-ae6d2a568a9e')
     def test_update_agent(self):
-        # Update an agent.
+        # Create and update an agent.
+        body = self.client.create_agent(**self.params_agent)['agent']
+        self.addCleanup(self.client.delete_agent, body['agent_id'])
+        agent_id = body['agent_id']
         params = self._param_helper(
             version='8.0', url='xxx://xxxx/xxx/xxx2',
             md5hash='add6bb58e139be103324d04d82d8f547')
-        body = self.client.update_agent(self.agent_id, **params)['agent']
+        body = self.client.update_agent(agent_id, **params)['agent']
         for expected_item, value in params.items():
             self.assertEqual(value, body[expected_item])
 
     @test.idempotent_id('470e0b89-386f-407b-91fd-819737d0b335')
     def test_delete_agent(self):
-        # Delete an agent.
-        self.client.delete_agent(self.agent_id)
+        # Create an agent and delete it.
+        body = self.client.create_agent(**self.params_agent)['agent']
+        self.client.delete_agent(body['agent_id'])
 
         # Verify the list doesn't contain the deleted agent.
         agents = self.client.list_agents()['agents']
-        self.assertNotIn(self.agent_id, map(lambda x: x['agent_id'], agents))
+        self.assertNotIn(body['agent_id'], map(lambda x: x['agent_id'],
+                                               agents))
 
     @test.idempotent_id('6a326c69-654b-438a-80a3-34bcc454e138')
     def test_list_agents(self):
-        # List all agents.
+        # Create an agent and  list all agents.
+        body = self.client.create_agent(**self.params_agent)['agent']
+        self.addCleanup(self.client.delete_agent, body['agent_id'])
         agents = self.client.list_agents()['agents']
         self.assertTrue(len(agents) > 0, 'Cannot get any agents.(%s)' % agents)
-        self.assertIn(self.agent_id, map(lambda x: x['agent_id'], agents))
+        self.assertIn(body['agent_id'], map(lambda x: x['agent_id'], agents))
 
     @test.idempotent_id('eabadde4-3cd7-4ec4-a4b5-5a936d2d4408')
     def test_list_agents_with_filter(self):
-        # List the agent builds by the filter.
+        # Create agents and list the agent builds by the filter.
+        body = self.client.create_agent(**self.params_agent)['agent']
+        self.addCleanup(self.client.delete_agent, body['agent_id'])
         params = self._param_helper(
             hypervisor='xen', os='linux', architecture='x86',
             version='7.0', url='xxx://xxxx/xxx/xxx1',
@@ -110,4 +110,5 @@
                   ['agents'])
         self.assertTrue(len(agents) > 0, 'Cannot get any agents.(%s)' % agents)
         self.assertIn(agent_id_xen, map(lambda x: x['agent_id'], agents))
-        self.assertNotIn(self.agent_id, map(lambda x: x['agent_id'], agents))
+        self.assertNotIn(body['agent_id'], map(lambda x: x['agent_id'],
+                                               agents))
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index fbcc1d1..667d30b 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -215,10 +215,8 @@
         self.client.add_host(aggregate['id'], host=self.host)
         self.addCleanup(self.client.remove_host, aggregate['id'],
                         host=self.host)
-        server_name = data_utils.rand_name('test_server')
         admin_servers_client = self.os_adm.servers_client
-        server = self.create_test_server(name=server_name,
-                                         availability_zone=az_name,
+        server = self.create_test_server(availability_zone=az_name,
                                          wait_until='ACTIVE')
         body = admin_servers_client.show_server(server['id'])['server']
         self.assertEqual(self.host, body['OS-EXT-SRV-ATTR:host'])
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 95e7ef1..fde5622 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -161,6 +161,7 @@
         verify_flavor_response_extension(flavor)
 
         # Check if flavor is present in list
+        flag = False
         flavors = self.user_client.list_flavors(detail=True)['flavors']
         for flavor in flavors:
             if flavor['name'] == flavor_name:
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index 6113c04..62dbfe4 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -31,6 +31,8 @@
         super(MigrationsAdminTest, cls).setup_clients()
         cls.client = cls.os_adm.migrations_client
         cls.flavors_admin_client = cls.os_adm.flavors_client
+        cls.admin_hosts_client = cls.os_adm.hosts_client
+        cls.admin_servers_client = cls.os_adm.servers_client
 
     @test.idempotent_id('75c0b83d-72a0-4cf8-a153-631e83e7d53f')
     def test_list_migrations(self):
@@ -103,3 +105,28 @@
 
         server = self.servers_client.show_server(server['id'])['server']
         self.assertEqual(flavor['id'], server['flavor']['id'])
+
+    @test.idempotent_id('4bf0be52-3b6f-4746-9a27-3143636fe30d')
+    @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
+                          'Cold migration not available.')
+    def test_cold_migration(self):
+        if CONF.compute.min_compute_nodes < 2:
+            msg = "Less than 2 compute nodes, skipping multinode tests."
+            raise self.skipException(msg)
+
+        server = self.create_test_server(wait_until="ACTIVE")
+        src_host = self.admin_servers_client.show_server(
+            server['id'])['server']['OS-EXT-SRV-ATTR:host']
+
+        self.admin_servers_client.migrate_server(server['id'])
+
+        waiters.wait_for_server_status(self.servers_client,
+                                       server['id'], 'VERIFY_RESIZE')
+
+        self.servers_client.confirm_resize_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client,
+                                       server['id'], 'ACTIVE')
+        dst_host = self.admin_servers_client.show_server(
+            server['id'])['server']['OS-EXT-SRV-ATTR:host']
+
+        self.assertNotEqual(src_host, dst_host)
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index b1f0755..7d97ce2 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -117,8 +117,6 @@
                                                password=password,
                                                project=project,
                                                email=email)
-        if 'user' in user:
-            user = user['user']
         user_id = user['id']
         self.addCleanup(self.identity_utils.delete_user, user_id)
 
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index aabb40c..c9ffcca 100755
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -102,14 +102,18 @@
         params = {'tenant_id': tenant_id}
         body = self.client.list_servers(detail=True, **params)
         servers = body['servers']
-        self.assertEqual([], servers)
+        servers_name = map(lambda x: x['name'], servers)
+        self.assertNotIn(self.s1_name, servers_name)
+        self.assertNotIn(self.s2_name, servers_name)
 
-        # List the admin tenant which has no servers
+        # List the admin tenant shouldn't get servers created by other tenants
         admin_tenant_id = self.client.tenant_id
         params = {'all_tenants': '', 'tenant_id': admin_tenant_id}
         body = self.client.list_servers(detail=True, **params)
         servers = body['servers']
-        self.assertEqual([], servers)
+        servers_name = map(lambda x: x['name'], servers)
+        self.assertNotIn(self.s1_name, servers_name)
+        self.assertNotIn(self.s2_name, servers_name)
 
     @test.idempotent_id('86c7a8f7-50cf-43a9-9bac-5b985317134f')
     def test_list_servers_filter_by_exist_host(self):
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index db6e682..23b16e7 100755
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -69,7 +69,7 @@
             self.tenant_id)['quota_set']
         ram = int(quota_set['ram'])
         if ram == -1:
-            raise self.skipException("default ram quota set is -1,"
+            raise self.skipException("ram quota set is -1,"
                                      " cannot test overlimit")
         ram += 1
         vcpus = 8
@@ -98,7 +98,7 @@
             self.tenant_id)['quota_set']
         vcpus = int(quota_set['cores'])
         if vcpus == -1:
-            raise self.skipException("default cores quota set is -1,"
+            raise self.skipException("cores quota set is -1,"
                                      " cannot test overlimit")
         vcpus += 1
         disk = 10
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 5e75493..27afff3 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -219,6 +219,8 @@
         :param validatable: Whether the server will be pingable or sshable.
         :param volume_backed: Whether the instance is volume backed or not.
         """
+        if 'name' not in kwargs:
+            kwargs['name'] = data_utils.rand_name(cls.__name__ + "-server")
         tenant_network = cls.get_tenant_network()
         body, servers = compute.create_test_server(
             cls.os,
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 6f80730..999233d 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -71,7 +71,7 @@
         body = body['image'] if 'image' in body else body
         cls.image_id = body['id']
         cls.images.append(cls.image_id)
-        image_file = six.StringIO(('*' * 1024))
+        image_file = six.BytesIO((b'*' * 1024))
         if CONF.image_feature_enabled.api_v1:
             cls.glance_client.update_image(cls.image_id, data=image_file)
         else:
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index c0caa52..f340658 100755
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -78,7 +78,7 @@
             # Wait 1 second between creation and upload to ensure a delta
             # between created_at and updated_at.
             time.sleep(1)
-            image_file = six.StringIO(('*' * 1024))
+            image_file = six.BytesIO((b'*' * 1024))
             if CONF.image_feature_enabled.api_v1:
                 cls.glance_client.update_image(image_id, data=image_file)
             else:
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 853ef31..4f53663 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
@@ -23,7 +23,8 @@
 
 
 def not_existing_id():
-    if CONF.service_available.neutron:
+    if (CONF.service_available.neutron and
+        test.is_extension_enabled('security-group', 'network')):
         return data_utils.rand_uuid()
     else:
         return data_utils.rand_int_id(start=999)
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index f6353c8..755336f 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -94,8 +94,7 @@
 
         # Create server and add the security group created
         # above to the server we just created
-        server_name = data_utils.rand_name('server')
-        server = self.create_test_server(name=server_name)
+        server = self.create_test_server()
         server_id = server['id']
         waiters.wait_for_server_status(self.servers_client, server_id,
                                        'ACTIVE')
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 7c12bf9..b936b23 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -47,22 +47,20 @@
     @classmethod
     def setup_clients(cls):
         super(AttachInterfacesTestJSON, cls).setup_clients()
-        cls.client = cls.os.interfaces_client
         cls.networks_client = cls.os.networks_client
         cls.subnets_client = cls.os.subnets_client
         cls.ports_client = cls.os.ports_client
-        cls.servers_client = cls.servers_client
 
     def wait_for_interface_status(self, server, port_id, status):
         """Waits for an interface to reach a given status."""
-        body = (self.client.show_interface(server, port_id)
+        body = (self.interfaces_client.show_interface(server, port_id)
                 ['interfaceAttachment'])
         interface_status = body['port_state']
         start = int(time.time())
 
         while(interface_status != status):
             time.sleep(self.build_interval)
-            body = (self.client.show_interface(server, port_id)
+            body = (self.interfaces_client.show_interface(server, port_id)
                     ['interfaceAttachment'])
             interface_status = body['port_state']
 
@@ -119,7 +117,7 @@
 
     def _create_server_get_interfaces(self):
         server = self.create_test_server(wait_until='ACTIVE')
-        ifs = (self.client.list_interfaces(server['id'])
+        ifs = (self.interfaces_client.list_interfaces(server['id'])
                ['interfaceAttachments'])
         body = self.wait_for_interface_status(
             server['id'], ifs[0]['port_id'], 'ACTIVE')
@@ -127,7 +125,7 @@
         return server, ifs
 
     def _test_create_interface(self, server):
-        iface = (self.client.create_interface(server['id'])
+        iface = (self.interfaces_client.create_interface(server['id'])
                  ['interfaceAttachment'])
         iface = self.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
@@ -136,7 +134,7 @@
 
     def _test_create_interface_by_network_id(self, server, ifs):
         network_id = ifs[0]['net_id']
-        iface = self.client.create_interface(
+        iface = self.interfaces_client.create_interface(
             server['id'], net_id=network_id)['interfaceAttachment']
         iface = self.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
@@ -148,7 +146,7 @@
         port = self.ports_client.create_port(network_id=network_id)
         port_id = port['port']['id']
         self.addCleanup(self.ports_client.delete_port, port_id)
-        iface = self.client.create_interface(
+        iface = self.interfaces_client.create_interface(
             server['id'], port_id=port_id)['interfaceAttachment']
         iface = self.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
@@ -165,7 +163,7 @@
                                                     1)
 
         fixed_ips = [{'ip_address': ip_list[0]}]
-        iface = self.client.create_interface(
+        iface = self.interfaces_client.create_interface(
             server['id'], net_id=network_id,
             fixed_ips=fixed_ips)['interfaceAttachment']
         self.addCleanup(self.ports_client.delete_port, iface['port_id'])
@@ -176,7 +174,7 @@
 
     def _test_show_interface(self, server, ifs):
         iface = ifs[0]
-        _iface = self.client.show_interface(
+        _iface = self.interfaces_client.show_interface(
             server['id'], iface['port_id'])['interfaceAttachment']
         self._check_interface(iface, port_id=_iface['port_id'],
                               network_id=_iface['net_id'],
@@ -186,14 +184,14 @@
     def _test_delete_interface(self, server, ifs):
         # NOTE(danms): delete not the first or last, but one in the middle
         iface = ifs[1]
-        self.client.delete_interface(server['id'], iface['port_id'])
-        _ifs = (self.client.list_interfaces(server['id'])
+        self.interfaces_client.delete_interface(server['id'], iface['port_id'])
+        _ifs = (self.interfaces_client.list_interfaces(server['id'])
                 ['interfaceAttachments'])
         start = int(time.time())
 
         while len(ifs) == len(_ifs):
             time.sleep(self.build_interval)
-            _ifs = (self.client.list_interfaces(server['id'])
+            _ifs = (self.interfaces_client.list_interfaces(server['id'])
                     ['interfaceAttachments'])
             timed_out = int(time.time()) - start >= self.build_timeout
             if len(ifs) == len(_ifs) and timed_out:
@@ -239,7 +237,7 @@
         iface = self._test_create_interface_by_fixed_ips(server, ifs)
         ifs.append(iface)
 
-        _ifs = (self.client.list_interfaces(server['id'])
+        _ifs = (self.interfaces_client.list_interfaces(server['id'])
                 ['interfaceAttachments'])
         self._compare_iface_list(ifs, _ifs)
 
@@ -302,11 +300,11 @@
 
         for server in servers:
             # attach the port to the server
-            iface = self.client.create_interface(
+            iface = self.interfaces_client.create_interface(
                 server['id'], port_id=port_id)['interfaceAttachment']
             self._check_interface(iface, port_id=port_id)
 
             # detach the port from the server; this is a cast in the compute
             # API so we have to poll the port until the device_id is unset.
-            self.client.delete_interface(server['id'], port_id)
+            self.interfaces_client.delete_interface(server['id'], port_id)
             self.wait_for_port_detach(port_id)
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 26cbb090..611d5a2 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -119,8 +119,8 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @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
+    def test_list_servers_filter_by_active_status(self):
+        # Filter the list of servers by server active status
         params = {'status': 'active'}
         body = self.client.list_servers(**params)
         servers = body['servers']
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 357c907..fcd5a24 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
-
 from tempest.api.compute import base
 from tempest.common import waiters
 from tempest.lib import exceptions as lib_exc
@@ -38,7 +36,7 @@
         # tearDownClass method of the super-class.
         cls.existing_fixtures = []
         cls.deleted_fixtures = []
-        for x in moves.xrange(2):
+        for x in range(2):
             srv = cls.create_test_server(wait_until='ACTIVE')
             cls.existing_fixtures.append(srv)
 
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index eb1beb1..4dd26af 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -21,16 +21,10 @@
 class MultipleCreateTestJSON(base.BaseV2ComputeTest):
     _name = 'multiple-create-test'
 
-    def _generate_name(self):
-        return data_utils.rand_name(self._name)
-
-    def _create_multiple_servers(self, name=None, wait_until=None, **kwargs):
-        # NOTE: This is the right way to create_multiple servers and manage to
-        # get the created servers into the servers list to be cleaned up after
-        # all.
-        kwargs['name'] = name if name else self._generate_name()
-        if wait_until:
-            kwargs['wait_until'] = wait_until
+    def _create_multiple_servers(self, **kwargs):
+        # This is the right way to create_multiple servers and manage to get
+        # the created servers into the servers list to be cleaned up after all.
+        kwargs['name'] = kwargs.get('name', data_utils.rand_name(self._name))
         body = self.create_test_server(**kwargs)
 
         return body
diff --git a/tempest/api/compute/servers/test_multiple_create_negative.py b/tempest/api/compute/servers/test_multiple_create_negative.py
index e5b4f46..c4dbe23 100644
--- a/tempest/api/compute/servers/test_multiple_create_negative.py
+++ b/tempest/api/compute/servers/test_multiple_create_negative.py
@@ -22,13 +22,10 @@
 class MultipleCreateNegativeTestJSON(base.BaseV2ComputeTest):
     _name = 'multiple-create-test'
 
-    def _generate_name(self):
-        return data_utils.rand_name(self._name)
-
-    def _create_multiple_servers(self, name=None, wait_until=None, **kwargs):
+    def _create_multiple_servers(self, **kwargs):
         # This is the right way to create_multiple servers and manage to get
         # the created servers into the servers list to be cleaned up after all.
-        kwargs['name'] = kwargs.get('name', self._generate_name())
+        kwargs['name'] = kwargs.get('name', data_utils.rand_name(self._name))
         body = self.create_test_server(**kwargs)
 
         return body
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index baa4f9a..e5ad7b4 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import base64
+from oslo_serialization import base64
 
 from tempest.api.compute import base
 from tempest.common.utils.linux import remote_client
@@ -55,7 +55,7 @@
         file_contents = 'This is a test file.'
         file_path = '/test.txt'
         personality = [{'path': file_path,
-                        'contents': base64.b64encode(file_contents)}]
+                        'contents': base64.encode_as_text(file_contents)}]
         password = data_utils.rand_password()
         created_server = self.create_test_server(personality=personality,
                                                  adminPass=password,
@@ -79,7 +79,7 @@
         server_id = server['id']
         file_contents = 'Test server rebuild.'
         personality = [{'path': 'rebuild.txt',
-                        'contents': base64.b64encode(file_contents)}]
+                        'contents': base64.encode_as_text(file_contents)}]
         rebuilt_server = self.client.rebuild_server(server_id,
                                                     self.image_ref_alt,
                                                     personality=personality)
@@ -100,7 +100,8 @@
         for i in range(0, int(max_file_limit) + 1):
             path = 'etc/test' + str(i) + '.txt'
             personality.append({'path': path,
-                                'contents': base64.b64encode(file_contents)})
+                                'contents': base64.encode_as_text(
+                                    file_contents)})
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised when out of quota
         self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
@@ -120,7 +121,7 @@
             path = '/etc/test' + str(i) + '.txt'
             person.append({
                 'path': path,
-                'contents': base64.b64encode(file_contents),
+                'contents': base64.encode_as_text(file_contents),
             })
         password = data_utils.rand_password()
         created_server = self.create_test_server(personality=person,
@@ -136,6 +137,6 @@
                 server=server,
                 servers_client=self.client)
             for i in person:
-                self.assertEqual(base64.b64decode(i['contents']),
+                self.assertEqual(base64.decode_as_text(i['contents']),
                                  linux_client.exec_command(
                                      'sudo cat %s' % i['path']))
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 2304cb7..89be3f3 100755
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -302,7 +302,7 @@
         # Pass a server ID that exceeds length limit to delete server
 
         self.assertRaises(lib_exc.NotFound, self.client.delete_server,
-                          sys.maxint + 1)
+                          sys.maxsize + 1)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('c5fa6041-80cd-483b-aa6d-4e45f19d093c')
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 80d2c78..c48169f 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -17,6 +17,7 @@
 
 from tempest.api.compute import base
 from tempest.common import compute
+from tempest.common.utils import data_utils
 from tempest.common.utils.linux import remote_client
 from tempest.common import waiters
 from tempest import config
@@ -57,13 +58,6 @@
             waiters.wait_for_volume_status(self.volumes_client,
                                            volume_id, 'available')
 
-    def _delete_volume(self):
-        # Delete the created Volumes
-        if self.volume:
-            self.volumes_client.delete_volume(self.volume['id'])
-            self.volumes_client.wait_for_resource_deletion(self.volume['id'])
-            self.volume = None
-
     def _create_server(self):
         # Start a server and wait for it to become ready
         server = self.create_test_server(
@@ -78,28 +72,30 @@
 
     def _create_and_attach_volume(self, server):
         # Create a volume and wait for it to become ready
-        self.volume = self.volumes_client.create_volume(
-            size=CONF.volume.volume_size, display_name='test')['volume']
-        self.addCleanup(self._delete_volume)
+        vol_name = data_utils.rand_name(self.__class__.__name__ + '-volume')
+        volume = self.volumes_client.create_volume(
+            size=CONF.volume.volume_size, display_name=vol_name)['volume']
+        self.addCleanup(self.delete_volume, volume['id'])
         waiters.wait_for_volume_status(self.volumes_client,
-                                       self.volume['id'], 'available')
+                                       volume['id'], 'available')
 
         # Attach the volume to the server
         self.attachment = self.servers_client.attach_volume(
             server['id'],
-            volumeId=self.volume['id'],
+            volumeId=volume['id'],
             device='/dev/%s' % self.device)['volumeAttachment']
         waiters.wait_for_volume_status(self.volumes_client,
-                                       self.volume['id'], 'in-use')
+                                       volume['id'], 'in-use')
 
-        self.addCleanup(self._detach, server['id'], self.volume['id'])
+        self.addCleanup(self._detach, server['id'], volume['id'])
+        return volume
 
     @test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
     def test_attach_detach_volume(self):
         # Stop and Start a server with an attached volume, ensuring that
         # the volume remains attached.
         server = self._create_server()
-        self._create_and_attach_volume(server)
+        volume = self._create_and_attach_volume(server)
 
         self.servers_client.stop_server(server['id'])
         waiters.wait_for_server_status(self.servers_client, server['id'],
@@ -119,9 +115,10 @@
                 servers_client=self.servers_client)
 
             partitions = linux_client.get_partitions()
-            self.assertIn(self.device, partitions)
+            device_name_to_match = ' ' + self.device + '\n'
+            self.assertIn(device_name_to_match, partitions)
 
-        self._detach(server['id'], self.volume['id'])
+        self._detach(server['id'], volume['id'])
         self.attachment = None
         self.servers_client.stop_server(server['id'])
         waiters.wait_for_server_status(self.servers_client, server['id'],
@@ -141,13 +138,13 @@
                 servers_client=self.servers_client)
 
             partitions = linux_client.get_partitions()
-            self.assertNotIn(self.device, partitions)
+            self.assertNotIn(device_name_to_match, partitions)
 
     @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
     def test_list_get_volume_attachments(self):
         # Create Server, Volume and attach that Volume to Server
         server = self._create_server()
-        self._create_and_attach_volume(server)
+        volume = self._create_and_attach_volume(server)
 
         # List Volume attachment of the server
         body = self.servers_client.list_volume_attachments(
@@ -160,7 +157,7 @@
             server['id'],
             self.attachment['id'])['volumeAttachment']
         self.assertEqual(server['id'], body['serverId'])
-        self.assertEqual(self.volume['id'], body['volumeId'])
+        self.assertEqual(volume['id'], body['volumeId'])
         self.assertEqual(self.attachment['id'], body['id'])
 
 
@@ -168,7 +165,7 @@
     """Testing volume with shelved instance.
 
     This test checks the attaching and detaching volumes from
-    a shelved or shelved ofload instance.
+    a shelved or shelved offload instance.
     """
 
     min_microversion = '2.20'
@@ -253,10 +250,10 @@
         server = self._create_server()
         num_vol = self._count_volumes(server)
         self._shelve_server(server)
-        self._create_and_attach_volume(server)
+        volume = self._create_and_attach_volume(server)
 
         # Detach the volume
-        self._detach(server['id'], self.volume['id'])
+        self._detach(server['id'], volume['id'])
         self.attachment = None
 
         # Unshelve the instance and check that we have the expected number of
diff --git a/tempest/api/identity/admin/v2/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
index 380920f..d284aac 100644
--- a/tempest/api/identity/admin/v2/test_roles.py
+++ b/tempest/api/identity/admin/v2/test_roles.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
-
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
@@ -27,7 +25,7 @@
     def resource_setup(cls):
         super(RolesTestJSON, cls).resource_setup()
         cls.roles = list()
-        for _ in moves.xrange(5):
+        for _ in range(5):
             role_name = data_utils.rand_name(name='role')
             role = cls.roles_client.create_role(name=role_name)['role']
             cls.roles.append(role)
diff --git a/tempest/api/identity/admin/v2/test_services.py b/tempest/api/identity/admin/v2/test_services.py
index 94291f8..3ed51f0 100644
--- a/tempest/api/identity/admin/v2/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
-
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest.lib import exceptions as lib_exc
@@ -84,7 +82,7 @@
     def test_list_services(self):
         # Create, List, Verify and Delete Services
         services = []
-        for _ in moves.xrange(3):
+        for _ in range(3):
             name = data_utils.rand_name('service')
             s_type = data_utils.rand_name('type')
             description = data_utils.rand_name('description')
diff --git a/tempest/api/identity/admin/v2/test_tenants.py b/tempest/api/identity/admin/v2/test_tenants.py
index 4faf184..f4fad53 100644
--- a/tempest/api/identity/admin/v2/test_tenants.py
+++ b/tempest/api/identity/admin/v2/test_tenants.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
-
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
@@ -27,7 +25,7 @@
     def test_tenant_list_delete(self):
         # Create several tenants and delete them
         tenants = []
-        for _ in moves.xrange(3):
+        for _ in range(3):
             tenant_name = data_utils.rand_name(name='tenant-new')
             tenant = self.tenants_client.create_tenant(
                 name=tenant_name)['tenant']
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 8e63498..4a4b51a 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -234,4 +234,4 @@
         # Validate the updated password through getting a token.
         body = self.token_client.auth(user['name'], new_pass,
                                       tenant['name'])
-        self.assertTrue('id' in body['token'])
+        self.assertIn('id', body['token'])
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 12b236f..a0d8748 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.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.
+from oslo_serialization import jsonutils as json
 
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
@@ -70,6 +71,7 @@
         update_body = self.creds_client.update_credential(
             cred['id'], blob=blob, project_id=self.projects[1],
             type='ec2')['credential']
+        update_body['blob'] = json.loads(update_body['blob'])
         self.assertEqual(cred['id'], update_body['id'])
         self.assertEqual(self.projects[1], update_body['project_id'])
         self.assertEqual(self.user_body['id'], update_body['user_id'])
@@ -77,6 +79,7 @@
         self.assertEqual(update_body['blob']['secret'], new_keys[1])
 
         get_body = self.creds_client.show_credential(cred['id'])['credential']
+        get_body['blob'] = json.loads(get_body['blob'])
         for value1 in self.creds_list[0]:
             self.assertEqual(update_body[value1],
                              get_body[value1])
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 48e5f02..3cbcc1f 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -91,7 +91,8 @@
 
         # list users in group
         group_users = self.groups_client.list_group_users(group['id'])['users']
-        self.assertEqual(sorted(users), sorted(group_users))
+        self.assertEqual(sorted(users, key=lambda k: k['name']),
+                         sorted(group_users, key=lambda k: k['name']))
         # check and delete user in group
         for user in users:
             self.groups_client.check_group_user_existence(
@@ -118,7 +119,8 @@
             self.groups_client.add_group_user(group['id'], user['id'])
         # list groups which user belongs to
         user_groups = self.users_client.list_user_groups(user['id'])['groups']
-        self.assertEqual(sorted(groups), sorted(user_groups))
+        self.assertEqual(sorted(groups, key=lambda k: k['name']),
+                         sorted(user_groups, key=lambda k: k['name']))
         self.assertEqual(2, len(user_groups))
 
     @test.idempotent_id('cc9a57a5-a9ed-4f2d-a29f-4f979a06ec71')
diff --git a/tempest/api/identity/admin/v3/test_inherits.py b/tempest/api/identity/admin/v3/test_inherits.py
index 76771bb..955b6fb 100644
--- a/tempest/api/identity/admin/v3/test_inherits.py
+++ b/tempest/api/identity/admin/v3/test_inherits.py
@@ -68,10 +68,10 @@
             name=data_utils.rand_name('Role'))['role']
         self.addCleanup(self.roles_client.delete_role, src_role['id'])
         # Assign role on domains user
-        self.roles_client.assign_inherited_role_on_domains_user(
+        self.inherited_roles_client.create_inherited_role_on_domains_user(
             self.domain['id'], self.user['id'], src_role['id'])
         # list role on domains user
-        roles = self.roles_client.\
+        roles = self.inherited_roles_client.\
             list_inherited_project_role_for_user_on_domain(
                 self.domain['id'], self.user['id'])['roles']
 
@@ -80,10 +80,11 @@
                               src_role['id'])
 
         # Check role on domains user
-        self.roles_client.check_user_inherited_project_role_on_domain(
-            self.domain['id'], self.user['id'], src_role['id'])
+        (self.inherited_roles_client.
+         check_user_inherited_project_role_on_domain(
+             self.domain['id'], self.user['id'], src_role['id']))
         # Revoke role from domains user.
-        self.roles_client.revoke_inherited_role_from_user_on_domain(
+        self.inherited_roles_client.delete_inherited_role_from_user_on_domain(
             self.domain['id'], self.user['id'], src_role['id'])
 
     @test.idempotent_id('c7a8dda2-be50-4fb4-9a9c-e830771078b1')
@@ -93,10 +94,10 @@
             name=data_utils.rand_name('Role'))['role']
         self.addCleanup(self.roles_client.delete_role, src_role['id'])
         # Assign role on domains group
-        self.roles_client.assign_inherited_role_on_domains_group(
+        self.inherited_roles_client.create_inherited_role_on_domains_group(
             self.domain['id'], self.group['id'], src_role['id'])
         # List role on domains group
-        roles = self.roles_client.\
+        roles = self.inherited_roles_client.\
             list_inherited_project_role_for_group_on_domain(
                 self.domain['id'], self.group['id'])['roles']
 
@@ -105,10 +106,11 @@
                               src_role['id'])
 
         # Check role on domains group
-        self.roles_client.check_group_inherited_project_role_on_domain(
-            self.domain['id'], self.group['id'], src_role['id'])
+        (self.inherited_roles_client.
+         check_group_inherited_project_role_on_domain(
+             self.domain['id'], self.group['id'], src_role['id']))
         # Revoke role from domains group
-        self.roles_client.revoke_inherited_role_from_group_on_domain(
+        self.inherited_roles_client.delete_inherited_role_from_group_on_domain(
             self.domain['id'], self.group['id'], src_role['id'])
 
     @test.idempotent_id('18b70e45-7687-4b72-8277-b8f1a47d7591')
@@ -118,13 +120,14 @@
             name=data_utils.rand_name('Role'))['role']
         self.addCleanup(self.roles_client.delete_role, src_role['id'])
         # Assign role on projects user
-        self.roles_client.assign_inherited_role_on_projects_user(
+        self.inherited_roles_client.create_inherited_role_on_projects_user(
             self.project['id'], self.user['id'], src_role['id'])
         # Check role on projects user
-        self.roles_client.check_user_has_flag_on_inherited_to_project(
-            self.project['id'], self.user['id'], src_role['id'])
+        (self.inherited_roles_client.
+         check_user_has_flag_on_inherited_to_project(
+             self.project['id'], self.user['id'], src_role['id']))
         # Revoke role from projects user
-        self.roles_client.revoke_inherited_role_from_user_on_project(
+        self.inherited_roles_client.delete_inherited_role_from_user_on_project(
             self.project['id'], self.user['id'], src_role['id'])
 
     @test.idempotent_id('26021436-d5a4-4256-943c-ded01e0d4b45')
@@ -134,11 +137,98 @@
             name=data_utils.rand_name('Role'))['role']
         self.addCleanup(self.roles_client.delete_role, src_role['id'])
         # Assign role on projects group
-        self.roles_client.assign_inherited_role_on_projects_group(
+        self.inherited_roles_client.create_inherited_role_on_projects_group(
             self.project['id'], self.group['id'], src_role['id'])
         # Check role on projects group
-        self.roles_client.check_group_has_flag_on_inherited_to_project(
-            self.project['id'], self.group['id'], src_role['id'])
+        (self.inherited_roles_client.
+         check_group_has_flag_on_inherited_to_project(
+             self.project['id'], self.group['id'], src_role['id']))
         # Revoke role from projects group
-        self.roles_client.revoke_inherited_role_from_group_on_project(
-            self.project['id'], self.group['id'], src_role['id'])
+        (self.inherited_roles_client.
+         delete_inherited_role_from_group_on_project(
+             self.project['id'], self.group['id'], src_role['id']))
+
+    @test.idempotent_id('3acf666e-5354-42ac-8e17-8b68893bcd36')
+    def test_inherit_assign_list_revoke_user_roles_on_domain(self):
+        # Create role
+        src_role = self.roles_client.create_role(
+            name=data_utils.rand_name('Role'))['role']
+        self.addCleanup(self.roles_client.delete_role, src_role['id'])
+
+        # Create a project hierarchy
+        leaf_project_name = data_utils.rand_name('project')
+        leaf_project = self.projects_client.create_project(
+            leaf_project_name, domain_id=self.domain['id'],
+            parent_id=self.project['id'])['project']
+        self.addCleanup(
+            self.projects_client.delete_project, leaf_project['id'])
+
+        # Assign role on domain
+        self.inherited_roles_client.create_inherited_role_on_domains_user(
+            self.domain['id'], self.user['id'], src_role['id'])
+
+        # List "effective" role assignments from user on the parent project
+        assignments = (
+            self.role_assignments.list_user_project_effective_assignments(
+                self.project['id'], self.user['id']))['role_assignments']
+        self.assertNotEmpty(assignments)
+
+        # List "effective" role assignments from user on the leaf project
+        assignments = (
+            self.role_assignments.list_user_project_effective_assignments(
+                leaf_project['id'], self.user['id']))['role_assignments']
+        self.assertNotEmpty(assignments)
+
+        # Revoke role from domain
+        self.inherited_roles_client.delete_inherited_role_from_user_on_domain(
+            self.domain['id'], self.user['id'], src_role['id'])
+
+        # List "effective" role assignments from user on the parent project
+        # should return an empty list
+        assignments = (
+            self.role_assignments.list_user_project_effective_assignments(
+                self.project['id'], self.user['id']))['role_assignments']
+        self.assertEmpty(assignments)
+
+        # List "effective" role assignments from user on the leaf project
+        # should return an empty list
+        assignments = (
+            self.role_assignments.list_user_project_effective_assignments(
+                leaf_project['id'], self.user['id']))['role_assignments']
+        self.assertEmpty(assignments)
+
+    @test.idempotent_id('9f02ccd9-9b57-46b4-8f77-dd5a736f3a06')
+    def test_inherit_assign_list_revoke_user_roles_on_project_tree(self):
+        # Create role
+        src_role = self.roles_client.create_role(
+            name=data_utils.rand_name('Role'))['role']
+        self.addCleanup(self.roles_client.delete_role, src_role['id'])
+
+        # Create a project hierarchy
+        leaf_project_name = data_utils.rand_name('project')
+        leaf_project = self.projects_client.create_project(
+            leaf_project_name, domain_id=self.domain['id'],
+            parent_id=self.project['id'])['project']
+        self.addCleanup(
+            self.projects_client.delete_project, leaf_project['id'])
+
+        # Assign role on parent project
+        self.inherited_roles_client.create_inherited_role_on_projects_user(
+            self.project['id'], self.user['id'], src_role['id'])
+
+        # List "effective" role assignments from user on the leaf project
+        assignments = (
+            self.role_assignments.list_user_project_effective_assignments(
+                leaf_project['id'], self.user['id']))['role_assignments']
+        self.assertNotEmpty(assignments)
+
+        # Revoke role from parent project
+        self.inherited_roles_client.delete_inherited_role_from_user_on_project(
+            self.project['id'], self.user['id'], src_role['id'])
+
+        # List "effective" role assignments from user on the leaf project
+        # should return an empty list
+        assignments = (
+            self.role_assignments.list_user_project_effective_assignments(
+                leaf_project['id'], self.user['id']))['role_assignments']
+        self.assertEmpty(assignments)
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 6c926fb..14bf4f8 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -23,6 +23,12 @@
 class BaseIdentityTest(tempest.test.BaseTestCase):
 
     @classmethod
+    def setup_credentials(cls):
+        # Create no network resources for these test.
+        cls.set_network_resources()
+        super(BaseIdentityTest, cls).setup_credentials()
+
+    @classmethod
     def disable_user(cls, user_name):
         user = cls.get_user_by_name(user_name)
         cls.users_client.update_user_enabled(user['id'], enabled=False)
@@ -167,6 +173,7 @@
         cls.users_client = cls.os_adm.users_v3_client
         cls.trusts_client = cls.os_adm.trusts_client
         cls.roles_client = cls.os_adm.roles_v3_client
+        cls.inherited_roles_client = cls.os_adm.inherited_roles_client
         cls.token = cls.os_adm.token_v3_client
         cls.endpoints_client = cls.os_adm.endpoints_v3_client
         cls.regions_client = cls.os_adm.regions_client
@@ -175,6 +182,7 @@
         cls.creds_client = cls.os_adm.credentials_client
         cls.groups_client = cls.os_adm.groups_client
         cls.projects_client = cls.os_adm.projects_client
+        cls.role_assignments = cls.os_admin.role_assignments_client
         if CONF.identity.admin_domain_scope:
             # NOTE(andreaf) When keystone policy requires it, the identity
             # admin clients for these tests shall use 'domain' scoped tokens.
diff --git a/tempest/api/image/admin/v2/test_images.py b/tempest/api/image/admin/v2/test_images.py
index 80da7a1..c719b7a 100644
--- a/tempest/api/image/admin/v2/test_images.py
+++ b/tempest/api/image/admin/v2/test_images.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
+import six
 import testtools
 
 from tempest.api.image import base
@@ -42,7 +42,7 @@
         self.addCleanup(self.client.delete_image, image_id)
         # upload an image file
         content = data_utils.random_bytes()
-        image_file = moves.cStringIO(content)
+        image_file = six.BytesIO(content)
         self.client.store_image_file(image_id, image_file)
         # deactivate image
         self.admin_client.deactivate_image(image_id)
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index e7a46b0..f74f97b 100755
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
+import six
 
 from tempest.common import image as common_image
 from tempest.common.utils import data_utils
@@ -118,7 +118,7 @@
         cls.alt_tenant_id = cls.alt_image_member_client.tenant_id
 
     def _create_image(self):
-        image_file = moves.cStringIO(data_utils.random_bytes())
+        image_file = six.BytesIO(data_utils.random_bytes())
         image = self.create_image(container_format='bare',
                                   disk_format='raw',
                                   is_public=False,
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 694408d..712b34b 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
+import six
 
 from tempest.api.image import base
 from tempest.common import image as common_image
@@ -63,7 +63,7 @@
             self.assertEqual(val, body.get('properties')[key])
 
         # Now try uploading an image file
-        image_file = moves.cStringIO(data_utils.random_bytes())
+        image_file = six.BytesIO(data_utils.random_bytes())
         body = self.client.update_image(image_id, data=image_file)['image']
         self.assertIn('size', body)
         self.assertEqual(1024, body.get('size'))
@@ -199,7 +199,7 @@
         Note that the size of the new image is a random number between
         1024 and 4096
         """
-        image_file = moves.cStringIO(data_utils.random_bytes(size))
+        image_file = six.BytesIO(data_utils.random_bytes(size))
         name = 'New Standard Image %s' % name
         image = cls.create_image(name=name,
                                  container_format=container_format,
@@ -294,7 +294,7 @@
                                disk_format, size):
         """Create a new standard image and return newly-registered image-id"""
 
-        image_file = moves.cStringIO(data_utils.random_bytes(size))
+        image_file = six.BytesIO(data_utils.random_bytes(size))
         name = 'New Standard Image %s' % name
         image = cls.create_image(name=name,
                                  container_format=container_format,
diff --git a/tempest/api/image/v1/test_images_negative.py b/tempest/api/image/v1/test_images_negative.py
index 9e67c25..d8f103a 100644
--- a/tempest/api/image/v1/test_images_negative.py
+++ b/tempest/api/image/v1/test_images_negative.py
@@ -40,13 +40,6 @@
                                    'x-image-meta-disk_format': 'wrong'})
 
     @test.attr(type=['negative'])
-    @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(lib_exc.NotFound, self.client.delete_image,
-                          '!@$%^&*()')
-
-    @test.attr(type=['negative'])
     @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
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 42a4352..f363d34 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -16,7 +16,7 @@
 
 import random
 
-from six import moves
+import six
 
 from oslo_log import log as logging
 from tempest.api.image import base
@@ -60,7 +60,7 @@
 
         # Now try uploading an image file
         file_content = data_utils.random_bytes()
-        image_file = moves.cStringIO(file_content)
+        image_file = six.BytesIO(file_content)
         self.client.store_image_file(image_id, image_file)
 
         # Now try to get image details
@@ -117,7 +117,7 @@
         image_id = body['id']
 
         # Now try uploading an image file
-        image_file = moves.cStringIO(data_utils.random_bytes())
+        image_file = six.BytesIO(data_utils.random_bytes())
         self.client.store_image_file(image_id, image_file)
 
         # Update Image
@@ -160,7 +160,7 @@
         1024 and 4096
         """
         size = random.randint(1024, 4096)
-        image_file = moves.cStringIO(data_utils.random_bytes(size))
+        image_file = six.BytesIO(data_utils.random_bytes(size))
         name = data_utils.rand_name('image')
         body = cls.create_image(name=name,
                                 container_format=container_format,
@@ -250,6 +250,16 @@
         self.assertEqual(len(images_list), params['limit'],
                          "Failed to get images by limit")
 
+    @test.idempotent_id('e9a44b91-31c8-4b40-a332-e0a39ffb4dbb')
+    def test_list_image_param_owner(self):
+        # Test to get images by owner
+        image_id = self.created_images[0]
+        # Get image metadata
+        image = self.client.show_image(image_id)
+
+        params = {"owner": image['owner']}
+        self._list_by_param_value_and_assert(params)
+
     @test.idempotent_id('622b925c-479f-4736-860d-adeaf13bc371')
     def test_get_image_schema(self):
         # Test to get image schema
diff --git a/tempest/api/image/v2/test_images_metadefs_resource_types.py b/tempest/api/image/v2/test_images_metadefs_resource_types.py
index a5143a1..3dd432b 100644
--- a/tempest/api/image/v2/test_images_metadefs_resource_types.py
+++ b/tempest/api/image/v2/test_images_metadefs_resource_types.py
@@ -18,7 +18,7 @@
 
 
 class MetadataResourceTypesTest(base.BaseV2ImageTest):
-    """Test the Metadata definition ressource types basic functionality"""
+    """Test the Metadata definition resource types basic functionality"""
 
     @test.idempotent_id('6f358a4e-5ef0-11e6-a795-080027d0d606')
     def test_basic_meta_def_resource_type_association(self):
@@ -34,7 +34,7 @@
         # NOTE(raiesmh08): Here intentionally I have not added addcleanup
         # method for resource type dissociation because its a metadata add and
         # being cleaned as soon as namespace is cleaned at test case level.
-        # When namespace cleans, resource type associaion will automatically
+        # When namespace cleans, resource type association will automatically
         # clean without any error or dependency.
 
         # List resource type associations and validate creation
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 2ff31e0..3a264ff 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -87,5 +87,5 @@
 
     @test.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
     def test_quotas(self):
-        new_quotas = {'network': 0, 'security_group': 0}
+        new_quotas = {'network': 0, 'port': 0}
         self._check_quotas(new_quotas)
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 77008ab..c1462db 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -30,7 +30,7 @@
 class NetworksTestDHCPv6(base.BaseNetworkTest):
     _ip_version = 6
 
-    """ Test DHCPv6 specific features using SLAAC, stateless and
+    """Test DHCPv6 specific features using SLAAC, stateless and
     stateful settings for subnets. Also it shall check dual-stack
     functionality (IPv4 + IPv6 together).
     The tests include:
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index caf7f14..e5972a9 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -16,6 +16,7 @@
 import socket
 
 import netaddr
+import testtools
 
 from tempest.api.network import base
 from tempest.api.network import base_security_groups as sec_base
@@ -308,11 +309,17 @@
             self.assertIn(security_group, port_show['security_groups'])
 
     @test.idempotent_id('58091b66-4ff4-4cc1-a549-05d60c7acd1a')
+    @testtools.skipUnless(
+        test.is_extension_enabled('security-group', 'network'),
+        'security-group extension not enabled.')
     def test_update_port_with_security_group_and_extra_attributes(self):
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup')])
 
     @test.idempotent_id('edf6766d-3d40-4621-bc6e-2521a44c257d')
+    @testtools.skipUnless(
+        test.is_extension_enabled('security-group', 'network'),
+        'security-group extension not enabled.')
     def test_update_port_with_two_security_groups_and_extra_attributes(self):
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup'),
@@ -337,6 +344,9 @@
 
     @test.attr(type='smoke')
     @test.idempotent_id('4179dcb9-1382-4ced-84fe-1b91c54f5735')
+    @testtools.skipUnless(
+        test.is_extension_enabled('security-group', 'network'),
+        'security-group extension not enabled.')
     def test_create_port_with_no_securitygroups(self):
         network = self.create_network()
         self.addCleanup(self.networks_client.delete_network, network['id'])
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 85026af..fd973c6 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -58,6 +58,16 @@
         cls.container_client.auth_provider.clear_auth()
         cls.account_client.auth_provider.clear_auth()
 
+        # make sure that discoverability is enabled and that the sections
+        # have not been disallowed by Swift
+        cls.policies = None
+
+        if CONF.object_storage_feature_enabled.discoverability:
+            _, body = cls.account_client.list_extensions()
+
+            if 'swift' in body and 'policies' in body['swift']:
+                cls.policies = body['swift']['policies']
+
         cls.containers = []
 
     @classmethod
@@ -117,5 +127,5 @@
         """Check the existence and the format of response headers"""
 
         self.assertThat(resp, custom_matchers.ExistsAllResponseHeaders(
-                        target, method))
+                        target, method, self.policies))
         self.assertThat(resp, custom_matchers.AreAllWellFormatted())
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 9e9f08b..33e5852 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -15,7 +15,6 @@
 
 import random
 
-from six import moves
 import testtools
 
 from tempest.api.object_storage import base
@@ -42,7 +41,7 @@
     @classmethod
     def resource_setup(cls):
         super(AccountTest, cls).resource_setup()
-        for i in moves.xrange(ord('a'), ord('f') + 1):
+        for i in range(ord('a'), ord('f') + 1):
             name = data_utils.rand_name(name='%s-' % chr(i))
             cls.container_client.create_container(name)
             cls.containers.append(name)
@@ -80,7 +79,7 @@
         # headers is checked without custom matcher.
         #
         # As the expected response is 204 No Content, Content-Length presence
-        # is not checked here intensionally. According to RFC 7230 a server
+        # is not checked here intentionally. According to RFC 7230 a server
         # MUST NOT send the header in such responses. Thus, clients should not
         # depend on this header. However, the standard does not require them
         # to validate the server's behavior. We leverage that to not refuse
@@ -140,7 +139,8 @@
     @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):
+        for limit in (1, self.containers_count // 2,
+                      self.containers_count):
             params = {'limit': limit}
             resp, container_list = \
                 self.account_client.list_account_containers(params=params)
@@ -161,12 +161,13 @@
 
         self.assertEqual(len(container_list), 0)
 
-        params = {'marker': self.containers[self.containers_count / 2]}
+        params = {'marker': self.containers[self.containers_count // 2]}
         resp, container_list = \
             self.account_client.list_account_containers(params=params)
         self.assertHeaders(resp, 'Account', 'GET')
 
-        self.assertEqual(len(container_list), self.containers_count / 2 - 1)
+        self.assertEqual(len(container_list),
+                         self.containers_count // 2 - 1)
 
     @test.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
     def test_list_containers_with_end_marker(self):
@@ -180,11 +181,11 @@
         self.assertHeaders(resp, 'Account', 'GET')
         self.assertEqual(len(container_list), 0)
 
-        params = {'end_marker': self.containers[self.containers_count / 2]}
+        params = {'end_marker': self.containers[self.containers_count // 2]}
         resp, container_list = \
             self.account_client.list_account_containers(params=params)
         self.assertHeaders(resp, 'Account', 'GET')
-        self.assertEqual(len(container_list), self.containers_count / 2)
+        self.assertEqual(len(container_list), self.containers_count // 2)
 
     @test.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
     def test_list_containers_with_marker_and_end_marker(self):
@@ -215,12 +216,12 @@
         # list containers combining limit and end_marker param
         limit = random.randint(1, self.containers_count)
         params = {'limit': limit,
-                  'end_marker': self.containers[self.containers_count / 2]}
+                  'end_marker': self.containers[self.containers_count // 2]}
         resp, container_list = self.account_client.list_account_containers(
             params=params)
         self.assertHeaders(resp, 'Account', 'GET')
         self.assertEqual(len(container_list),
-                         min(limit, self.containers_count / 2))
+                         min(limit, self.containers_count // 2))
 
     @test.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
     def test_list_containers_with_limit_and_marker_and_end_marker(self):
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index 8522269..dbe8b4a 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -63,7 +63,8 @@
         # create container with metadata value
         container_name = data_utils.rand_name(name='TestContainer')
 
-        metadata = {'test-container-meta': 'Meta1'}
+        # metadata name using underscores should be converted to hyphens
+        metadata = {'test_container_meta': 'Meta1'}
         resp, _ = self.container_client.create_container(
             container_name,
             metadata=metadata)
@@ -74,7 +75,7 @@
             container_name)
         self.assertIn('x-container-meta-test-container-meta', resp)
         self.assertEqual(resp['x-container-meta-test-container-meta'],
-                         metadata['test-container-meta'])
+                         metadata['test_container_meta'])
 
     @test.idempotent_id('24d16451-1c0c-4e4f-b59c-9840a3aba40e')
     def test_create_container_with_remove_metadata_key(self):
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index a707ebb..8736f9a 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -47,9 +47,9 @@
         object_name = data_utils.rand_name(name='LObject')
         data = data_utils.arbitrary_string()
         segments = 10
-        data_segments = [data + str(i) for i in six.moves.xrange(segments)]
+        data_segments = [data + str(i) for i in range(segments)]
         # uploading segments
-        for i in six.moves.xrange(segments):
+        for i in range(segments):
             resp, _ = self.object_client.create_object_segments(
                 self.container_name, object_name, i, data_segments[i])
 
@@ -901,9 +901,9 @@
         object_name = data_utils.rand_name(name='LObject')
         data = data_utils.arbitrary_string()
         segments = 10
-        data_segments = [data + str(i) for i in six.moves.xrange(segments)]
+        data_segments = [data + str(i) for i in range(segments)]
         # uploading segments
-        for i in six.moves.xrange(segments):
+        for i in range(segments):
             resp, _ = self.object_client.create_object_segments(
                 self.container_name, object_name, i, data_segments[i])
         # creating a manifest file
@@ -954,10 +954,7 @@
         # When the file is not downloaded from Swift server, response does
         # not contain 'X-Timestamp' header. This is the special case, therefore
         # the existence of response headers is checked without custom matcher.
-        self.assertIn('content-type', resp)
-        self.assertIn('x-trans-id', resp)
         self.assertIn('date', resp)
-        self.assertIn('accept-ranges', resp)
         # Check only the format of common headers with custom matcher
         self.assertThat(resp, custom_matchers.AreAllWellFormatted())
 
diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
index 0400e76..8d12e75 100644
--- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -72,10 +72,10 @@
         for outputs in stack['outputs']:
             output_map[outputs['output_key']] = outputs['output_value']
         # Test that first key generated public and private keys
-        self.assertTrue('KeyPair_PublicKey' in output_map)
-        self.assertTrue("Generated" in output_map['KeyPair_PublicKey'])
-        self.assertTrue('KeyPair_PrivateKey' in output_map)
-        self.assertTrue('-----BEGIN' in output_map['KeyPair_PrivateKey'])
+        self.assertIn('KeyPair_PublicKey', output_map)
+        self.assertIn("Generated", output_map['KeyPair_PublicKey'])
+        self.assertIn('KeyPair_PrivateKey', output_map)
+        self.assertIn('-----BEGIN', output_map['KeyPair_PrivateKey'])
         # Test that second key generated public key, and private key is not
         # in the output due to save_private_key = false
         self.assertTrue('KeyPairDontSavePrivate_PublicKey' in output_map)
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index f7013d8..73f1f8f 100755
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -13,9 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import base64
-import six
-
+from oslo_serialization import base64
 from oslo_serialization import jsonutils as json
 
 from tempest.api.volume import base
@@ -46,13 +44,11 @@
         self.admin_backups_client.wait_for_resource_deletion(backup_id)
 
     def _decode_url(self, backup_url):
-        return json.loads(base64.decodestring(backup_url))
+        return json.loads(base64.decode_as_text(backup_url))
 
     def _encode_backup(self, backup):
         retval = json.dumps(backup)
-        if six.PY3:
-            retval = retval.encode('utf-8')
-        return base64.encodestring(retval)
+        return base64.encode_as_text(retval)
 
     def _modify_backup_url(self, backup_url, changes):
         backup = self._decode_url(backup_url)
@@ -72,8 +68,8 @@
             volume_id=self.volume['id'], name=backup_name)['backup'])
         self.addCleanup(self._delete_backup, backup['id'])
         self.assertEqual(backup_name, backup['name'])
-        self.admin_backups_client.wait_for_backup_status(backup['id'],
-                                                         'available')
+        waiters.wait_for_backup_status(self.admin_backups_client,
+                                       backup['id'], 'available')
 
         # Export Backup
         export_backup = (self.admin_backups_client.export_backup(backup['id'])
@@ -105,8 +101,8 @@
         self.addCleanup(self._delete_backup, new_id)
         self.assertIn("id", import_backup)
         self.assertEqual(new_id, import_backup['id'])
-        self.admin_backups_client.wait_for_backup_status(import_backup['id'],
-                                                         'available')
+        waiters.wait_for_backup_status(self.admin_backups_client,
+                                       import_backup['id'], 'available')
 
         # Verify Import Backup
         backups = self.admin_backups_client.list_backups(
@@ -125,8 +121,8 @@
         # Verify if restored volume is there in volume list
         volumes = self.admin_volume_client.list_volumes()['volumes']
         self.assertIn(restore['volume_id'], [v['id'] for v in volumes])
-        self.admin_backups_client.wait_for_backup_status(import_backup['id'],
-                                                         'available')
+        waiters.wait_for_backup_status(self.admin_backups_client,
+                                       import_backup['id'], 'available')
 
     @test.idempotent_id('47a35425-a891-4e13-961c-c45deea21e94')
     def test_volume_backup_reset_status(self):
@@ -138,13 +134,13 @@
         self.addCleanup(self.admin_backups_client.delete_backup,
                         backup['id'])
         self.assertEqual(backup_name, backup['name'])
-        self.admin_backups_client.wait_for_backup_status(backup['id'],
-                                                         'available')
+        waiters.wait_for_backup_status(self.admin_backups_client,
+                                       backup['id'], 'available')
         # Reset backup status to error
         self.admin_backups_client.reset_backup_status(backup_id=backup['id'],
                                                       status="error")
-        self.admin_backups_client.wait_for_backup_status(backup['id'],
-                                                         'error')
+        waiters.wait_for_backup_status(self.admin_backups_client,
+                                       backup['id'], 'error')
 
 
 class VolumesBackupsAdminV1Test(VolumesBackupsAdminV2Test):
diff --git a/tempest/api/volume/v3/admin/__init__.py b/tempest/api/volume/admin/v2/__init__.py
similarity index 100%
rename from tempest/api/volume/v3/admin/__init__.py
rename to tempest/api/volume/admin/v2/__init__.py
diff --git a/tempest/api/volume/admin/test_volume_pools.py b/tempest/api/volume/admin/v2/test_volume_pools.py
similarity index 100%
rename from tempest/api/volume/admin/test_volume_pools.py
rename to tempest/api/volume/admin/v2/test_volume_pools.py
diff --git a/tempest/api/volume/admin/test_volume_type_access.py b/tempest/api/volume/admin/v2/test_volume_type_access.py
similarity index 100%
rename from tempest/api/volume/admin/test_volume_type_access.py
rename to tempest/api/volume/admin/v2/test_volume_type_access.py
diff --git a/tempest/api/volume/admin/test_volumes_list.py b/tempest/api/volume/admin/v2/test_volumes_list.py
similarity index 100%
rename from tempest/api/volume/admin/test_volumes_list.py
rename to tempest/api/volume/admin/v2/test_volumes_list.py
diff --git a/tempest/api/volume/v3/admin/__init__.py b/tempest/api/volume/admin/v3/__init__.py
similarity index 100%
copy from tempest/api/volume/v3/admin/__init__.py
copy to tempest/api/volume/admin/v3/__init__.py
diff --git a/tempest/api/volume/v3/admin/test_user_messages.py b/tempest/api/volume/admin/v3/test_user_messages.py
similarity index 100%
rename from tempest/api/volume/v3/admin/test_user_messages.py
rename to tempest/api/volume/admin/v3/test_user_messages.py
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 786538b..b49a126 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -172,14 +172,19 @@
             except Exception:
                 pass
 
-    @classmethod
-    def create_server(cls, name, **kwargs):
-        tenant_network = cls.get_tenant_network()
+    def create_server(self, name, **kwargs):
+        tenant_network = self.get_tenant_network()
         body, _ = compute.create_test_server(
-            cls.os,
+            self.os,
             tenant_network=tenant_network,
             name=name,
             **kwargs)
+
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        waiters.wait_for_server_termination,
+                        self.servers_client, body['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.servers_client.delete_server, body['id'])
         return body
 
 
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index e529538..ee1744d 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -26,11 +26,10 @@
         super(VolumesV2MetadataTest, cls).resource_setup()
         # Create a volume
         cls.volume = cls.create_volume()
-        cls.volume_id = cls.volume['id']
 
     def tearDown(self):
         # Update the metadata to {}
-        self.volumes_client.update_volume_metadata(self.volume_id, {})
+        self.volumes_client.update_volume_metadata(self.volume['id'], {})
         super(VolumesV2MetadataTest, self).tearDown()
 
     @test.idempotent_id('6f5b125b-f664-44bf-910f-751591fe5769')
@@ -41,17 +40,17 @@
                     "key3": "value3",
                     "key4": "<value&special_chars>"}
 
-        body = self.volumes_client.create_volume_metadata(self.volume_id,
+        body = self.volumes_client.create_volume_metadata(self.volume['id'],
                                                           metadata)['metadata']
         # Get the metadata of the volume
         body = self.volumes_client.show_volume_metadata(
-            self.volume_id)['metadata']
+            self.volume['id'])['metadata']
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Delete one item metadata of the volume
         self.volumes_client.delete_volume_metadata_item(
-            self.volume_id, "key1")
+            self.volume['id'], "key1")
         body = self.volumes_client.show_volume_metadata(
-            self.volume_id)['metadata']
+            self.volume['id'])['metadata']
         self.assertNotIn("key1", body)
         del metadata["key1"]
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
@@ -68,17 +67,17 @@
 
         # Create metadata for the volume
         body = self.volumes_client.create_volume_metadata(
-            self.volume_id, metadata)['metadata']
+            self.volume['id'], metadata)['metadata']
         # Get the metadata of the volume
         body = self.volumes_client.show_volume_metadata(
-            self.volume_id)['metadata']
+            self.volume['id'])['metadata']
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Update metadata
         body = self.volumes_client.update_volume_metadata(
-            self.volume_id, update)['metadata']
+            self.volume['id'], update)['metadata']
         # Get the metadata of the volume
         body = self.volumes_client.show_volume_metadata(
-            self.volume_id)['metadata']
+            self.volume['id'])['metadata']
         self.assertEqual(update, body)
 
     @test.idempotent_id('862261c5-8df4-475a-8c21-946e50e36a20')
@@ -93,14 +92,14 @@
                   "key3": "value3_update"}
         # Create metadata for the volume
         body = self.volumes_client.create_volume_metadata(
-            self.volume_id, metadata)['metadata']
+            self.volume['id'], metadata)['metadata']
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Update metadata item
         body = self.volumes_client.update_volume_metadata_item(
-            self.volume_id, "key3", update_item)['meta']
+            self.volume['id'], "key3", update_item)['meta']
         # Get the metadata of the volume
         body = self.volumes_client.show_volume_metadata(
-            self.volume_id)['metadata']
+            self.volume['id'])['metadata']
         self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
 
 
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 7783c18..b80a4a4 100755
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -45,34 +45,25 @@
     @classmethod
     def resource_setup(cls):
         super(VolumesV2ActionsTest, cls).resource_setup()
-        # Create a test shared instance
-        srv_name = data_utils.rand_name(cls.__name__ + '-Instance')
-        cls.server = cls.create_server(
-            name=srv_name,
-            wait_until='ACTIVE')
 
         # Create a test shared volume for attach/detach tests
         cls.volume = cls.create_volume()
         waiters.wait_for_volume_status(cls.client,
                                        cls.volume['id'], 'available')
 
-    @classmethod
-    def resource_cleanup(cls):
-        # Delete the test instance
-        cls.servers_client.delete_server(cls.server['id'])
-        waiters.wait_for_server_termination(cls.servers_client,
-                                            cls.server['id'])
-
-        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')
     def test_attach_detach_volume_to_instance(self):
+        # Create a server
+        srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
+        server = self.create_server(
+            name=srv_name,
+            wait_until='ACTIVE')
         # Volume is attached and detached successfully from an instance
         self.client.attach_volume(self.volume['id'],
-                                  instance_uuid=self.server['id'],
+                                  instance_uuid=server['id'],
                                   mountpoint='/dev/%s' %
                                              CONF.compute.volume_device_name)
         waiters.wait_for_volume_status(self.client,
@@ -99,9 +90,14 @@
     @test.stresstest(class_setup_per='process')
     @test.services('compute')
     def test_get_volume_attachment(self):
+        # Create a server
+        srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
+        server = self.create_server(
+            name=srv_name,
+            wait_until='ACTIVE')
         # Verify that a volume's attachment information is retrieved
         self.client.attach_volume(self.volume['id'],
-                                  instance_uuid=self.server['id'],
+                                  instance_uuid=server['id'],
                                   mountpoint='/dev/%s' %
                                              CONF.compute.volume_device_name)
         waiters.wait_for_volume_status(self.client,
@@ -119,7 +115,7 @@
         self.assertEqual('/dev/%s' %
                          CONF.compute.volume_device_name,
                          attachment['device'])
-        self.assertEqual(self.server['id'], attachment['server_id'])
+        self.assertEqual(server['id'], attachment['server_id'])
         self.assertEqual(self.volume['id'], attachment['id'])
         self.assertEqual(self.volume['id'], attachment['volume_id'])
 
diff --git a/tempest/api/volume/test_volumes_backup.py b/tempest/api/volume/test_volumes_backup.py
index 50a1360..867e520 100755
--- a/tempest/api/volume/test_volumes_backup.py
+++ b/tempest/api/volume/test_volumes_backup.py
@@ -30,10 +30,6 @@
         if not CONF.volume_feature_enabled.backup:
             raise cls.skipException("Cinder backup feature disabled")
 
-    @classmethod
-    def resource_setup(cls):
-        super(VolumesBackupsV2Test, cls).resource_setup()
-
     @test.idempotent_id('a66eb488-8ee1-47d4-8e9f-575a095728c6')
     def test_volume_backup_create_get_detailed_list_restore_delete(self):
         # Create backup
@@ -50,8 +46,8 @@
         self.assertEqual(backup_name, backup['name'])
         waiters.wait_for_volume_status(self.volumes_client,
                                        volume['id'], 'available')
-        self.backups_client.wait_for_backup_status(backup['id'],
-                                                   'available')
+        waiters.wait_for_backup_status(self.backups_client,
+                                       backup['id'], 'available')
 
         # Get a given backup
         backup = self.backups_client.show_backup(backup['id'])['backup']
@@ -71,8 +67,8 @@
         self.addCleanup(self.volumes_client.delete_volume,
                         restore['volume_id'])
         self.assertEqual(backup['id'], restore['backup_id'])
-        self.backups_client.wait_for_backup_status(backup['id'],
-                                                   'available')
+        waiters.wait_for_backup_status(self.backups_client,
+                                       backup['id'], 'available')
         waiters.wait_for_volume_status(self.volumes_client,
                                        restore['volume_id'], 'available')
 
@@ -91,7 +87,6 @@
         server_name = data_utils.rand_name(
             self.__class__.__name__ + '-instance')
         server = self.create_server(name=server_name, wait_until='ACTIVE')
-        self.addCleanup(self.servers_client.delete_server, server['id'])
         # Attach volume to instance
         self.servers_client.attach_volume(server['id'],
                                           volumeId=volume['id'])
@@ -108,8 +103,8 @@
             volume_id=volume['id'],
             name=backup_name, force=True)['backup']
         self.addCleanup(self.backups_client.delete_backup, backup['id'])
-        self.backups_client.wait_for_backup_status(backup['id'],
-                                                   'available')
+        waiters.wait_for_backup_status(self.backups_client,
+                                       backup['id'], 'available')
         self.assertEqual(backup_name, backup['name'])
 
 
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 16c8571..e8ead5b 100755
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -15,7 +15,6 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest.common import waiters
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -181,9 +180,6 @@
         server = self.create_server(
             name=srv_name,
             wait_until='ACTIVE')
-        self.addCleanup(waiters.wait_for_server_termination,
-                        self.servers_client, server['id'])
-        self.addCleanup(self.servers_client.delete_server, server['id'])
 
         self.assertRaises(lib_exc.NotFound,
                           self.client.attach_volume,
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 20c647a..6be569c 100755
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -14,7 +14,6 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
-from tempest.lib import decorators
 from tempest import test
 
 CONF = config.CONF
@@ -32,12 +31,8 @@
     def resource_setup(cls):
         super(VolumesV2SnapshotTestJSON, cls).resource_setup()
         cls.volume_origin = cls.create_volume()
-
         cls.name_field = cls.special_fields['name_field']
         cls.descrip_field = cls.special_fields['descrip_field']
-        # Create 2 snapshots
-        for _ in xrange(2):
-            cls.create_snapshot(cls.volume_origin['id'])
 
     def _detach(self, volume_id):
         """Detach volume."""
@@ -45,31 +40,6 @@
         waiters.wait_for_volume_status(self.volumes_client,
                                        volume_id, 'available')
 
-    def _list_by_param_values_and_assert(self, with_detail=False, **params):
-        """list or list_details with given params and validates result."""
-
-        if with_detail:
-            fetched_snap_list = self.snapshots_client.list_snapshots(
-                detail=True, **params)['snapshots']
-        else:
-            fetched_snap_list = self.snapshots_client.list_snapshots(
-                **params)['snapshots']
-
-        # Validating params of fetched snapshots
-        for snap in fetched_snap_list:
-            for key in params:
-                msg = "Failed to list snapshots %s by %s" % \
-                      ('details' if with_detail else '', key)
-                self.assertEqual(params[key], snap[key], msg)
-
-    def _list_snapshots_by_param_limit(self, limit, expected_elements):
-        """list snapshots by limit param"""
-        # Get snapshots list using limit parameter
-        fetched_snap_list = self.snapshots_client.list_snapshots(
-            limit=limit)['snapshots']
-        # Validating filtered snapshots length equals to expected_elements
-        self.assertEqual(expected_elements, len(fetched_snap_list))
-
     @test.idempotent_id('b467b54c-07a4-446d-a1cf-651dedcc3ff1')
     @test.services('compute')
     def test_snapshot_create_with_volume_in_use(self):
@@ -80,7 +50,6 @@
         server = self.create_server(
             name=server_name,
             wait_until='ACTIVE')
-        self.addCleanup(self.servers_client.delete_server, server['id'])
         self.servers_client.attach_volume(
             server['id'], volumeId=self.volume_origin['id'],
             device='/dev/%s' % CONF.compute.volume_device_name)
@@ -136,48 +105,6 @@
         # Delete the snapshot
         self.cleanup_snapshot(snapshot)
 
-    @test.idempotent_id('59f41f43-aebf-48a9-ab5d-d76340fab32b')
-    def test_snapshots_list_with_params(self):
-        """list snapshots with params."""
-        # Create a snapshot
-        display_name = data_utils.rand_name(self.__class__.__name__ + '-snap')
-        params = {self.name_field: display_name}
-        snapshot = self.create_snapshot(self.volume_origin['id'], **params)
-        self.addCleanup(self.cleanup_snapshot, snapshot)
-
-        # Verify list snapshots by display_name filter
-        params = {self.name_field: snapshot[self.name_field]}
-        self._list_by_param_values_and_assert(**params)
-
-        # Verify list snapshots by status filter
-        params = {'status': 'available'}
-        self._list_by_param_values_and_assert(**params)
-
-        # Verify list snapshots by status and display name filter
-        params = {'status': 'available',
-                  self.name_field: snapshot[self.name_field]}
-        self._list_by_param_values_and_assert(**params)
-
-    @test.idempotent_id('220a1022-1fcd-4a74-a7bd-6b859156cda2')
-    def test_snapshots_list_details_with_params(self):
-        """list snapshot details with params."""
-        # Create a snapshot
-        display_name = data_utils.rand_name(self.__class__.__name__ + '-snap')
-        params = {self.name_field: display_name}
-        snapshot = self.create_snapshot(self.volume_origin['id'], **params)
-        self.addCleanup(self.cleanup_snapshot, snapshot)
-
-        # Verify list snapshot details by display_name filter
-        params = {self.name_field: snapshot[self.name_field]}
-        self._list_by_param_values_and_assert(with_detail=True, **params)
-        # Verify list snapshot details by status filter
-        params = {'status': 'available'}
-        self._list_by_param_values_and_assert(with_detail=True, **params)
-        # Verify list snapshot details by status and display name filter
-        params = {'status': 'available',
-                  self.name_field: snapshot[self.name_field]}
-        self._list_by_param_values_and_assert(with_detail=True, **params)
-
     @test.idempotent_id('677863d1-3142-456d-b6ac-9924f667a7f4')
     def test_volume_from_snapshot(self):
         # Creates a volume a snapshot passing a size different from the source
@@ -194,25 +121,6 @@
         self.assertEqual(volume['snapshot_id'], src_snap['id'])
         self.assertEqual(int(volume['size']), src_size + 1)
 
-    @test.idempotent_id('db4d8e0a-7a2e-41cc-a712-961f6844e896')
-    def test_snapshot_list_param_limit(self):
-        # List returns limited elements
-        self._list_snapshots_by_param_limit(limit=1, expected_elements=1)
-
-    @test.idempotent_id('a1427f61-420e-48a5-b6e3-0b394fa95400')
-    def test_snapshot_list_param_limit_equals_infinite(self):
-        # List returns all elements when request limit exceeded
-        # snapshots number
-        snap_list = self.snapshots_client.list_snapshots()['snapshots']
-        self._list_snapshots_by_param_limit(limit=100000,
-                                            expected_elements=len(snap_list))
-
-    @decorators.skip_because(bug='1540893')
-    @test.idempotent_id('e3b44b7f-ae87-45b5-8a8c-66110eb24d0a')
-    def test_snapshot_list_param_limit_equals_zero(self):
-        # List returns zero elements
-        self._list_snapshots_by_param_limit(limit=0, expected_elements=0)
-
     def cleanup_snapshot(self, snapshot):
         # Delete the snapshot
         self.snapshots_client.delete_snapshot(snapshot['id'])
diff --git a/tempest/api/volume/test_volumes_snapshots_list.py b/tempest/api/volume/test_volumes_snapshots_list.py
new file mode 100644
index 0000000..4416bef
--- /dev/null
+++ b/tempest/api/volume/test_volumes_snapshots_list.py
@@ -0,0 +1,116 @@
+#    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.volume import base
+from tempest import config
+from tempest.lib import decorators
+from tempest import test
+
+CONF = config.CONF
+
+
+class VolumesV2SnapshotListTestJSON(base.BaseVolumeTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(VolumesV2SnapshotListTestJSON, cls).skip_checks()
+        if not CONF.volume_feature_enabled.snapshot:
+            raise cls.skipException("Cinder volume snapshots are disabled")
+
+    @classmethod
+    def resource_setup(cls):
+        super(VolumesV2SnapshotListTestJSON, cls).resource_setup()
+        cls.volume_origin = cls.create_volume()
+        cls.name_field = cls.special_fields['name_field']
+        # Create snapshots with params
+        for _ in range(2):
+            cls.snapshot = cls.create_snapshot(cls.volume_origin['id'])
+
+    def _list_by_param_values_and_assert(self, with_detail=False, **params):
+        """list or list_details with given params and validates result."""
+
+        fetched_snap_list = self.snapshots_client.list_snapshots(
+            detail=with_detail, **params)['snapshots']
+
+        # Validating params of fetched snapshots
+        for snap in fetched_snap_list:
+            for key in params:
+                msg = "Failed to list snapshots %s by %s" % \
+                      ('details' if with_detail else '', key)
+                self.assertEqual(params[key], snap[key], msg)
+
+    def _list_snapshots_by_param_limit(self, limit, expected_elements):
+        """list snapshots by limit param"""
+        # Get snapshots list using limit parameter
+        fetched_snap_list = self.snapshots_client.list_snapshots(
+            limit=limit)['snapshots']
+        # Validating filtered snapshots length equals to expected_elements
+        self.assertEqual(expected_elements, len(fetched_snap_list))
+
+    @test.idempotent_id('59f41f43-aebf-48a9-ab5d-d76340fab32b')
+    def test_snapshots_list_with_params(self):
+        """list snapshots with params."""
+        # Verify list snapshots by display_name filter
+        params = {self.name_field: self.snapshot[self.name_field]}
+        self._list_by_param_values_and_assert(**params)
+
+        # Verify list snapshots by status filter
+        params = {'status': 'available'}
+        self._list_by_param_values_and_assert(**params)
+
+        # Verify list snapshots by status and display name filter
+        params = {'status': 'available',
+                  self.name_field: self.snapshot[self.name_field]}
+        self._list_by_param_values_and_assert(**params)
+
+    @test.idempotent_id('220a1022-1fcd-4a74-a7bd-6b859156cda2')
+    def test_snapshots_list_details_with_params(self):
+        """list snapshot details with params."""
+        # Verify list snapshot details by display_name filter
+        params = {self.name_field: self.snapshot[self.name_field]}
+        self._list_by_param_values_and_assert(with_detail=True, **params)
+        # Verify list snapshot details by status filter
+        params = {'status': 'available'}
+        self._list_by_param_values_and_assert(with_detail=True, **params)
+        # Verify list snapshot details by status and display name filter
+        params = {'status': 'available',
+                  self.name_field: self.snapshot[self.name_field]}
+        self._list_by_param_values_and_assert(with_detail=True, **params)
+
+    @test.idempotent_id('db4d8e0a-7a2e-41cc-a712-961f6844e896')
+    def test_snapshot_list_param_limit(self):
+        # List returns limited elements
+        self._list_snapshots_by_param_limit(limit=1, expected_elements=1)
+
+    @test.idempotent_id('a1427f61-420e-48a5-b6e3-0b394fa95400')
+    def test_snapshot_list_param_limit_equals_infinite(self):
+        # List returns all elements when request limit exceeded
+        # snapshots number
+        snap_list = self.snapshots_client.list_snapshots()['snapshots']
+        self._list_snapshots_by_param_limit(limit=100000,
+                                            expected_elements=len(snap_list))
+
+    @decorators.skip_because(bug='1540893')
+    @test.idempotent_id('e3b44b7f-ae87-45b5-8a8c-66110eb24d0a')
+    def test_snapshot_list_param_limit_equals_zero(self):
+        # List returns zero elements
+        self._list_snapshots_by_param_limit(limit=0, expected_elements=0)
+
+    def cleanup_snapshot(self, snapshot):
+        # Delete the snapshot
+        self.snapshots_client.delete_snapshot(snapshot['id'])
+        self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
+        self.snapshots.remove(snapshot)
+
+
+class VolumesV1SnapshotLimitTestJSON(VolumesV2SnapshotListTestJSON):
+    _api_version = 1
diff --git a/tempest/clients.py b/tempest/clients.py
index f8c276a..765a526 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -14,7 +14,9 @@
 #    under the License.
 
 import copy
+
 from oslo_log import log as logging
+
 from tempest.common import negative_rest_client
 from tempest import config
 from tempest import exceptions
@@ -115,7 +117,7 @@
                     configuration[service_for_config] = (
                         config.service_client_config(service_for_config))
             except lib_exc.UnknownServiceClient:
-                LOG.warn(
+                LOG.warning(
                     'Could not load configuration for service %s' % service)
 
         return configuration
@@ -246,6 +248,10 @@
             self.auth_provider, **params_v3)
         self.roles_v3_client = identity.v3.RolesClient(self.auth_provider,
                                                        **params_v3)
+        self.inherited_roles_client = identity.v3.InheritedRolesClient(
+            self.auth_provider, **params_v3)
+        self.role_assignments_client = identity.v3.RoleAssignmentsClient(
+            self.auth_provider, **params_v3)
         self.identity_services_v3_client = identity.v3.ServicesClient(
             self.auth_provider, **params_v3)
         self.policies_client = identity.v3.PoliciesClient(self.auth_provider,
diff --git a/tempest/cmd/init.py b/tempest/cmd/init.py
index eeca063..baa36a2 100644
--- a/tempest/cmd/init.py
+++ b/tempest/cmd/init.py
@@ -69,7 +69,10 @@
 
     def get_parser(self, prog_name):
         parser = super(TempestInit, self).get_parser(prog_name)
-        parser.add_argument('dir', nargs='?', default=os.getcwd())
+        parser.add_argument('dir', nargs='?', default=os.getcwd(),
+                            help="The path to the workspace directory. If you "
+                            "omit this argument, the workspace directory is "
+                            "your current directory")
         parser.add_argument('--config-dir', '-c', default=None)
         parser.add_argument('--show-global-config-dir', '-s',
                             action='store_true', dest='show_global_dir',
@@ -78,7 +81,7 @@
         parser.add_argument('--name', help="The workspace name", default=None)
         parser.add_argument('--workspace-path', default=None,
                             help="The path to the workspace file, the default "
-                                 "is ~/.tempest/workspace")
+                                 "is ~/.tempest/workspace.yaml")
         return parser
 
     def generate_testr_conf(self, local_path):
@@ -90,7 +93,7 @@
             testr_conf_file.write(testr_conf)
 
     def get_configparser(self, conf_path):
-        config_parse = moves.configparser.SafeConfigParser()
+        config_parse = moves.configparser.ConfigParser()
         config_parse.optionxform = str
         # get any existing values if a config file already exists
         if os.path.isfile(conf_path):
@@ -170,10 +173,10 @@
         workspace_manager = workspace.WorkspaceManager(
             parsed_args.workspace_path)
         name = parsed_args.name or parsed_args.dir.split(os.path.sep)[-1]
-        workspace_manager.register_new_workspace(
-            name, parsed_args.dir, init=True)
         config_dir = parsed_args.config_dir or get_tempest_default_config_dir()
         if parsed_args.show_global_dir:
             print("Global config dir is located at: %s" % config_dir)
             sys.exit(0)
         self.create_working_dir(parsed_args.dir, config_dir)
+        workspace_manager.register_new_workspace(
+            name, parsed_args.dir, init=True)
diff --git a/tempest/cmd/run.py b/tempest/cmd/run.py
index fef836c..236953c 100644
--- a/tempest/cmd/run.py
+++ b/tempest/cmd/run.py
@@ -264,8 +264,8 @@
 
             run_thread = threading.Thread(target=run_argv_thread)
             run_thread.start()
-            returncodes['subunit-trace'] = subunit_trace.trace(subunit_r,
-                                                               sys.stdout)
+            returncodes['subunit-trace'] = subunit_trace.trace(
+                subunit_r, sys.stdout, post_fails=True, print_failures=True)
             run_thread.join()
             subunit_r.close()
             # python version of pipefail
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 9947f2a..b2e72c5 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -46,7 +46,7 @@
     conf_dir = os.environ.get('TEMPEST_CONFIG_DIR', default_config_dir)
     conf_file = os.environ.get('TEMPEST_CONFIG', default_config_file)
     path = os.path.join(conf_dir, conf_file)
-    fd = open(path, 'rw')
+    fd = open(path, 'r+')
     return fd
 
 
@@ -370,10 +370,9 @@
     replace = opts.replace_ext
     global CONF_PARSER
 
-    outfile = sys.stdout
     if update:
         conf_file = _get_config_file()
-        CONF_PARSER = moves.configparser.SafeConfigParser()
+        CONF_PARSER = moves.configparser.ConfigParser()
         CONF_PARSER.optionxform = str
         CONF_PARSER.readfp(conf_file)
 
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index 998612b..b6ff241 100644
--- a/tempest/common/custom_matchers.py
+++ b/tempest/common/custom_matchers.py
@@ -28,7 +28,7 @@
     checked in each test code.
     """
 
-    def __init__(self, target, method):
+    def __init__(self, target, method, policies=None):
         """Initialization of ExistsAllResponseHeaders
 
         param: target Account/Container/Object
@@ -36,6 +36,7 @@
         """
         self.target = target
         self.method = method
+        self.policies = policies or []
 
     def _content_length_required(self, resp):
         # Verify whether given HTTP response must contain content-length.
@@ -84,11 +85,63 @@
                     return NonExistentHeader('x-account-container-count')
                 if 'x-account-object-count' not in actual:
                     return NonExistentHeader('x-account-object-count')
+                if actual['x-account-container-count'] > 0:
+                    acct_header = "x-account-storage-policy-"
+                    matched_policy_count = 0
+
+                    # Loop through the policies and look for account
+                    # usage data.  There should be at least 1 set
+                    for policy in self.policies:
+                        front_header = acct_header + policy['name'].lower()
+
+                        usage_policies = [
+                            front_header + '-bytes-used',
+                            front_header + '-object-count',
+                            front_header + '-container-count'
+                        ]
+
+                        # There should be 3 usage values for a give storage
+                        # policy in an account bytes, object count, and
+                        # container count
+                        policy_hdrs = sum(1 for use_hdr in usage_policies
+                                          if use_hdr in actual)
+
+                        # If there are less than 3 headers here then 1 is
+                        # missing, let's figure out which one and report
+                        if policy_hdrs == 3:
+                            matched_policy_count = matched_policy_count + 1
+                        else:
+                            if policy_hdrs > 0 and policy_hdrs < 3:
+                                for use_hdr in usage_policies:
+                                    if use_hdr not in actual:
+                                        return NonExistentHeader(use_hdr)
+
+                    # Only flag an error if actual policies have been read and
+                    # no usage has been found
+                    if self.policies and matched_policy_count == 0:
+                        return GenericError("No storage policy usage headers")
+
             elif self.target == 'Container':
                 if 'x-container-bytes-used' not in actual:
                     return NonExistentHeader('x-container-bytes-used')
                 if 'x-container-object-count' not in actual:
                     return NonExistentHeader('x-container-object-count')
+                if 'x-storage-policy' not in actual:
+                    return NonExistentHeader('x-storage-policy')
+                else:
+                    policy_name = actual['x-storage-policy']
+
+                    # loop through the policies and ensure that
+                    # the value in the container header matches
+                    # one of the storage policies
+                    for policy in self.policies:
+                        if policy['name'] == policy_name:
+                            break
+                    else:
+                        # Ensure that there are actual policies stored
+                        if self.policies:
+                            return InvalidHeaderValue('x-storage-policy',
+                                                      policy_name)
             elif self.target == 'Object':
                 if 'etag' not in actual:
                     return NonExistentHeader('etag')
@@ -114,6 +167,19 @@
         return None
 
 
+class GenericError(object):
+    """Informs an error message of a generic error during header evaluation"""
+
+    def __init__(self, body):
+        self.body = body
+
+    def describe(self):
+        return "%s" % self.body
+
+    def get_details(self):
+        return {}
+
+
 class NonExistentHeader(object):
     """Informs an error message in the case of missing a certain header"""
 
@@ -127,6 +193,20 @@
         return {}
 
 
+class InvalidHeaderValue(object):
+    """Informs an error message when a header contains a bad value"""
+
+    def __init__(self, header, value):
+        self.header = header
+        self.value = value
+
+    def describe(self):
+        return "InvalidValue (%s, %s)" % (self.header, self.value)
+
+    def get_details(self):
+        return {}
+
+
 class AreAllWellFormatted(object):
     """Specific matcher to check the correctness of formats of values
 
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 04c9645..b96b1c0 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -136,8 +136,6 @@
         email = data_utils.rand_name(root) + "@example.com"
         user = self.creds_client.create_user(
             username, user_password, project, email)
-        if 'user' in user:
-            user = user['user']
         role_assigned = False
         if admin:
             self.creds_client.assign_user_role(user, project, self.admin_role)
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index caab1fa..fa951b5 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -210,6 +210,27 @@
             raise exceptions.TimeoutException(message)
 
 
+def wait_for_backup_status(client, backup_id, status):
+    """Waits for a Backup to reach a given status."""
+    body = client.show_backup(backup_id)['backup']
+    backup_status = body['status']
+    start = int(time.time())
+
+    while backup_status != status:
+        time.sleep(client.build_interval)
+        body = client.show_backup(backup_id)['backup']
+        backup_status = body['status']
+        if backup_status == 'error' and backup_status != status:
+            raise exceptions.VolumeBackupException(backup_id=backup_id)
+
+        if int(time.time()) - start >= client.build_timeout:
+            message = ('Volume backup %s failed to reach %s status '
+                       '(current %s) within the required time (%s s).' %
+                       (backup_id, status, backup_status,
+                        client.build_timeout))
+            raise exceptions.TimeoutException(message)
+
+
 def wait_for_bm_node_status(client, node_id, attr, status):
     """Waits for a baremetal node attribute to reach given status.
 
diff --git a/tempest/config.py b/tempest/config.py
index 3fd20ab..b6fca7e 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -304,6 +304,12 @@
                                       title="Enabled Compute Service Features")
 
 ComputeFeaturesGroup = [
+    # NOTE(mriedem): This is a feature toggle for bug 1175464 which is fixed in
+    # mitaka and newton. This option can be removed after liberty-eol.
+    cfg.BoolOpt('allow_port_security_disabled',
+                default=False,
+                help='Does the test environment support creating ports in a '
+                     'network where port security is disabled?'),
     cfg.BoolOpt('disk_config',
                 default=True,
                 help="If false, skip disk config tests"),
@@ -333,6 +339,10 @@
     cfg.BoolOpt('suspend',
                 default=True,
                 help="Does the test environment support suspend/resume?"),
+    cfg.BoolOpt('cold_migration',
+                default=True,
+                help="Does the test environment support cold migration "
+                     "available?"),
     cfg.BoolOpt('live_migration',
                 default=True,
                 help="Does the test environment support live migration "
@@ -370,7 +380,8 @@
                 default=True,
                 help='Enables returning of the instance password by the '
                      'relevant server API calls such as create, rebuild '
-                     'or rescue.'),
+                     'or rescue. This configuration value should be same as '
+                     'nova.conf: DEFAULT.enable_instance_password'),
     cfg.BoolOpt('interface_attach',
                 default=True,
                 help='Does the test environment support dynamic network '
@@ -564,6 +575,9 @@
                 default=True,
                 help="Does the test environment support changing"
                      " port admin state"),
+    cfg.BoolOpt('port_security',
+                default=False,
+                help="Does the test environment support port security?"),
 ]
 
 validation_group = cfg.OptGroup(name='validation',
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index e2d6585..4123ae5 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -19,7 +19,7 @@
 
 
 PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron',
-                  'ironic', 'savanna', 'heat', 'sahara']
+                  'ironic', 'heat', 'sahara']
 
 PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
 TEST_DEFINITION = re.compile(r'^\s*def test.*')
diff --git a/tempest/lib/cmd/check_uuid.py b/tempest/lib/cmd/check_uuid.py
index be3aa49..1239ac5 100755
--- a/tempest/lib/cmd/check_uuid.py
+++ b/tempest/lib/cmd/check_uuid.py
@@ -69,7 +69,8 @@
         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):
+    @staticmethod
+    def _save_changes(filename, source):
         print('%s fixed' % filename)
         with open(filename, 'w') as f:
             f.write(source)
diff --git a/tempest/lib/common/utils/data_utils.py b/tempest/lib/common/utils/data_utils.py
index 6b6548e..4095c77 100644
--- a/tempest/lib/common/utils/data_utils.py
+++ b/tempest/lib/common/utils/data_utils.py
@@ -19,6 +19,7 @@
 import string
 import uuid
 
+from debtcollector import removals
 from oslo_utils import netutils
 import six.moves
 
@@ -153,7 +154,7 @@
 
     This generates a string with an arbitrary number of characters, generated
     by looping the base_text string. If the size is smaller than the size of
-    base_text, returning string is shrinked to the size.
+    base_text, returning string is shrunk to the size.
     :param int size: a returning characters size
     :param str base_text: a string you want to repeat
     :return: size string
@@ -171,10 +172,14 @@
     :return: size randomly bytes
     :rtype: string
     """
-    return ''.join([chr(random.randint(0, 255))
+    return b''.join([six.int2byte(random.randint(0, 255))
                     for i in range(size)])
 
 
+@removals.remove(
+    message="use get_ipv6_addr_by_EUI64 from oslo_utils.netutils",
+    version="Newton",
+    removal_version="Ocata")
 def get_ipv6_addr_by_EUI64(cidr, mac):
     """Generate a IPv6 addr by EUI-64 with CIDR and MAC
 
@@ -204,5 +209,5 @@
 # Courtesy of http://stackoverflow.com/a/312464
 def chunkify(sequence, chunksize):
     """Yield successive chunks from `sequence`."""
-    for i in six.moves.xrange(0, len(sequence), chunksize):
+    for i in range(0, len(sequence), chunksize):
         yield sequence[i:i + chunksize]
diff --git a/tempest/lib/services/compute/hosts_client.py b/tempest/lib/services/compute/hosts_client.py
index 16b5edd..1b93b00 100644
--- a/tempest/lib/services/compute/hosts_client.py
+++ b/tempest/lib/services/compute/hosts_client.py
@@ -45,8 +45,9 @@
     def update_host(self, hostname, **kwargs):
         """Update a host.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#enablehost
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#enablehost
         """
 
         request_body = {
diff --git a/tempest/lib/services/compute/images_client.py b/tempest/lib/services/compute/images_client.py
index 3dc3749..e937c13 100644
--- a/tempest/lib/services/compute/images_client.py
+++ b/tempest/lib/services/compute/images_client.py
@@ -27,8 +27,9 @@
     def create_image(self, server_id, **kwargs):
         """Create an image of the original server.
 
-        Available params: see http://developer.openstack.org/
-                          api-ref-compute-v2.1.html#createImage
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#createImage
         """
 
         post_body = {'createImage': kwargs}
@@ -41,8 +42,9 @@
     def list_images(self, detail=False, **params):
         """Return a list of all images filtered by any parameter.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#listImages
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#listImages
         """
         url = 'images'
         _schema = schema.list_images
@@ -81,8 +83,9 @@
     def set_image_metadata(self, image_id, meta):
         """Set the metadata for an image.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#createImageMetadata
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#createImageMetadata
         """
         post_body = json.dumps({'metadata': meta})
         resp, body = self.put('images/%s/metadata' % image_id, post_body)
@@ -93,8 +96,9 @@
     def update_image_metadata(self, image_id, meta):
         """Update the metadata for an image.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#updateImageMetadata
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#updateImageMetadata
         """
         post_body = json.dumps({'metadata': meta})
         resp, body = self.post('images/%s/metadata' % image_id, post_body)
@@ -112,8 +116,9 @@
     def set_image_metadata_item(self, image_id, key, meta):
         """Set the value for a specific image metadata key.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#setImageMetadataItem
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#setImageMetadataItem
         """
         post_body = json.dumps({'meta': meta})
         resp, body = self.put('images/%s/metadata/%s' % (image_id, key),
diff --git a/tempest/lib/services/compute/interfaces_client.py b/tempest/lib/services/compute/interfaces_client.py
index 80192a1..37157a4 100644
--- a/tempest/lib/services/compute/interfaces_client.py
+++ b/tempest/lib/services/compute/interfaces_client.py
@@ -31,8 +31,9 @@
     def create_interface(self, server_id, **kwargs):
         """Create an interface.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#createAttachInterface
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#createAttachInterface
         """
         post_body = {'interfaceAttachment': kwargs}
         post_body = json.dumps(post_body)
diff --git a/tempest/lib/services/compute/keypairs_client.py b/tempest/lib/services/compute/keypairs_client.py
index 2246739..c3f1781 100755
--- a/tempest/lib/services/compute/keypairs_client.py
+++ b/tempest/lib/services/compute/keypairs_client.py
@@ -30,8 +30,9 @@
     def list_keypairs(self, **params):
         """Lists keypairs that are associated with the account.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#listKeypairs
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#listKeypairs
         """
         url = 'os-keypairs'
         if params:
@@ -45,8 +46,9 @@
     def show_keypair(self, keypair_name, **params):
         """Shows details for a keypair that is associated with the account.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#showKeypair
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#showKeypair
         """
         url = "os-keypairs/%s" % keypair_name
         if params:
@@ -60,8 +62,9 @@
     def create_keypair(self, **kwargs):
         """Create a keypair.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#createKeypair
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#createKeypair
         """
         post_body = json.dumps({'keypair': kwargs})
         resp, body = self.post("os-keypairs", body=post_body)
@@ -73,8 +76,9 @@
     def delete_keypair(self, keypair_name, **params):
         """Deletes a keypair.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#deleteKeypair
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#deleteKeypair
         """
         url = "os-keypairs/%s" % keypair_name
         if params:
diff --git a/tempest/lib/services/compute/migrations_client.py b/tempest/lib/services/compute/migrations_client.py
index c3bdba7..375cbda 100644
--- a/tempest/lib/services/compute/migrations_client.py
+++ b/tempest/lib/services/compute/migrations_client.py
@@ -30,8 +30,9 @@
     def list_migrations(self, **params):
         """List all migrations.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#listMigrations
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#listMigrations
         """
 
         url = 'os-migrations'
diff --git a/tempest/lib/services/compute/quota_classes_client.py b/tempest/lib/services/compute/quota_classes_client.py
index 9dc04ad..523a306 100644
--- a/tempest/lib/services/compute/quota_classes_client.py
+++ b/tempest/lib/services/compute/quota_classes_client.py
@@ -35,8 +35,9 @@
     def update_quota_class_set(self, quota_class_id, **kwargs):
         """Update the quota class's limits for one or more resources.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#updatequota
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#updatequota
         """
         post_body = json.dumps({'quota_class_set': kwargs})
 
diff --git a/tempest/lib/services/compute/quotas_client.py b/tempest/lib/services/compute/quotas_client.py
index 6d41f4b..a2b0397 100644
--- a/tempest/lib/services/compute/quotas_client.py
+++ b/tempest/lib/services/compute/quotas_client.py
@@ -45,8 +45,9 @@
     def update_quota_set(self, tenant_id, user_id=None, **kwargs):
         """Updates the tenant's quota limits for one or more resources.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#updateQuota
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-compute-v2.1.html#updateQuota
         """
 
         post_body = json.dumps({'quota_set': kwargs})
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index 8b22be0..d5902e1 100755
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -47,8 +47,13 @@
     def create_server(self, **kwargs):
         """Create server.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#createServer
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/compute/#create-server
+
+        :param name: Server name
+        :param imageRef: Image reference (UUID)
+        :param flavorRef: Flavor reference (UUID or full URL)
 
         Most parameters except the following are passed to the API without
         any changes.
diff --git a/tempest/lib/services/identity/v2/__init__.py b/tempest/lib/services/identity/v2/__init__.py
index e69de29..b7d3c74 100644
--- a/tempest/lib/services/identity/v2/__init__.py
+++ b/tempest/lib/services/identity/v2/__init__.py
@@ -0,0 +1,24 @@
+# Copyright (c) 2016 Hewlett-Packard Enterprise 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 tempest.lib.services.identity.v2.endpoints_client import EndpointsClient
+from tempest.lib.services.identity.v2.identity_client import IdentityClient
+from tempest.lib.services.identity.v2.roles_client import RolesClient
+from tempest.lib.services.identity.v2.services_client import ServicesClient
+from tempest.lib.services.identity.v2.tenants_client import TenantsClient
+from tempest.lib.services.identity.v2.token_client import TokenClient
+from tempest.lib.services.identity.v2.users_client import UsersClient
+
+__all__ = ['EndpointsClient', 'IdentityClient', 'RolesClient',
+           'ServicesClient', 'TenantsClient', 'TokenClient', 'UsersClient']
diff --git a/tempest/lib/services/identity/v2/endpoints_client.py b/tempest/lib/services/identity/v2/endpoints_client.py
index f7b265d..770e8ae 100644
--- a/tempest/lib/services/identity/v2/endpoints_client.py
+++ b/tempest/lib/services/identity/v2/endpoints_client.py
@@ -23,8 +23,9 @@
     def create_endpoint(self, **kwargs):
         """Create an endpoint for service.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-identity-v2-ext.html#createEndpoint
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#createEndpoint
         """
 
         post_body = json.dumps({'endpoint': kwargs})
diff --git a/tempest/lib/services/identity/v2/roles_client.py b/tempest/lib/services/identity/v2/roles_client.py
index aaa75f1..635d013 100644
--- a/tempest/lib/services/identity/v2/roles_client.py
+++ b/tempest/lib/services/identity/v2/roles_client.py
@@ -22,8 +22,9 @@
     def create_role(self, **kwargs):
         """Create a role.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#createRole
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#createRole
         """
         post_body = json.dumps({'role': kwargs})
         resp, body = self.post('OS-KSADM/roles', post_body)
@@ -34,12 +35,11 @@
     def show_role(self, role_id_or_name):
         """Get a role by its id or name.
 
-        Available params: see
-            http://developer.openstack.org/
-            api-ref-identity-v2-ext.html#showRoleByID
-            OR
-            http://developer.openstack.org/
-            api-ref-identity-v2-ext.html#showRoleByName
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#showRoleByID
+        OR
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#showRoleByName
         """
         resp, body = self.get('OS-KSADM/roles/%s' % role_id_or_name)
         self.expected_success(200, resp.status)
@@ -49,8 +49,9 @@
     def list_roles(self, **params):
         """Returns roles.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#listRoles
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#listRoles
         """
         url = 'OS-KSADM/roles'
         if params:
@@ -63,8 +64,9 @@
     def delete_role(self, role_id):
         """Delete a role.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#deleteRole
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#deleteRole
         """
         resp, body = self.delete('OS-KSADM/roles/%s' % role_id)
         self.expected_success(204, resp.status)
@@ -73,9 +75,9 @@
     def create_user_role_on_project(self, tenant_id, user_id, role_id):
         """Add roles to a user on a tenant.
 
-        Available params: see
-            http://developer.openstack.org/
-            api-ref-identity-v2-ext.html#grantRoleToUserOnTenant
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#grantRoleToUserOnTenant
         """
         resp, body = self.put('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
                               (tenant_id, user_id, role_id), "")
@@ -97,9 +99,9 @@
     def delete_role_from_user_on_project(self, tenant_id, user_id, role_id):
         """Removes a role assignment for a user on a tenant.
 
-        Available params: see
-            http://developer.openstack.org/
-            api-ref-identity-v2-ext.html#revokeRoleFromUserOnTenant
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#revokeRoleFromUserOnTenant
         """
         resp, body = self.delete('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
                                  (tenant_id, user_id, role_id))
diff --git a/tempest/lib/services/identity/v2/services_client.py b/tempest/lib/services/identity/v2/services_client.py
index c26d419..b3f94aa 100755
--- a/tempest/lib/services/identity/v2/services_client.py
+++ b/tempest/lib/services/identity/v2/services_client.py
@@ -24,8 +24,9 @@
     def create_service(self, **kwargs):
         """Create a service.
 
-        Available params: see http://developer.openstack.org/api-ref/identity/
-                              v2-ext/?expanded=#create-service-admin-extension
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-ext/?expanded=#create-service-admin-extension
         """
         post_body = json.dumps({'OS-KSADM:service': kwargs})
         resp, body = self.post('/OS-KSADM/services', post_body)
@@ -44,8 +45,9 @@
     def list_services(self, **params):
         """List Service - Returns Services.
 
-        Available params: see http://developer.openstack.org/api-ref/identity/
-                              v2-ext/?expanded=#list-services-admin-extension
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-ext/?expanded=#list-services-admin-extension
         """
         url = '/OS-KSADM/services'
         if params:
diff --git a/tempest/lib/services/identity/v2/tenants_client.py b/tempest/lib/services/identity/v2/tenants_client.py
index f92c703..b687332 100644
--- a/tempest/lib/services/identity/v2/tenants_client.py
+++ b/tempest/lib/services/identity/v2/tenants_client.py
@@ -24,9 +24,9 @@
     def create_tenant(self, **kwargs):
         """Create a tenant
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v2-admin/index.html#
-                              create-tenant
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-admin/index.html#create-tenant
         """
         post_body = json.dumps({'tenant': kwargs})
         resp, body = self.post('tenants', post_body)
@@ -37,8 +37,9 @@
     def delete_tenant(self, tenant_id):
         """Delete a tenant.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#deleteTenant
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#deleteTenant
         """
         resp, body = self.delete('tenants/%s' % str(tenant_id))
         self.expected_success(204, resp.status)
@@ -47,9 +48,9 @@
     def show_tenant(self, tenant_id):
         """Get tenant details.
 
-        Available params: see
-            http://developer.openstack.org/
-            api-ref-identity-v2-ext.html#admin-showTenantById
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#admin-showTenantById
         """
         resp, body = self.get('tenants/%s' % str(tenant_id))
         self.expected_success(200, resp.status)
@@ -59,9 +60,9 @@
     def list_tenants(self, **params):
         """Returns tenants.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v2-admin/index.html#
-                              list-tenants-admin-endpoint
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-tenants-admin-endpoint
         """
         url = 'tenants'
         if params:
@@ -74,9 +75,9 @@
     def update_tenant(self, tenant_id, **kwargs):
         """Updates a tenant.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v2-admin/index.html#
-                              update-tenant
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-admin/index.html#update-tenant
         """
         if 'id' not in kwargs:
             kwargs['id'] = tenant_id
@@ -89,9 +90,9 @@
     def list_tenant_users(self, tenant_id, **params):
         """List users for a Tenant.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v2-admin/index.html#
-                              list-users-on-a-tenant
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-users-on-a-tenant
         """
         url = '/tenants/%s/users' % tenant_id
         if params:
diff --git a/tempest/lib/services/identity/v2/users_client.py b/tempest/lib/services/identity/v2/users_client.py
index 2a266d9..f20fdc4 100644
--- a/tempest/lib/services/identity/v2/users_client.py
+++ b/tempest/lib/services/identity/v2/users_client.py
@@ -22,9 +22,9 @@
     def create_user(self, **kwargs):
         """Create a user.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v2-admin/index.html#
-                              create-user-admin-endpoint
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-admin/index.html#create-user-admin-endpoint
         """
         post_body = json.dumps({'user': kwargs})
         resp, body = self.post('users', post_body)
@@ -35,9 +35,9 @@
     def update_user(self, user_id, **kwargs):
         """Updates a user.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v2-admin/index.html#
-                              update-user-admin-endpoint
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-admin/index.html#update-user-admin-endpoint
         """
         put_body = json.dumps({'user': kwargs})
         resp, body = self.put('users/%s' % user_id, put_body)
@@ -48,8 +48,9 @@
     def show_user(self, user_id):
         """GET a user.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-admin-v2.html#admin-showUser
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-admin-v2.html#admin-showUser
         """
         resp, body = self.get("users/%s" % user_id)
         self.expected_success(200, resp.status)
@@ -59,8 +60,9 @@
     def delete_user(self, user_id):
         """Delete a user.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-admin-v2.html#admin-deleteUser
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-admin-v2.html#admin-deleteUser
         """
         resp, body = self.delete("users/%s" % user_id)
         self.expected_success(204, resp.status)
@@ -69,9 +71,9 @@
     def list_users(self, **params):
         """Get the list of users.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v2-admin/index.html#
-                              list-users-admin-endpoint
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-users-admin-endpoint
         """
         url = "users"
         if params:
@@ -84,8 +86,9 @@
     def update_user_enabled(self, user_id, **kwargs):
         """Enables or disables a user.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#enableUser
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-identity-v2-ext.html#enableUser
         """
         # NOTE: The URL (users/<id>/enabled) is different from the api-site
         # one (users/<id>/OS-KSADM/enabled) , but they are the same API
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/lib/services/identity/v3/credentials_client.py
similarity index 71%
rename from tempest/services/identity/v3/json/credentials_client.py
rename to tempest/lib/services/identity/v3/credentials_client.py
index 55eeee4..6e5fd31 100644
--- a/tempest/services/identity/v3/json/credentials_client.py
+++ b/tempest/lib/services/identity/v3/credentials_client.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 """
-http://developer.openstack.org/api-ref-identity-v3.html#credentials
+http://developer.openstack.org/api-ref/identity/v3/index.html#credentials
 """
 
 from oslo_serialization import jsonutils as json
@@ -29,46 +29,47 @@
     def create_credential(self, **kwargs):
         """Creates a credential.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#create-credential
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#create-credential
         """
         post_body = json.dumps({'credential': kwargs})
         resp, body = self.post('credentials', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        body['credential']['blob'] = json.loads(body['credential']['blob'])
         return rest_client.ResponseBody(resp, body)
 
     def update_credential(self, credential_id, **kwargs):
         """Updates a credential.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#update-credential
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#update-credential
         """
         post_body = json.dumps({'credential': kwargs})
         resp, body = self.patch('credentials/%s' % credential_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        body['credential']['blob'] = json.loads(body['credential']['blob'])
         return rest_client.ResponseBody(resp, body)
 
     def show_credential(self, credential_id):
         """To GET Details of a credential.
 
-        For API details, see http://developer.openstack.org/
-                             api-ref-identity-v3.html#show-credential-details
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#show-credential-details
         """
         resp, body = self.get('credentials/%s' % credential_id)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        body['credential']['blob'] = json.loads(body['credential']['blob'])
         return rest_client.ResponseBody(resp, body)
 
     def list_credentials(self, **params):
         """Lists out all the available credentials.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v3/#list-credentials
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#list-credentials
         """
         url = 'credentials'
         if params:
@@ -81,8 +82,9 @@
     def delete_credential(self, credential_id):
         """Deletes a credential.
 
-        For API details, see http://developer.openstack.org/
-                             api-ref/identity/v3/#delete-credential
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#delete-credential
         """
         resp, body = self.delete('credentials/%s' % credential_id)
         self.expected_success(204, resp.status)
diff --git a/tempest/lib/services/identity/v3/endpoints_client.py b/tempest/lib/services/identity/v3/endpoints_client.py
index db30508..c4c0d8d 100644
--- a/tempest/lib/services/identity/v3/endpoints_client.py
+++ b/tempest/lib/services/identity/v3/endpoints_client.py
@@ -35,8 +35,9 @@
     def create_endpoint(self, **kwargs):
         """Create endpoint.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createEndpoint
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#create-endpoint
         """
         post_body = json.dumps({'endpoint': kwargs})
         resp, body = self.post('endpoints', post_body)
@@ -47,8 +48,9 @@
     def update_endpoint(self, endpoint_id, **kwargs):
         """Updates an endpoint with given parameters.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateEndpoint
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#update-endpoint
         """
         post_body = json.dumps({'endpoint': kwargs})
         resp, body = self.patch('endpoints/%s' % endpoint_id, post_body)
diff --git a/tempest/services/identity/v3/json/groups_client.py b/tempest/lib/services/identity/v3/groups_client.py
similarity index 83%
rename from tempest/services/identity/v3/json/groups_client.py
rename to tempest/lib/services/identity/v3/groups_client.py
index 3674496..5e68939 100644
--- a/tempest/services/identity/v3/json/groups_client.py
+++ b/tempest/lib/services/identity/v3/groups_client.py
@@ -29,8 +29,9 @@
     def create_group(self, **kwargs):
         """Creates a group.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createGroup
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#create-group
         """
         post_body = json.dumps({'group': kwargs})
         resp, body = self.post('groups', post_body)
@@ -48,8 +49,9 @@
     def list_groups(self, **params):
         """Lists the groups.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v3/#list-groups
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#list-groups
         """
         url = 'groups'
         if params:
@@ -62,8 +64,9 @@
     def update_group(self, group_id, **kwargs):
         """Updates a group.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateGroup
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#update-group
         """
         post_body = json.dumps({'group': kwargs})
         resp, body = self.patch('groups/%s' % group_id, post_body)
@@ -87,8 +90,9 @@
     def list_group_users(self, group_id, **params):
         """List users in group.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v3/#list-users-in-group
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#list-users-in-group
         """
         url = 'groups/%s/users' % group_id
         if params:
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/lib/services/identity/v3/identity_client.py
similarity index 100%
rename from tempest/services/identity/v3/json/identity_client.py
rename to tempest/lib/services/identity/v3/identity_client.py
diff --git a/tempest/lib/services/identity/v3/inherited_roles_client.py b/tempest/lib/services/identity/v3/inherited_roles_client.py
new file mode 100644
index 0000000..691c7fd
--- /dev/null
+++ b/tempest/lib/services/identity/v3/inherited_roles_client.py
@@ -0,0 +1,151 @@
+# Copyright 2016 Red Hat, 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.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
+
+
+class InheritedRolesClient(rest_client.RestClient):
+    api_version = "v3"
+
+    def create_inherited_role_on_domains_user(
+            self, domain_id, user_id, role_id):
+        """Assigns a role to a user on projects owned by a domain."""
+        resp, body = self.put(
+            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
+            % (domain_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_inherited_role_from_user_on_domain(
+            self, domain_id, user_id, role_id):
+        """Revokes an inherited project role from a user on a domain."""
+        resp, body = self.delete(
+            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
+            % (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_inherited_project_role_for_user_on_domain(
+            self, domain_id, user_id):
+        """Lists the inherited project roles on a domain for a user."""
+        resp, body = self.get(
+            "OS-INHERIT/domains/%s/users/%s/roles/inherited_to_projects"
+            % (domain_id, user_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def check_user_inherited_project_role_on_domain(
+            self, domain_id, user_id, role_id):
+        """Checks whether a user has an inherited project role on a domain."""
+        resp, body = self.head(
+            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
+            % (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
+
+    def create_inherited_role_on_domains_group(
+            self, domain_id, group_id, role_id):
+        """Assigns a role to a group on projects owned by a domain."""
+        resp, body = self.put(
+            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
+            % (domain_id, group_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_inherited_role_from_group_on_domain(
+            self, domain_id, group_id, role_id):
+        """Revokes an inherited project role from a group on a domain."""
+        resp, body = self.delete(
+            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
+            % (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_inherited_project_role_for_group_on_domain(
+            self, domain_id, group_id):
+        """Lists the inherited project roles on a domain for a group."""
+        resp, body = self.get(
+            "OS-INHERIT/domains/%s/groups/%s/roles/inherited_to_projects"
+            % (domain_id, group_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def check_group_inherited_project_role_on_domain(
+            self, domain_id, group_id, role_id):
+        """Checks whether a group has an inherited project role on a domain."""
+        resp, body = self.head(
+            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
+            % (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
+
+    def create_inherited_role_on_projects_user(
+            self, project_id, user_id, role_id):
+        """Assigns a role to a user on projects in a subtree."""
+        resp, body = self.put(
+            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
+            % (project_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_inherited_role_from_user_on_project(
+            self, project_id, user_id, role_id):
+        """Revokes an inherited role from a user on a project."""
+        resp, body = self.delete(
+            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
+            % (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def check_user_has_flag_on_inherited_to_project(
+            self, project_id, user_id, role_id):
+        """Checks whether a user has a role assignment"""
+        """with the inherited_to_projects flag on a project."""
+        resp, body = self.head(
+            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
+            % (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
+
+    def create_inherited_role_on_projects_group(
+            self, project_id, group_id, role_id):
+        """Assigns a role to a group on projects in a subtree."""
+        resp, body = self.put(
+            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
+            % (project_id, group_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_inherited_role_from_group_on_project(
+            self, project_id, group_id, role_id):
+        """Revokes an inherited role from a group on a project."""
+        resp, body = self.delete(
+            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
+            % (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def check_group_has_flag_on_inherited_to_project(
+            self, project_id, group_id, role_id):
+        """Checks whether a group has a role assignment"""
+        """with the inherited_to_projects flag on a project."""
+        resp, body = self.head(
+            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
+            % (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
diff --git a/tempest/lib/services/identity/v3/policies_client.py b/tempest/lib/services/identity/v3/policies_client.py
index f28db9a..0282745 100644
--- a/tempest/lib/services/identity/v3/policies_client.py
+++ b/tempest/lib/services/identity/v3/policies_client.py
@@ -28,8 +28,9 @@
     def create_policy(self, **kwargs):
         """Creates a Policy.
 
-        Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#createPolicy
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#create-policy
         """
         post_body = json.dumps({'policy': kwargs})
         resp, body = self.post('policies', post_body)
@@ -55,8 +56,9 @@
     def update_policy(self, policy_id, **kwargs):
         """Updates a policy.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updatePolicy
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#update-policy
         """
         post_body = json.dumps({'policy': kwargs})
         url = 'policies/%s' % policy_id
diff --git a/tempest/lib/services/identity/v3/projects_client.py b/tempest/lib/services/identity/v3/projects_client.py
index ce2f38d..20787da 100644
--- a/tempest/lib/services/identity/v3/projects_client.py
+++ b/tempest/lib/services/identity/v3/projects_client.py
@@ -25,8 +25,9 @@
     def create_project(self, name, **kwargs):
         """Create a Project.
 
-        Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#createProject
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#create-project
 
         """
         # Include the project name to the kwargs parameters
@@ -49,8 +50,9 @@
     def update_project(self, project_id, **kwargs):
         """Update a Project.
 
-        Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#updateProject
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#update-project
 
         """
         post_body = json.dumps({'project': kwargs})
diff --git a/tempest/lib/services/identity/v3/regions_client.py b/tempest/lib/services/identity/v3/regions_client.py
index 90dd9d7..33c754a 100644
--- a/tempest/lib/services/identity/v3/regions_client.py
+++ b/tempest/lib/services/identity/v3/regions_client.py
@@ -29,11 +29,9 @@
     def create_region(self, region_id=None, **kwargs):
         """Create region.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createRegion
-
-                          see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createRegionWithID
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#create-region
         """
         if region_id is not None:
             method = self.put
@@ -50,8 +48,9 @@
     def update_region(self, region_id, **kwargs):
         """Updates a region.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateRegion
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#update-region
         """
         post_body = json.dumps({'region': kwargs})
         resp, body = self.patch('regions/%s' % region_id, post_body)
diff --git a/tempest/lib/services/identity/v3/roles_client.py b/tempest/lib/services/identity/v3/roles_client.py
new file mode 100644
index 0000000..f1339dd
--- /dev/null
+++ b/tempest/lib/services/identity/v3/roles_client.py
@@ -0,0 +1,192 @@
+# Copyright 2016 Red Hat, 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.
+
+from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest.lib.common import rest_client
+
+
+class RolesClient(rest_client.RestClient):
+    api_version = "v3"
+
+    def create_role(self, **kwargs):
+        """Create a Role.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#create-role
+        """
+        post_body = json.dumps({'role': kwargs})
+        resp, body = self.post('roles', post_body)
+        self.expected_success(201, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_role(self, role_id):
+        """GET a Role."""
+        resp, body = self.get('roles/%s' % role_id)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_roles(self, **params):
+        """Get the list of Roles."""
+
+        url = 'roles'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_role(self, role_id, **kwargs):
+        """Update a Role.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#update-role
+        """
+        post_body = json.dumps({'role': kwargs})
+        resp, body = self.patch('roles/%s' % role_id, post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_role(self, role_id):
+        """Delete a role."""
+        resp, body = self.delete('roles/%s' % role_id)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_user_role_on_project(self, project_id, user_id, role_id):
+        """Add roles to a user on a project."""
+        resp, body = self.put('projects/%s/users/%s/roles/%s' %
+                              (project_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_user_role_on_domain(self, domain_id, user_id, role_id):
+        """Add roles to a user on a domain."""
+        resp, body = self.put('domains/%s/users/%s/roles/%s' %
+                              (domain_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_user_roles_on_project(self, project_id, user_id):
+        """list roles of a user on a project."""
+        resp, body = self.get('projects/%s/users/%s/roles' %
+                              (project_id, user_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_user_roles_on_domain(self, domain_id, user_id):
+        """list roles of a user on a domain."""
+        resp, body = self.get('domains/%s/users/%s/roles' %
+                              (domain_id, user_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_role_from_user_on_project(self, project_id, user_id, role_id):
+        """Delete role of a user on a project."""
+        resp, body = self.delete('projects/%s/users/%s/roles/%s' %
+                                 (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_role_from_user_on_domain(self, domain_id, user_id, role_id):
+        """Delete role of a user on a domain."""
+        resp, body = self.delete('domains/%s/users/%s/roles/%s' %
+                                 (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def check_user_role_existence_on_project(self, project_id,
+                                             user_id, role_id):
+        """Check role of a user on a project."""
+        resp, body = self.head('projects/%s/users/%s/roles/%s' %
+                               (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
+
+    def check_user_role_existence_on_domain(self, domain_id,
+                                            user_id, role_id):
+        """Check role of a user on a domain."""
+        resp, body = self.head('domains/%s/users/%s/roles/%s' %
+                               (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
+
+    def create_group_role_on_project(self, project_id, group_id, role_id):
+        """Add roles to a group on a project."""
+        resp, body = self.put('projects/%s/groups/%s/roles/%s' %
+                              (project_id, group_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_group_role_on_domain(self, domain_id, group_id, role_id):
+        """Add roles to a group on a domain."""
+        resp, body = self.put('domains/%s/groups/%s/roles/%s' %
+                              (domain_id, group_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_group_roles_on_project(self, project_id, group_id):
+        """list roles of a group on a project."""
+        resp, body = self.get('projects/%s/groups/%s/roles' %
+                              (project_id, group_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_group_roles_on_domain(self, domain_id, group_id):
+        """list roles of a group on a domain."""
+        resp, body = self.get('domains/%s/groups/%s/roles' %
+                              (domain_id, group_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_role_from_group_on_project(self, project_id, group_id, role_id):
+        """Delete role of a group on a project."""
+        resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
+                                 (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_role_from_group_on_domain(self, domain_id, group_id, role_id):
+        """Delete role of a group on a domain."""
+        resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
+                                 (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def check_role_from_group_on_project_existence(self, project_id,
+                                                   group_id, role_id):
+        """Check role of a group on a project."""
+        resp, body = self.head('projects/%s/groups/%s/roles/%s' %
+                               (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
+
+    def check_role_from_group_on_domain_existence(self, domain_id,
+                                                  group_id, role_id):
+        """Check role of a group on a domain."""
+        resp, body = self.head('domains/%s/groups/%s/roles/%s' %
+                               (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
diff --git a/tempest/lib/services/identity/v3/services_client.py b/tempest/lib/services/identity/v3/services_client.py
index 95caf7d..14c81cc 100644
--- a/tempest/lib/services/identity/v3/services_client.py
+++ b/tempest/lib/services/identity/v3/services_client.py
@@ -29,8 +29,9 @@
     def update_service(self, service_id, **kwargs):
         """Updates a service.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateService
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#update-service
         """
         patch_body = json.dumps({'service': kwargs})
         resp, body = self.patch('services/%s' % service_id, patch_body)
@@ -49,8 +50,9 @@
     def create_service(self, **kwargs):
         """Creates a service.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createService
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#create-service
         """
         body = json.dumps({'service': kwargs})
         resp, body = self.post("services", body)
@@ -67,8 +69,9 @@
     def list_services(self, **params):
         """List services.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v3/#list-services
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#list-services
         """
         url = 'services'
         if params:
diff --git a/tempest/services/identity/v3/json/trusts_client.py b/tempest/lib/services/identity/v3/trusts_client.py
similarity index 80%
rename from tempest/services/identity/v3/json/trusts_client.py
rename to tempest/lib/services/identity/v3/trusts_client.py
index dedee05..d113905 100644
--- a/tempest/services/identity/v3/json/trusts_client.py
+++ b/tempest/lib/services/identity/v3/trusts_client.py
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
 
 from tempest.lib.common import rest_client
 
@@ -23,8 +24,9 @@
     def create_trust(self, **kwargs):
         """Creates a trust.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3-ext.html#createTrust
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3-ext/index.html#create-trust
         """
         post_body = json.dumps({'trust': kwargs})
         resp, body = self.post('OS-TRUST/trusts', post_body)
@@ -38,16 +40,17 @@
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
-    def list_trusts(self, trustor_user_id=None, trustee_user_id=None):
-        """GET trusts."""
-        if trustor_user_id:
-            resp, body = self.get("OS-TRUST/trusts?trustor_user_id=%s"
-                                  % trustor_user_id)
-        elif trustee_user_id:
-            resp, body = self.get("OS-TRUST/trusts?trustee_user_id=%s"
-                                  % trustee_user_id)
-        else:
-            resp, body = self.get("OS-TRUST/trusts")
+    def list_trusts(self, **params):
+        """Returns trusts
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3-ext/index.html#list-trusts
+        """
+        url = "OS-TRUST/trusts/"
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/users_clients.py b/tempest/lib/services/identity/v3/users_client.py
similarity index 75%
rename from tempest/services/identity/v3/json/users_clients.py
rename to tempest/lib/services/identity/v3/users_client.py
index 0dcdacd..e99a971 100644
--- a/tempest/services/identity/v3/json/users_clients.py
+++ b/tempest/lib/services/identity/v3/users_client.py
@@ -24,8 +24,9 @@
     def create_user(self, **kwargs):
         """Creates a user.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v3/#create-user
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#create-user
         """
         post_body = json.dumps({'user': kwargs})
         resp, body = self.post('users', post_body)
@@ -36,8 +37,9 @@
     def update_user(self, user_id, **kwargs):
         """Updates a user.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateUser
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#update-user
         """
         if 'id' not in kwargs:
             kwargs['id'] = user_id
@@ -50,8 +52,9 @@
     def update_user_password(self, user_id, **kwargs):
         """Update a user password
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#changeUserPassword
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/index.html#change-password-for-user
         """
         update_user = json.dumps({'user': kwargs})
         resp, _ = self.post('users/%s/password' % user_id, update_user)
@@ -61,8 +64,9 @@
     def list_user_projects(self, user_id, **params):
         """Lists the projects on which a user has roles assigned.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v3/#list-projects-for-user
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#list-projects-for-user
         """
         url = 'users/%s/projects' % user_id
         if params:
@@ -75,8 +79,9 @@
     def list_users(self, **params):
         """Get the list of users.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/identity/v3/#list-users
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#list-users
         """
         url = 'users'
         if params:
@@ -102,8 +107,9 @@
     def list_user_groups(self, user_id, **params):
         """Lists groups which a user belongs to.
 
-        Available params: see http://developer.openstack.org/
-            api-ref/identity/v3/#list-groups-to-which-a-user-belongs
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/identity/v3/#list-groups-to-which-a-user-belongs
         """
         url = 'users/%s/groups' % user_id
         if params:
diff --git a/tempest/lib/services/image/v1/image_members_client.py b/tempest/lib/services/image/v1/image_members_client.py
index e7fa0c9..2318087 100644
--- a/tempest/lib/services/image/v1/image_members_client.py
+++ b/tempest/lib/services/image/v1/image_members_client.py
@@ -29,8 +29,9 @@
     def list_shared_images(self, tenant_id):
         """List image memberships for the given tenant.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v1.html#listSharedImages-v1
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v1/#list-shared-images
         """
 
         url = 'shared-images/%s' % tenant_id
@@ -42,8 +43,9 @@
     def create_image_member(self, image_id, member_id, **kwargs):
         """Add a member to an image.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v1.html#addMember-v1
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v1/#add-member-to-image
         """
         url = 'images/%s/members/%s' % (image_id, member_id)
         body = json.dumps({'member': kwargs})
@@ -54,8 +56,9 @@
     def delete_image_member(self, image_id, member_id):
         """Removes a membership from the image.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v1.html#removeMember-v1
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v1/#remove-member
         """
         url = 'images/%s/members/%s' % (image_id, member_id)
         resp, __ = self.delete(url)
diff --git a/tempest/lib/services/image/v1/images_client.py b/tempest/lib/services/image/v1/images_client.py
index 0db98f8..9737be3 100644
--- a/tempest/lib/services/image/v1/images_client.py
+++ b/tempest/lib/services/image/v1/images_client.py
@@ -61,8 +61,9 @@
     def create_image(self, data=None, headers=None):
         """Create an image.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v1.html#createImage-v1
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-image-v1.html#createImage-v1
         """
         if headers is None:
             headers = {}
@@ -78,8 +79,9 @@
     def update_image(self, image_id, data=None, headers=None):
         """Update an image.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v1.html#updateImage-v1
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-image-v1.html#updateImage-v1
         """
         if headers is None:
             headers = {}
@@ -102,8 +104,9 @@
     def list_images(self, detail=False, **kwargs):
         """Return a list of all images filtered by input parameters.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v1.html#listImage-v1
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v1/#list-images
 
         Most parameters except the following are passed to the API without
         any changes.
diff --git a/tempest/lib/services/image/v2/image_members_client.py b/tempest/lib/services/image/v2/image_members_client.py
index d0ab165..e5118a8 100644
--- a/tempest/lib/services/image/v2/image_members_client.py
+++ b/tempest/lib/services/image/v2/image_members_client.py
@@ -21,8 +21,9 @@
     def list_image_members(self, image_id):
         """List image members.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#listImageMembers-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#list-image-members
         """
         url = 'images/%s/members' % image_id
         resp, body = self.get(url)
@@ -33,8 +34,9 @@
     def create_image_member(self, image_id, **kwargs):
         """Create an image member.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#createImageMember-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#create-image-member
         """
         url = 'images/%s/members' % image_id
         data = json.dumps(kwargs)
@@ -46,8 +48,9 @@
     def update_image_member(self, image_id, member_id, **kwargs):
         """Update an image member.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#updateImageMember-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#update-image-member
         """
         url = 'images/%s/members/%s' % (image_id, member_id)
         data = json.dumps(kwargs)
@@ -59,8 +62,9 @@
     def show_image_member(self, image_id, member_id):
         """Show an image member.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#showImageMember-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#show-image-member-details
         """
         url = 'images/%s/members/%s' % (image_id, member_id)
         resp, body = self.get(url)
@@ -70,8 +74,9 @@
     def delete_image_member(self, image_id, member_id):
         """Delete an image member.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#deleteImageMember-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#delete-image-member
         """
         url = 'images/%s/members/%s' % (image_id, member_id)
         resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/images_client.py b/tempest/lib/services/image/v2/images_client.py
index 996ce94..bcdae44 100644
--- a/tempest/lib/services/image/v2/images_client.py
+++ b/tempest/lib/services/image/v2/images_client.py
@@ -30,8 +30,9 @@
     def update_image(self, image_id, patch):
         """Update an image.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#updateImage-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/index.html#update-an-image
         """
         data = json.dumps(patch)
         headers = {"Content-Type": "application/openstack-images-v2.0"
@@ -44,8 +45,9 @@
     def create_image(self, **kwargs):
         """Create an image.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#createImage-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/index.html#create-an-image
         """
         data = json.dumps(kwargs)
         resp, body = self.post('images', data)
@@ -56,9 +58,10 @@
     def deactivate_image(self, image_id):
         """Deactivate image.
 
-         Available params: see http://developer.openstack.org/
-                               api-ref-image-v2.html#deactivateImage-v2
-         """
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#deactivate-image
+        """
         url = 'images/%s/actions/deactivate' % image_id
         resp, body = self.post(url, None)
         self.expected_success(204, resp.status)
@@ -67,9 +70,10 @@
     def reactivate_image(self, image_id):
         """Reactivate image.
 
-         Available params: see http://developer.openstack.org/
-                               api-ref-image-v2.html#reactivateImage-v2
-         """
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#reactivate-image
+        """
         url = 'images/%s/actions/reactivate' % image_id
         resp, body = self.post(url, None)
         self.expected_success(204, resp.status)
@@ -78,8 +82,9 @@
     def delete_image(self, image_id):
         """Delete image.
 
-         Available params: see http://developer.openstack.org/
-                               api-ref-image-v2.html#deleteImage-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#delete-an-image
          """
         url = 'images/%s' % image_id
         resp, _ = self.delete(url)
@@ -89,8 +94,9 @@
     def list_images(self, params=None):
         """List images.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#listImages-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#show-images
         """
         url = 'images'
 
@@ -105,8 +111,9 @@
     def show_image(self, image_id):
         """Show image details.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#showImage-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#show-image-details
         """
         url = 'images/%s' % image_id
         resp, body = self.get(url)
@@ -129,8 +136,9 @@
     def store_image_file(self, image_id, data):
         """Upload binary image data.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#storeImageFile-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#upload-binary-image-data
         """
         url = 'images/%s/file' % image_id
 
@@ -147,8 +155,9 @@
     def show_image_file(self, image_id):
         """Download binary image data.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#showImageFile-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#download-binary-image-data
         """
         url = 'images/%s/file' % image_id
         resp, body = self.get(url)
@@ -158,8 +167,9 @@
     def add_image_tag(self, image_id, tag):
         """Add an image tag.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#addImageTag-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#add-image-tag
         """
         url = 'images/%s/tags/%s' % (image_id, tag)
         resp, body = self.put(url, body=None)
@@ -169,8 +179,9 @@
     def delete_image_tag(self, image_id, tag):
         """Delete an image tag.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#deleteImageTag-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/#delete-image-tag
         """
         url = 'images/%s/tags/%s' % (image_id, tag)
         resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/namespaces_client.py b/tempest/lib/services/image/v2/namespaces_client.py
index 5bd096d..c92ff3a 100644
--- a/tempest/lib/services/image/v2/namespaces_client.py
+++ b/tempest/lib/services/image/v2/namespaces_client.py
@@ -24,8 +24,9 @@
     def create_namespace(self, **kwargs):
         """Create a namespace.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#createNamespace-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-namespace
         """
         data = json.dumps(kwargs)
         resp, body = self.post('metadefs/namespaces', data)
@@ -34,6 +35,12 @@
         return rest_client.ResponseBody(resp, body)
 
     def show_namespace(self, namespace):
+        """Show namespace details.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#get-namespace-details
+        """
         url = 'metadefs/namespaces/%s' % namespace
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
@@ -43,8 +50,9 @@
     def update_namespace(self, namespace, **kwargs):
         """Update a namespace.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#updateNamespace-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#update-namespace
         """
         # NOTE: On Glance API, we need to pass namespace on both URI
         # and a request body.
@@ -60,8 +68,9 @@
     def delete_namespace(self, namespace):
         """Delete a namespace.
 
-        Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#deleteNamespace-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-namespace
         """
         url = 'metadefs/namespaces/%s' % namespace
         resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/resource_types_client.py b/tempest/lib/services/image/v2/resource_types_client.py
index 8f2a977..1b6889f 100644
--- a/tempest/lib/services/image/v2/resource_types_client.py
+++ b/tempest/lib/services/image/v2/resource_types_client.py
@@ -24,10 +24,10 @@
     def list_resource_types(self):
         """Lists all resource types.
 
-         Available params: see http://developer.openstack.org/
-                               api-ref/image/v2/metadefs-index.html?expanded=#
-                               list-resource-types
-         """
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/metadefs-index.html?expanded=#list-resource-types
+        """
         url = 'metadefs/resource_types'
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
@@ -37,10 +37,10 @@
     def create_resource_type_association(self, namespace_id, **kwargs):
         """Creates a resource type association in given namespace.
 
-         Available params: see http://developer.openstack.org/
-                               api-ref/image/v2/metadefs-index.html?expanded=#
-                               create-resource-type-association
-         """
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/metadefs-index.html?expanded=#create-resource-type-association
+        """
         url = 'metadefs/namespaces/%s/resource_types' % namespace_id
         data = json.dumps(kwargs)
         resp, body = self.post(url, data)
@@ -51,10 +51,10 @@
     def list_resource_type_association(self, namespace_id):
         """Lists resource type associations in given namespace.
 
-         Available params: see http://developer.openstack.org/
-                               api-ref/image/v2/metadefs-index.html?expanded=#
-                               list-resource-type-associations
-         """
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/metadefs-index.html?expanded=#list-resource-type-associations
+        """
         url = 'metadefs/namespaces/%s/resource_types' % namespace_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
@@ -64,10 +64,10 @@
     def delete_resource_type_association(self, namespace_id, resource_name):
         """Removes resource type association in given namespace.
 
-         Available params: see http://developer.openstack.org/
-                               api-ref/image/v2/metadefs-index.html?expanded=#
-                               remove-resource-type-association
-         """
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/image/v2/metadefs-index.html?expanded=#remove-resource-type-association
+        """
         url = 'metadefs/namespaces/%s/resource_types/%s' % (namespace_id,
                                                             resource_name)
         resp, _ = self.delete(url)
diff --git a/tempest/lib/services/network/floating_ips_client.py b/tempest/lib/services/network/floating_ips_client.py
index f6cc0ff..2bb18e0 100755
--- a/tempest/lib/services/network/floating_ips_client.py
+++ b/tempest/lib/services/network/floating_ips_client.py
@@ -21,8 +21,9 @@
         If you specify port information, associates the floating IP with an
         internal port.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#createFloatingIp
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-floating-ip
         """
         uri = '/floatingips'
         post_data = {'floatingip': kwargs}
@@ -31,8 +32,9 @@
     def update_floatingip(self, floatingip_id, **kwargs):
         """Updates a floating IP and its association with an internal port.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#updateFloatingIp
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#update-floating-ip
         """
         uri = '/floatingips/%s' % floatingip_id
         post_data = {'floatingip': kwargs}
@@ -41,8 +43,9 @@
     def show_floatingip(self, floatingip_id, **fields):
         """Shows details for a floating IP.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showFloatingIp
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-floating-ip-details
         """
         uri = '/floatingips/%s' % floatingip_id
         return self.show_resource(uri, **fields)
@@ -54,8 +57,9 @@
     def list_floatingips(self, **filters):
         """Lists floating IPs.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listFloatingIps
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-floating-ips
         """
         uri = '/floatingips'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/metering_labels_client.py b/tempest/lib/services/network/metering_labels_client.py
index 12a5834..411da1f 100755
--- a/tempest/lib/services/network/metering_labels_client.py
+++ b/tempest/lib/services/network/metering_labels_client.py
@@ -18,9 +18,9 @@
     def create_metering_label(self, **kwargs):
         """Creates an L3 metering label.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              createMeteringLabel
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-metering-label
         """
         uri = '/metering/metering-labels'
         post_data = {'metering_label': kwargs}
@@ -29,8 +29,9 @@
     def show_metering_label(self, metering_label_id, **fields):
         """Shows details for a metering label.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showMeteringLabel
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-metering-label-details
         """
         uri = '/metering/metering-labels/%s' % metering_label_id
         return self.show_resource(uri, **fields)
@@ -38,9 +39,9 @@
     def delete_metering_label(self, metering_label_id):
         """Deletes an L3 metering label.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              deleteMeteringLabel
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#delete-metering-label
         """
         uri = '/metering/metering-labels/%s' % metering_label_id
         return self.delete_resource(uri)
@@ -48,9 +49,9 @@
     def list_metering_labels(self, **filters):
         """Lists all L3 metering labels that belong to the tenant.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              listMeteringLabels
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-metering-labels
         """
         uri = '/metering/metering-labels'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/networks_client.py b/tempest/lib/services/network/networks_client.py
index 6b601ee..77d4823 100755
--- a/tempest/lib/services/network/networks_client.py
+++ b/tempest/lib/services/network/networks_client.py
@@ -18,8 +18,9 @@
     def create_network(self, **kwargs):
         """Creates a network.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/networking/v2/index.html#create-network
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-network
         """
         uri = '/networks'
         post_data = {'network': kwargs}
@@ -28,8 +29,9 @@
     def update_network(self, network_id, **kwargs):
         """Updates a network.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/networking/v2/index.html#update-network
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#update-network
         """
         uri = '/networks/%s' % network_id
         post_data = {'network': kwargs}
@@ -38,8 +40,9 @@
     def show_network(self, network_id, **fields):
         """Shows details for a network.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/networking/v2/index.html#show-network-details
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-network-details
         """
         uri = '/networks/%s' % network_id
         return self.show_resource(uri, **fields)
@@ -51,8 +54,9 @@
     def list_networks(self, **filters):
         """Lists networks to which the tenant has access.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/networking/v2/index.html#list-networks
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-networks
         """
         uri = '/networks'
         return self.list_resources(uri, **filters)
@@ -60,8 +64,9 @@
     def create_bulk_networks(self, **kwargs):
         """Create multiple networks in a single request.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref/networking/v2/index.html#bulk-create-networks
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#bulk-create-networks
         """
         uri = '/networks'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/ports_client.py b/tempest/lib/services/network/ports_client.py
index 71f1103..93138b9 100755
--- a/tempest/lib/services/network/ports_client.py
+++ b/tempest/lib/services/network/ports_client.py
@@ -19,8 +19,9 @@
     def create_port(self, **kwargs):
         """Creates a port on a network.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#createPort
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-port
         """
         uri = '/ports'
         post_data = {'port': kwargs}
@@ -29,8 +30,9 @@
     def update_port(self, port_id, **kwargs):
         """Updates a port.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#updatePort
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#update-port
         """
         uri = '/ports/%s' % port_id
         post_data = {'port': kwargs}
@@ -39,8 +41,9 @@
     def show_port(self, port_id, **fields):
         """Shows details for a port.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#showPort
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-port-details
         """
         uri = '/ports/%s' % port_id
         return self.show_resource(uri, **fields)
@@ -48,8 +51,9 @@
     def delete_port(self, port_id):
         """Deletes a port.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#removePort
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#delete-port
         """
         uri = '/ports/%s' % port_id
         return self.delete_resource(uri)
@@ -57,8 +61,9 @@
     def list_ports(self, **filters):
         """Lists ports to which the tenant has access.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#listPorts
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-ports
         """
         uri = '/ports'
         return self.list_resources(uri, **filters)
@@ -66,8 +71,9 @@
     def create_bulk_ports(self, **kwargs):
         """Create multiple ports in a single request.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#bulkCreatePorts
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html?expanded=#bulk-create-ports
         """
         uri = '/ports'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/routers_client.py b/tempest/lib/services/network/routers_client.py
index 23e9c4e..19b7627 100755
--- a/tempest/lib/services/network/routers_client.py
+++ b/tempest/lib/services/network/routers_client.py
@@ -18,8 +18,9 @@
     def create_router(self, **kwargs):
         """Create a router.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#createRouter
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-router
         """
         post_body = {'router': kwargs}
         uri = '/routers'
@@ -28,8 +29,9 @@
     def update_router(self, router_id, **kwargs):
         """Updates a logical router.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#updateRouter
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#update-router
         """
         uri = '/routers/%s' % router_id
         update_body = {'router': kwargs}
@@ -38,8 +40,9 @@
     def show_router(self, router_id, **fields):
         """Shows details for a router.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showRouter
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-router-details
         """
         uri = '/routers/%s' % router_id
         return self.show_resource(uri, **fields)
@@ -51,8 +54,9 @@
     def list_routers(self, **filters):
         """Lists logical routers.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listRouters
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-routers
         """
         uri = '/routers'
         return self.list_resources(uri, **filters)
@@ -60,9 +64,9 @@
     def add_router_interface(self, router_id, **kwargs):
         """Add router interface.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              addRouterInterface
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#add-interface-to-router
         """
         uri = '/routers/%s/add_router_interface' % router_id
         return self.update_resource(uri, kwargs)
@@ -70,9 +74,9 @@
     def remove_router_interface(self, router_id, **kwargs):
         """Remove router interface.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              deleteRouterInterface
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#remove-interface-from-router
         """
         uri = '/routers/%s/remove_router_interface' % router_id
         return self.update_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/security_group_rules_client.py b/tempest/lib/services/network/security_group_rules_client.py
index 6cd01e1..d2bc4a9 100755
--- a/tempest/lib/services/network/security_group_rules_client.py
+++ b/tempest/lib/services/network/security_group_rules_client.py
@@ -18,9 +18,9 @@
     def create_security_group_rule(self, **kwargs):
         """Creates an OpenStack Networking security group rule.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              createSecGroupRule
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-security-group-rule
         """
         uri = '/security-group-rules'
         post_data = {'security_group_rule': kwargs}
@@ -29,8 +29,9 @@
     def show_security_group_rule(self, security_group_rule_id, **fields):
         """Shows detailed information for a security group rule.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showSecGroupRule
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-security-group-rule
         """
         uri = '/security-group-rules/%s' % security_group_rule_id
         return self.show_resource(uri, **fields)
@@ -42,8 +43,9 @@
     def list_security_group_rules(self, **filters):
         """Lists a summary of all OpenStack Networking security group rules.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listSecGroupRules
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-security-group-rules
         """
         uri = '/security-group-rules'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/security_groups_client.py b/tempest/lib/services/network/security_groups_client.py
index 5c89a6f..1f30216 100755
--- a/tempest/lib/services/network/security_groups_client.py
+++ b/tempest/lib/services/network/security_groups_client.py
@@ -18,8 +18,9 @@
     def create_security_group(self, **kwargs):
         """Creates an OpenStack Networking security group.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#createSecGroup
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-security-group
         """
         uri = '/security-groups'
         post_data = {'security_group': kwargs}
@@ -28,8 +29,9 @@
     def update_security_group(self, security_group_id, **kwargs):
         """Updates a security group.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#updateSecGroup
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#update-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         post_data = {'security_group': kwargs}
@@ -38,8 +40,9 @@
     def show_security_group(self, security_group_id, **fields):
         """Shows details for a security group.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showSecGroup
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         return self.show_resource(uri, **fields)
@@ -47,8 +50,9 @@
     def delete_security_group(self, security_group_id):
         """Deletes an OpenStack Networking security group.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#deleteSecGroup
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#delete-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         return self.delete_resource(uri)
@@ -56,8 +60,9 @@
     def list_security_groups(self, **filters):
         """Lists OpenStack Networking security groups.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listSecGroups
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-security-groups
         """
         uri = '/security-groups'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/subnetpools_client.py b/tempest/lib/services/network/subnetpools_client.py
index f0a66a0..7e77e30 100755
--- a/tempest/lib/services/network/subnetpools_client.py
+++ b/tempest/lib/services/network/subnetpools_client.py
@@ -20,8 +20,9 @@
     def list_subnetpools(self, **filters):
         """Lists subnet pools to which the tenant has access.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listSubnetPools
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-subnet-pools
         """
         uri = '/subnetpools'
         return self.list_resources(uri, **filters)
@@ -29,8 +30,9 @@
     def create_subnetpool(self, **kwargs):
         """Creates a subnet pool.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#createSubnetPool
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-subnet-pool
         """
         uri = '/subnetpools'
         post_data = {'subnetpool': kwargs}
@@ -39,8 +41,9 @@
     def show_subnetpool(self, subnetpool_id, **fields):
         """Shows information for a subnet pool.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showSubnetPool
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-subnet-pool
         """
         uri = '/subnetpools/%s' % subnetpool_id
         return self.show_resource(uri, **fields)
@@ -48,8 +51,9 @@
     def update_subnetpool(self, subnetpool_id, **kwargs):
         """Updates a subnet pool.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#updateSubnetPool
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#update-subnet-pool
         """
         uri = '/subnetpools/%s' % subnetpool_id
         post_data = {'subnetpool': kwargs}
diff --git a/tempest/lib/services/network/subnets_client.py b/tempest/lib/services/network/subnets_client.py
index 0fde3ee..b843f84 100755
--- a/tempest/lib/services/network/subnets_client.py
+++ b/tempest/lib/services/network/subnets_client.py
@@ -18,8 +18,9 @@
     def create_subnet(self, **kwargs):
         """Creates a subnet on a network.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#createSubnet
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#create-subnet
         """
         uri = '/subnets'
         post_data = {'subnet': kwargs}
@@ -28,8 +29,9 @@
     def update_subnet(self, subnet_id, **kwargs):
         """Updates a subnet.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#updateSubnet
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#update-subnet
         """
         uri = '/subnets/%s' % subnet_id
         post_data = {'subnet': kwargs}
@@ -38,8 +40,9 @@
     def show_subnet(self, subnet_id, **fields):
         """Shows details for a subnet.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#showSubnet
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#show-subnet-details
         """
         uri = '/subnets/%s' % subnet_id
         return self.show_resource(uri, **fields)
@@ -51,8 +54,9 @@
     def list_subnets(self, **filters):
         """Lists subnets to which the tenant has access.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#listSubnets
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#list-subnets
         """
         uri = '/subnets'
         return self.list_resources(uri, **filters)
@@ -60,8 +64,9 @@
     def create_bulk_subnets(self, **kwargs):
         """Create multiple subnets in a single request.
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#bulkCreateSubnet
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref/networking/v2/index.html#bulk-create-subnet
         """
         uri = '/subnets'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/services/volume/v1/json/encryption_types_client.py b/tempest/lib/services/volume/v1/encryption_types_client.py
similarity index 100%
rename from tempest/services/volume/v1/json/encryption_types_client.py
rename to tempest/lib/services/volume/v1/encryption_types_client.py
diff --git a/tempest/services/volume/base/base_qos_client.py b/tempest/lib/services/volume/v1/qos_client.py
similarity index 96%
copy from tempest/services/volume/base/base_qos_client.py
copy to tempest/lib/services/volume/v1/qos_client.py
index 0ce76a7..65ae274 100644
--- a/tempest/services/volume/base/base_qos_client.py
+++ b/tempest/lib/services/volume/v1/qos_client.py
@@ -18,8 +18,13 @@
 from tempest.lib import exceptions as lib_exc
 
 
-class BaseQosSpecsClient(rest_client.RestClient):
-    """Client class to send CRUD QoS API requests"""
+class QosSpecsClient(rest_client.RestClient):
+    """Volume V1 QoS client.
+
+       Client class to send CRUD QoS API requests
+    """
+
+    api_version = "v1"
 
     def is_resource_deleted(self, qos_id):
         try:
diff --git a/tempest/lib/services/volume/v1/quotas_client.py b/tempest/lib/services/volume/v1/quotas_client.py
index 8924b42..678fd82 100644
--- a/tempest/lib/services/volume/v1/quotas_client.py
+++ b/tempest/lib/services/volume/v1/quotas_client.py
@@ -45,8 +45,9 @@
     def update_quota_set(self, tenant_id, **kwargs):
         """Updates quota set
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v1.html#updateQuota
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-blockstorage-v1.html#updateQuota
         """
         put_body = jsonutils.dumps({'quota_set': kwargs})
         resp, body = self.put('os-quota-sets/%s' % tenant_id, put_body)
diff --git a/tempest/services/volume/base/base_snapshots_client.py b/tempest/lib/services/volume/v1/snapshots_client.py
old mode 100755
new mode 100644
similarity index 91%
copy from tempest/services/volume/base/base_snapshots_client.py
copy to tempest/lib/services/volume/v1/snapshots_client.py
index 38a6dc7..1881078
--- a/tempest/services/volume/base/base_snapshots_client.py
+++ b/tempest/lib/services/volume/v1/snapshots_client.py
@@ -17,8 +17,8 @@
 from tempest.lib import exceptions as lib_exc
 
 
-class BaseSnapshotsClient(rest_client.RestClient):
-    """Base Client class to send CRUD Volume API requests."""
+class SnapshotsClient(rest_client.RestClient):
+    """Client class to send CRUD Volume V1 API requests."""
 
     create_resp = 200
 
@@ -26,7 +26,7 @@
         """List all the snapshot.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#listSnapshots
+                              api-ref-blockstorage-v1.html#listSnapshots
         """
         url = 'snapshots'
         if detail:
@@ -43,7 +43,7 @@
         """Returns the details of a single snapshot.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#showSnapshot
+                              api-ref-blockstorage-v1.html#showSnapshot
         """
         url = "snapshots/%s" % snapshot_id
         resp, body = self.get(url)
@@ -55,7 +55,7 @@
         """Creates a new snapshot.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#createSnapshot
+                              api-ref-blockstorage-v1.html#createSnapshot
         """
         post_body = json.dumps({'snapshot': kwargs})
         resp, body = self.post('snapshots', post_body)
@@ -63,23 +63,11 @@
         self.expected_success(self.create_resp, resp.status)
         return rest_client.ResponseBody(resp, body)
 
-    def update_snapshot(self, snapshot_id, **kwargs):
-        """Updates a snapshot.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#updateSnapshot
-        """
-        put_body = json.dumps({'snapshot': kwargs})
-        resp, body = self.put('snapshots/%s' % snapshot_id, put_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
     def delete_snapshot(self, snapshot_id):
         """Delete Snapshot.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#deleteSnapshot
+                              api-ref-blockstorage-v1.html#deleteSnapshot
         """
         resp, body = self.delete("snapshots/%s" % snapshot_id)
         self.expected_success(202, resp.status)
@@ -126,11 +114,24 @@
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, body)
 
+    def update_snapshot(self, snapshot_id, **kwargs):
+        """Updates a snapshot.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#
+                              updateSnapshotMetadata
+        """
+        put_body = json.dumps({'snapshot': kwargs})
+        resp, body = self.put('snapshots/%s' % snapshot_id, put_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
     def show_snapshot_metadata(self, snapshot_id):
         """Get metadata of the snapshot.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#
+                              api-ref-blockstorage-v1.html#
                               showSnapshotMetadata
         """
         url = "snapshots/%s/metadata" % snapshot_id
@@ -143,7 +144,7 @@
         """Update metadata for the snapshot.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#
+                              api-ref-blockstorage-v1.html#
                               updateSnapshotMetadata
         """
         put_body = json.dumps(kwargs)
diff --git a/tempest/services/volume/base/admin/base_types_client.py b/tempest/lib/services/volume/v1/types_client.py
old mode 100755
new mode 100644
similarity index 94%
rename from tempest/services/volume/base/admin/base_types_client.py
rename to tempest/lib/services/volume/v1/types_client.py
index fe70c1a..dce728d
--- a/tempest/services/volume/base/admin/base_types_client.py
+++ b/tempest/lib/services/volume/v1/types_client.py
@@ -20,7 +20,7 @@
 from tempest.lib import exceptions as lib_exc
 
 
-class BaseTypesClient(rest_client.RestClient):
+class TypesClient(rest_client.RestClient):
     """Client class to send CRUD Volume Types API requests"""
 
     def is_resource_deleted(self, id):
@@ -39,7 +39,7 @@
         """List all the volume_types created.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#showVolumeTypes
+                              api-ref-blockstorage-v1.html#listVolumeTypes
         """
         url = 'types'
         if params:
@@ -54,7 +54,7 @@
         """Returns the details of a single volume_type.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#showVolumeType
+                              api-ref-blockstorage-v1.html#showVolumeType
         """
         url = "types/%s" % volume_type_id
         resp, body = self.get(url)
@@ -66,7 +66,7 @@
         """Create volume type.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#createVolumeType
+                              api-ref-blockstorage-v1.html#createVolumeType
         """
         post_body = json.dumps({'volume_type': kwargs})
         resp, body = self.post('types', post_body)
@@ -78,7 +78,7 @@
         """Deletes the Specified Volume_type.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#deleteVolumeType
+                              api-ref-blockstorage-v1.html#deleteVolumeType
         """
         resp, body = self.delete("types/%s" % volume_type_id)
         self.expected_success(202, resp.status)
diff --git a/tempest/services/volume/v2/json/encryption_types_client.py b/tempest/lib/services/volume/v2/encryption_types_client.py
similarity index 100%
rename from tempest/services/volume/v2/json/encryption_types_client.py
rename to tempest/lib/services/volume/v2/encryption_types_client.py
diff --git a/tempest/services/volume/base/base_qos_client.py b/tempest/lib/services/volume/v2/qos_client.py
similarity index 96%
rename from tempest/services/volume/base/base_qos_client.py
rename to tempest/lib/services/volume/v2/qos_client.py
index 0ce76a7..5fac00f 100644
--- a/tempest/services/volume/base/base_qos_client.py
+++ b/tempest/lib/services/volume/v2/qos_client.py
@@ -18,8 +18,13 @@
 from tempest.lib import exceptions as lib_exc
 
 
-class BaseQosSpecsClient(rest_client.RestClient):
-    """Client class to send CRUD QoS API requests"""
+class QosSpecsClient(rest_client.RestClient):
+    """Volume V2 QoS client.
+
+       Client class to send CRUD QoS API requests
+    """
+
+    api_version = "v2"
 
     def is_resource_deleted(self, qos_id):
         try:
diff --git a/tempest/lib/services/volume/v2/quotas_client.py b/tempest/lib/services/volume/v2/quotas_client.py
index a302045..430957d 100644
--- a/tempest/lib/services/volume/v2/quotas_client.py
+++ b/tempest/lib/services/volume/v2/quotas_client.py
@@ -47,8 +47,9 @@
     def update_quota_set(self, tenant_id, **kwargs):
         """Updates quota set
 
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#updateQuotas-v2
+        For a full list of available parameters, please refer to the official
+        API reference:
+        http://developer.openstack.org/api-ref-blockstorage-v2.html#updateQuota
         """
         put_body = jsonutils.dumps({'quota_set': kwargs})
         resp, body = self.put('os-quota-sets/%s' % tenant_id, put_body)
diff --git a/tempest/services/volume/base/base_snapshots_client.py b/tempest/lib/services/volume/v2/snapshots_client.py
old mode 100755
new mode 100644
similarity index 97%
rename from tempest/services/volume/base/base_snapshots_client.py
rename to tempest/lib/services/volume/v2/snapshots_client.py
index 38a6dc7..c84e557
--- a/tempest/services/volume/base/base_snapshots_client.py
+++ b/tempest/lib/services/volume/v2/snapshots_client.py
@@ -17,10 +17,10 @@
 from tempest.lib import exceptions as lib_exc
 
 
-class BaseSnapshotsClient(rest_client.RestClient):
-    """Base Client class to send CRUD Volume API requests."""
-
-    create_resp = 200
+class SnapshotsClient(rest_client.RestClient):
+    """Client class to send CRUD Volume V2 API requests."""
+    api_version = "v2"
+    create_resp = 202
 
     def list_snapshots(self, detail=False, **params):
         """List all the snapshot.
diff --git a/tempest/services/volume/base/admin/base_types_client.py b/tempest/lib/services/volume/v2/types_client.py
old mode 100755
new mode 100644
similarity index 77%
copy from tempest/services/volume/base/admin/base_types_client.py
copy to tempest/lib/services/volume/v2/types_client.py
index fe70c1a..d399e99
--- a/tempest/services/volume/base/admin/base_types_client.py
+++ b/tempest/lib/services/volume/v2/types_client.py
@@ -20,8 +20,9 @@
 from tempest.lib import exceptions as lib_exc
 
 
-class BaseTypesClient(rest_client.RestClient):
-    """Client class to send CRUD Volume Types API requests"""
+class TypesClient(rest_client.RestClient):
+    """Client class to send CRUD Volume V2 API requests"""
+    api_version = "v2"
 
     def is_resource_deleted(self, id):
         try:
@@ -158,3 +159,42 @@
         body = json.loads(body)
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, body)
+
+    def add_type_access(self, volume_type_id, **kwargs):
+        """Adds volume type access for the given project.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html
+                              #createVolumeTypeAccessExt
+        """
+        post_body = json.dumps({'addProjectAccess': kwargs})
+        url = 'types/%s/action' % volume_type_id
+        resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def remove_type_access(self, volume_type_id, **kwargs):
+        """Removes volume type access for the given project.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html
+                              #removeVolumeTypeAccessExt
+        """
+        post_body = json.dumps({'removeProjectAccess': kwargs})
+        url = 'types/%s/action' % volume_type_id
+        resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_type_access(self, volume_type_id):
+        """Print access information about the given volume type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#
+                              listVolumeTypeAccessExt
+        """
+        url = 'types/%s/os-volume-type-access' % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 233d747..4baf420 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -658,7 +658,8 @@
 
     def _create_network(self, networks_client=None,
                         routers_client=None, tenant_id=None,
-                        namestart='network-smoke-'):
+                        namestart='network-smoke-',
+                        port_security_enabled=True):
         if not networks_client:
             networks_client = self.networks_client
         if not routers_client:
@@ -666,7 +667,12 @@
         if not tenant_id:
             tenant_id = networks_client.tenant_id
         name = data_utils.rand_name(namestart)
-        result = networks_client.create_network(name=name, tenant_id=tenant_id)
+        network_kwargs = dict(name=name, tenant_id=tenant_id)
+        # Neutron disables port security by default so we have to check the
+        # config before trying to create the network with port_security_enabled
+        if CONF.network_feature_enabled.port_security:
+            network_kwargs['port_security_enabled'] = port_security_enabled
+        result = networks_client.create_network(**network_kwargs)
         network = result['network']
 
         self.assertEqual(network['name'], name)
@@ -977,7 +983,7 @@
     def _default_security_group(self, client=None, tenant_id=None):
         """Get default secgroup for given tenant_id.
 
-        :returns: DeletableSecurityGroup -- default secgroup for given tenant
+        :returns: default secgroup for given tenant
         """
         if client is None:
             client = self.security_groups_client
@@ -1141,7 +1147,8 @@
 
     def create_networks(self, networks_client=None,
                         routers_client=None, subnets_client=None,
-                        tenant_id=None, dns_nameservers=None):
+                        tenant_id=None, dns_nameservers=None,
+                        port_security_enabled=True):
         """Create a network with a subnet connected to a router.
 
         The baremetal driver is a special case since all nodes are
@@ -1167,7 +1174,8 @@
         else:
             network = self._create_network(
                 networks_client=networks_client,
-                tenant_id=tenant_id)
+                tenant_id=tenant_id,
+                port_security_enabled=port_security_enabled)
             router = self._get_router(client=routers_client,
                                       tenant_id=tenant_id)
             subnet_kwargs = dict(network=network,
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 086b82d..43adfb1 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -36,7 +36,6 @@
         super(TestAggregatesBasicOps, cls).setup_clients()
         # Use admin client by default
         cls.manager = cls.admin_manager
-        super(TestAggregatesBasicOps, cls).resource_setup()
         cls.aggregates_client = cls.manager.aggregates_client
         cls.hosts_client = cls.manager.hosts_client
 
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index dba1c92..3ac6759 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -47,12 +47,6 @@
     10. Check SSH connection to instance after reboot
 
     """
-
-    def nova_list(self):
-        servers = self.servers_client.list_servers()
-        # The list servers in the compute client is inconsistent...
-        return servers['servers']
-
     def nova_show(self, server):
         got_server = (self.servers_client.show_server(server['id'])
                       ['server'])
@@ -96,6 +90,13 @@
                    '%s' % (secgroup['id'], server['id']))
             raise exceptions.TimeoutException(msg)
 
+    def _get_floating_ip_in_server_addresses(self, floating_ip, server):
+        for network_name, addresses in server['addresses'].items():
+            for address in addresses:
+                if (address['OS-EXT-IPS:type'] == 'floating' and
+                        address['addr'] == floating_ip['ip']):
+                    return address
+
     @test.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
     @test.services('compute', 'volume', 'image', 'network')
     def test_minimum_basic_scenario(self):
@@ -105,7 +106,7 @@
         server = self.create_server(image_id=image,
                                     key_name=keypair['name'],
                                     wait_until='ACTIVE')
-        servers = self.nova_list()
+        servers = self.servers_client.list_servers()['servers']
         self.assertIn(server['id'], [x['id'] for x in servers])
 
         self.nova_show(server)
@@ -121,6 +122,16 @@
         self.cinder_show(volume)
 
         floating_ip = self.create_floating_ip(server)
+        # fetch the server again to make sure the addresses were refreshed
+        # after associating the floating IP
+        server = self.servers_client.show_server(server['id'])['server']
+        address = self._get_floating_ip_in_server_addresses(
+            floating_ip, server)
+        self.assertIsNotNone(
+            address,
+            "Failed to find floating IP '%s' in server addresses: %s" %
+            (floating_ip['ip'], server['addresses']))
+
         self.create_and_add_security_group_to_server(server)
 
         # check that we can SSH to the server before reboot
@@ -135,3 +146,21 @@
             floating_ip['ip'], private_key=keypair['private_key'])
 
         self.check_partitions()
+
+        # delete the floating IP, this should refresh the server addresses
+        self.compute_floating_ips_client.delete_floating_ip(floating_ip['id'])
+
+        def is_floating_ip_detached_from_server():
+            server_info = self.servers_client.show_server(
+                server['id'])['server']
+            address = self._get_floating_ip_in_server_addresses(
+                floating_ip, server_info)
+            return (not address)
+
+        if not test_utils.call_until_true(
+            is_floating_ip_detached_from_server,
+            CONF.compute.build_timeout,
+            CONF.compute.build_interval):
+            msg = ("Floating IP '%s' should not be in server addresses: %s" %
+                   (floating_ip['ip'], server['addresses']))
+            raise exceptions.TimeoutException(msg)
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index a89147a..3390aff 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -50,28 +50,30 @@
         cls.set_network_resources()
         super(TestNetworkAdvancedServerOps, cls).setup_credentials()
 
-    def _setup_network_and_servers(self):
-        keypair = self.create_keypair()
+    def _setup_server(self, keypair):
         security_groups = []
         if test.is_extension_enabled('security-group', 'network'):
             security_group = self._create_security_group()
             security_groups = [{'name': security_group['name']}]
         network, subnet, router = self.create_networks()
-        public_network_id = CONF.network.public_network_id
-        server_name = data_utils.rand_name('server')
+        server_name = data_utils.rand_name(self.__class__.__name__ + '-server')
         server = self.create_server(
             name=server_name,
             networks=[{'uuid': network['id']}],
             key_name=keypair['name'],
             security_groups=security_groups,
             wait_until='ACTIVE')
+        return server
+
+    def _setup_network(self, server, keypair):
+        public_network_id = CONF.network.public_network_id
         floating_ip = self.create_floating_ip(server, public_network_id)
         # Verify that we can indeed connect to the server before we mess with
         # it's state
         self._wait_server_status_and_check_network_connectivity(
             server, keypair, floating_ip)
 
-        return server, keypair, floating_ip
+        return floating_ip
 
     def _check_network_connectivity(self, server, keypair, floating_ip,
                                     should_connect=True):
@@ -99,7 +101,9 @@
     @test.stresstest(class_setup_per='process')
     @test.services('compute', 'network')
     def test_server_connectivity_stop_start(self):
-        server, keypair, floating_ip = self._setup_network_and_servers()
+        keypair = self.create_keypair()
+        server = self._setup_server(keypair)
+        floating_ip = self._setup_network(server, keypair)
         self.servers_client.stop_server(server['id'])
         waiters.wait_for_server_status(self.servers_client, server['id'],
                                        'SHUTOFF')
@@ -112,7 +116,9 @@
     @test.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
     @test.services('compute', 'network')
     def test_server_connectivity_reboot(self):
-        server, keypair, floating_ip = self._setup_network_and_servers()
+        keypair = self.create_keypair()
+        server = self._setup_server(keypair)
+        floating_ip = self._setup_network(server, keypair)
         self.servers_client.reboot_server(server['id'], type='SOFT')
         self._wait_server_status_and_check_network_connectivity(
             server, keypair, floating_ip)
@@ -120,7 +126,9 @@
     @test.idempotent_id('88a529c2-1daa-4c85-9aec-d541ba3eb699')
     @test.services('compute', 'network')
     def test_server_connectivity_rebuild(self):
-        server, keypair, floating_ip = self._setup_network_and_servers()
+        keypair = self.create_keypair()
+        server = self._setup_server(keypair)
+        floating_ip = self._setup_network(server, keypair)
         image_ref_alt = CONF.compute.image_ref_alt
         self.servers_client.rebuild_server(server['id'],
                                            image_ref=image_ref_alt)
@@ -132,7 +140,9 @@
                           'Pause is not available.')
     @test.services('compute', 'network')
     def test_server_connectivity_pause_unpause(self):
-        server, keypair, floating_ip = self._setup_network_and_servers()
+        keypair = self.create_keypair()
+        server = self._setup_server(keypair)
+        floating_ip = self._setup_network(server, keypair)
         self.servers_client.pause_server(server['id'])
         waiters.wait_for_server_status(self.servers_client, server['id'],
                                        'PAUSED')
@@ -147,7 +157,9 @@
                           'Suspend is not available.')
     @test.services('compute', 'network')
     def test_server_connectivity_suspend_resume(self):
-        server, keypair, floating_ip = self._setup_network_and_servers()
+        keypair = self.create_keypair()
+        server = self._setup_server(keypair)
+        floating_ip = self._setup_network(server, keypair)
         self.servers_client.suspend_server(server['id'])
         waiters.wait_for_server_status(self.servers_client, server['id'],
                                        'SUSPENDED')
@@ -166,7 +178,9 @@
         if resize_flavor == CONF.compute.flavor_ref:
             msg = "Skipping test - flavor_ref and flavor_ref_alt are identical"
             raise self.skipException(msg)
-        server, keypair, floating_ip = self._setup_network_and_servers()
+        keypair = self.create_keypair()
+        server = self._setup_server(keypair)
+        floating_ip = self._setup_network(server, keypair)
         self.servers_client.resize_server(server['id'],
                                           flavor_ref=resize_flavor)
         waiters.wait_for_server_status(self.servers_client, server['id'],
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 519dbec..a295b6a 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -473,11 +473,11 @@
     def test_hotplug_nic(self):
         """Test hotplug network interface
 
-        1. create a new network, with no gateway (to prevent overwriting VM's
-            gateway)
-        2. connect VM to new network
-        3. set static ip and bring new nic up
-        4. check VM can ping new network dhcp port
+        1. Create a network and a VM.
+        2. Check connectivity to the VM via a public network.
+        3. Create a new network, with no gateway.
+        4. Bring up a new interface
+        5. check the VM reach the new network
 
         """
         self._setup_network_and_servers()
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 86185c8..2c16be8 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 from oslo_log import log
+import testtools
 
 from tempest import clients
 from tempest.common.utils import data_utils
@@ -256,7 +257,7 @@
         # and distributed routers; 'device_owner' is "" by default.
         return port['device_owner'].startswith('network:router_interface')
 
-    def _create_server(self, name, tenant, security_groups=None, **kwargs):
+    def _create_server(self, name, tenant, security_groups, **kwargs):
         """Creates a server and assigns it to security group.
 
         If multi-host is enabled, Ensures servers are created on different
@@ -264,8 +265,6 @@
         as scheduler_hints on creation.
         Validates servers are created as requested, using admin client.
         """
-        if security_groups is None:
-            security_groups = [tenant.security_groups['default']]
         security_groups_names = [{'name': s['name']} for s in security_groups]
         if self.multi_node:
             kwargs["scheduler_hints"] = {'different_host': self.servers}
@@ -277,9 +276,10 @@
             wait_until='ACTIVE',
             clients=tenant.manager,
             **kwargs)
-        self.assertEqual(
-            sorted([s['name'] for s in security_groups]),
-            sorted([s['name'] for s in server['security_groups']]))
+        if 'security_groups' in server:
+            self.assertEqual(
+                sorted([s['name'] for s in security_groups]),
+                sorted([s['name'] for s in server['security_groups']]))
 
         # Verify servers are on different compute nodes
         if self.multi_node:
@@ -303,7 +303,8 @@
                    num=i
             )
             name = data_utils.rand_name(name)
-            server = self._create_server(name, tenant)
+            server = self._create_server(name, tenant,
+                                         [tenant.security_groups['default']])
             tenant.servers.append(server)
 
     def _set_access_point(self, tenant):
@@ -326,11 +327,12 @@
             client=tenant.manager.floating_ips_client)
         self.floating_ips.setdefault(server['id'], floating_ip)
 
-    def _create_tenant_network(self, tenant):
+    def _create_tenant_network(self, tenant, port_security_enabled=True):
         network, subnet, router = self.create_networks(
             networks_client=tenant.manager.networks_client,
             routers_client=tenant.manager.routers_client,
-            subnets_client=tenant.manager.subnets_client)
+            subnets_client=tenant.manager.subnets_client,
+            port_security_enabled=port_security_enabled)
         tenant.set_network(network, subnet, router)
 
     def _deploy_tenant(self, tenant_or_id):
@@ -533,7 +535,8 @@
                tenant=new_tenant.creds.tenant_name
         )
         name = data_utils.rand_name(name)
-        server = self._create_server(name, new_tenant)
+        server = self._create_server(name, new_tenant,
+                                     [new_tenant.security_groups['default']])
 
         # Check connectivity failure with default security group
         try:
@@ -599,7 +602,8 @@
                tenant=new_tenant.creds.tenant_name
         )
         name = data_utils.rand_name(name)
-        server = self._create_server(name, new_tenant)
+        server = self._create_server(name, new_tenant,
+                                     [new_tenant.security_groups['default']])
 
         access_point_ssh = self._connect_to_access_point(new_tenant)
         server_id = server['id']
@@ -624,3 +628,32 @@
             for tenant in self.tenants.values():
                 self._log_console_output(servers=tenant.servers)
             raise
+
+    @test.requires_ext(service='network', extension='port-security')
+    @test.idempotent_id('13ccf253-e5ad-424b-9c4a-97b88a026699')
+    @testtools.skipUnless(
+        CONF.compute_feature_enabled.allow_port_security_disabled,
+        'Port security must be enabled.')
+    # TODO(mriedem): We shouldn't actually need to check this since neutron
+    # disables the port_security extension by default, but the problem is nova
+    # assumes port_security_enabled=True if it's not set on the network
+    # resource, which will mean nova may attempt to apply a security group on
+    # a port on that network which would fail. This is really a bug in nova.
+    @testtools.skipUnless(
+        CONF.network_feature_enabled.port_security,
+        'Port security must be enabled.')
+    @test.services('compute', 'network')
+    def test_boot_into_disabled_port_security_network_without_secgroup(self):
+        tenant = self.primary_tenant
+        self._create_tenant_network(tenant, port_security_enabled=False)
+        self.assertFalse(tenant.network['port_security_enabled'])
+        name = data_utils.rand_name('server-smoke')
+        sec_groups = []
+        server = self._create_server(name, tenant, sec_groups)
+        server_id = server['id']
+        ports = self._list_ports(device_id=server_id)
+        self.assertEqual(1, len(ports))
+        for port in ports:
+            self.assertEmpty(port['security_groups'],
+                             "Neutron shouldn't even use it's default sec "
+                             "group.")
diff --git a/tempest/scenario/test_server_multinode.py b/tempest/scenario/test_server_multinode.py
index 0cf72c3..b323d2a 100644
--- a/tempest/scenario/test_server_multinode.py
+++ b/tempest/scenario/test_server_multinode.py
@@ -42,7 +42,6 @@
         # this is needed so that we can use the availability_zone:host
         # scheduler hint, which is admin_only by default
         cls.servers_client = cls.admin_manager.servers_client
-        super(TestServerMultinode, cls).resource_setup()
 
     @test.idempotent_id('9cecbe35-b9d4-48da-a37e-7ce70aa43d30')
     @test.attr(type='smoke')
diff --git a/tempest/services/identity/__init__.py b/tempest/services/identity/__init__.py
index 0e24926..53c223f 100644
--- a/tempest/services/identity/__init__.py
+++ b/tempest/services/identity/__init__.py
@@ -12,7 +12,7 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
-from tempest.services.identity import v2
+from tempest.lib.services.identity import v2
 from tempest.services.identity import v3
 
 __all__ = ['v2', 'v3']
diff --git a/tempest/services/identity/v2/__init__.py b/tempest/services/identity/v2/__init__.py
deleted file mode 100644
index b7d3c74..0000000
--- a/tempest/services/identity/v2/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (c) 2016 Hewlett-Packard Enterprise 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 tempest.lib.services.identity.v2.endpoints_client import EndpointsClient
-from tempest.lib.services.identity.v2.identity_client import IdentityClient
-from tempest.lib.services.identity.v2.roles_client import RolesClient
-from tempest.lib.services.identity.v2.services_client import ServicesClient
-from tempest.lib.services.identity.v2.tenants_client import TenantsClient
-from tempest.lib.services.identity.v2.token_client import TokenClient
-from tempest.lib.services.identity.v2.users_client import UsersClient
-
-__all__ = ['EndpointsClient', 'IdentityClient', 'RolesClient',
-           'ServicesClient', 'TenantsClient', 'TokenClient', 'UsersClient']
diff --git a/tempest/services/identity/v2/json/__init__.py b/tempest/services/identity/v2/json/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/identity/v2/json/__init__.py
+++ /dev/null
diff --git a/tempest/services/identity/v3/__init__.py b/tempest/services/identity/v3/__init__.py
index c77c78d..9b40b77 100644
--- a/tempest/services/identity/v3/__init__.py
+++ b/tempest/services/identity/v3/__init__.py
@@ -12,22 +12,27 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+from tempest.lib.services.identity.v3.credentials_client import \
+    CredentialsClient
 from tempest.lib.services.identity.v3.endpoints_client import EndPointsClient
+from tempest.lib.services.identity.v3.groups_client import GroupsClient
+from tempest.lib.services.identity.v3.identity_client import IdentityClient
+from tempest.lib.services.identity.v3.inherited_roles_client import \
+    InheritedRolesClient
 from tempest.lib.services.identity.v3.policies_client import PoliciesClient
 from tempest.lib.services.identity.v3.projects_client import ProjectsClient
 from tempest.lib.services.identity.v3.regions_client import RegionsClient
+from tempest.lib.services.identity.v3.roles_client import RolesClient
 from tempest.lib.services.identity.v3.services_client import ServicesClient
 from tempest.lib.services.identity.v3.token_client import V3TokenClient
-from tempest.services.identity.v3.json.credentials_client import \
-    CredentialsClient
+from tempest.lib.services.identity.v3.trusts_client import TrustsClient
+from tempest.lib.services.identity.v3.users_client import UsersClient
 from tempest.services.identity.v3.json.domains_client import DomainsClient
-from tempest.services.identity.v3.json.groups_client import GroupsClient
-from tempest.services.identity.v3.json.identity_client import IdentityClient
-from tempest.services.identity.v3.json.roles_client import RolesClient
-from tempest.services.identity.v3.json.trusts_client import TrustsClient
-from tempest.services.identity.v3.json.users_clients import UsersClient
+from tempest.services.identity.v3.json.role_assignments_client import \
+    RoleAssignmentsClient
 
-__all__ = ['EndPointsClient', 'PoliciesClient', 'ProjectsClient',
-           'RegionsClient', 'ServicesClient', 'V3TokenClient',
-           'CredentialsClient', 'DomainsClient', 'GroupsClient',
-           'IdentityClient', 'RolesClient', 'TrustsClient', 'UsersClient', ]
+__all__ = ['CredentialsClient', 'EndPointsClient', 'GroupsClient',
+           'IdentityClient', 'InheritedRolesClient', 'PoliciesClient',
+           'ProjectsClient', 'RegionsClient', 'RoleAssignmentsClient',
+           'RolesClient', 'ServicesClient', 'V3TokenClient', 'TrustsClient',
+           'UsersClient', 'DomainsClient', ]
diff --git a/tempest/services/identity/v3/json/role_assignments_client.py b/tempest/services/identity/v3/json/role_assignments_client.py
new file mode 100644
index 0000000..9fd7736
--- /dev/null
+++ b/tempest/services/identity/v3/json/role_assignments_client.py
@@ -0,0 +1,31 @@
+# Copyright 2016 Red Hat, 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.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
+
+
+class RoleAssignmentsClient(rest_client.RestClient):
+    api_version = "v3"
+
+    def list_user_project_effective_assignments(
+            self, project_id, user_id):
+        """List the effective role assignments for a user in a project."""
+        resp, body = self.get(
+            "role_assignments?scope.project.id=%s&user.id=%s&effective" %
+            (project_id, user_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/roles_client.py b/tempest/services/identity/v3/json/roles_client.py
deleted file mode 100644
index 3f165fa..0000000
--- a/tempest/services/identity/v3/json/roles_client.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright 2016 Red Hat, 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.
-
-from oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.lib.common import rest_client
-
-
-class RolesClient(rest_client.RestClient):
-    api_version = "v3"
-
-    def create_role(self, **kwargs):
-        """Create a Role.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createRole
-        """
-        post_body = json.dumps({'role': kwargs})
-        resp, body = self.post('roles', post_body)
-        self.expected_success(201, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_role(self, role_id):
-        """GET a Role."""
-        resp, body = self.get('roles/%s' % role_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_roles(self, **params):
-        """Get the list of Roles."""
-
-        url = 'roles'
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-        resp, body = self.get(url)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def update_role(self, role_id, **kwargs):
-        """Update a Role.
-
-        Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#updateRole
-        """
-        post_body = json.dumps({'role': kwargs})
-        resp, body = self.patch('roles/%s' % role_id, post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role(self, role_id):
-        """Delete a role."""
-        resp, body = self.delete('roles/%s' % role_id)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_user_role_on_project(self, project_id, user_id, role_id):
-        """Add roles to a user on a project."""
-        resp, body = self.put('projects/%s/users/%s/roles/%s' %
-                              (project_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_user_role_on_domain(self, domain_id, user_id, role_id):
-        """Add roles to a user on a domain."""
-        resp, body = self.put('domains/%s/users/%s/roles/%s' %
-                              (domain_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_user_roles_on_project(self, project_id, user_id):
-        """list roles of a user on a project."""
-        resp, body = self.get('projects/%s/users/%s/roles' %
-                              (project_id, user_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_user_roles_on_domain(self, domain_id, user_id):
-        """list roles of a user on a domain."""
-        resp, body = self.get('domains/%s/users/%s/roles' %
-                              (domain_id, user_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role_from_user_on_project(self, project_id, user_id, role_id):
-        """Delete role of a user on a project."""
-        resp, body = self.delete('projects/%s/users/%s/roles/%s' %
-                                 (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role_from_user_on_domain(self, domain_id, user_id, role_id):
-        """Delete role of a user on a domain."""
-        resp, body = self.delete('domains/%s/users/%s/roles/%s' %
-                                 (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_user_role_existence_on_project(self, project_id,
-                                             user_id, role_id):
-        """Check role of a user on a project."""
-        resp, body = self.head('projects/%s/users/%s/roles/%s' %
-                               (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def check_user_role_existence_on_domain(self, domain_id,
-                                            user_id, role_id):
-        """Check role of a user on a domain."""
-        resp, body = self.head('domains/%s/users/%s/roles/%s' %
-                               (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def create_group_role_on_project(self, project_id, group_id, role_id):
-        """Add roles to a group on a project."""
-        resp, body = self.put('projects/%s/groups/%s/roles/%s' %
-                              (project_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_group_role_on_domain(self, domain_id, group_id, role_id):
-        """Add roles to a group on a domain."""
-        resp, body = self.put('domains/%s/groups/%s/roles/%s' %
-                              (domain_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_group_roles_on_project(self, project_id, group_id):
-        """list roles of a group on a project."""
-        resp, body = self.get('projects/%s/groups/%s/roles' %
-                              (project_id, group_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_group_roles_on_domain(self, domain_id, group_id):
-        """list roles of a group on a domain."""
-        resp, body = self.get('domains/%s/groups/%s/roles' %
-                              (domain_id, group_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role_from_group_on_project(self, project_id, group_id, role_id):
-        """Delete role of a group on a project."""
-        resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
-                                 (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role_from_group_on_domain(self, domain_id, group_id, role_id):
-        """Delete role of a group on a domain."""
-        resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
-                                 (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_role_from_group_on_project_existence(self, project_id,
-                                                   group_id, role_id):
-        """Check role of a group on a project."""
-        resp, body = self.head('projects/%s/groups/%s/roles/%s' %
-                               (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def check_role_from_group_on_domain_existence(self, domain_id,
-                                                  group_id, role_id):
-        """Check role of a group on a domain."""
-        resp, body = self.head('domains/%s/groups/%s/roles/%s' %
-                               (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def assign_inherited_role_on_domains_user(
-            self, domain_id, user_id, role_id):
-        """Assigns a role to a user on projects owned by a domain."""
-        resp, body = self.put(
-            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
-            % (domain_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def revoke_inherited_role_from_user_on_domain(
-            self, domain_id, user_id, role_id):
-        """Revokes an inherited project role from a user on a domain."""
-        resp, body = self.delete(
-            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
-            % (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_inherited_project_role_for_user_on_domain(
-            self, domain_id, user_id):
-        """Lists the inherited project roles on a domain for a user."""
-        resp, body = self.get(
-            "OS-INHERIT/domains/%s/users/%s/roles/inherited_to_projects"
-            % (domain_id, user_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_user_inherited_project_role_on_domain(
-            self, domain_id, user_id, role_id):
-        """Checks whether a user has an inherited project role on a domain."""
-        resp, body = self.head(
-            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
-            % (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def assign_inherited_role_on_domains_group(
-            self, domain_id, group_id, role_id):
-        """Assigns a role to a group on projects owned by a domain."""
-        resp, body = self.put(
-            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (domain_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def revoke_inherited_role_from_group_on_domain(
-            self, domain_id, group_id, role_id):
-        """Revokes an inherited project role from a group on a domain."""
-        resp, body = self.delete(
-            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_inherited_project_role_for_group_on_domain(
-            self, domain_id, group_id):
-        """Lists the inherited project roles on a domain for a group."""
-        resp, body = self.get(
-            "OS-INHERIT/domains/%s/groups/%s/roles/inherited_to_projects"
-            % (domain_id, group_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_group_inherited_project_role_on_domain(
-            self, domain_id, group_id, role_id):
-        """Checks whether a group has an inherited project role on a domain."""
-        resp, body = self.head(
-            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def assign_inherited_role_on_projects_user(
-            self, project_id, user_id, role_id):
-        """Assigns a role to a user on projects in a subtree."""
-        resp, body = self.put(
-            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
-            % (project_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def revoke_inherited_role_from_user_on_project(
-            self, project_id, user_id, role_id):
-        """Revokes an inherited role from a user on a project."""
-        resp, body = self.delete(
-            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
-            % (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_user_has_flag_on_inherited_to_project(
-            self, project_id, user_id, role_id):
-        """Checks whether a user has a role assignment"""
-        """with the inherited_to_projects flag on a project."""
-        resp, body = self.head(
-            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
-            % (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def assign_inherited_role_on_projects_group(
-            self, project_id, group_id, role_id):
-        """Assigns a role to a group on projects in a subtree."""
-        resp, body = self.put(
-            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (project_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def revoke_inherited_role_from_group_on_project(
-            self, project_id, group_id, role_id):
-        """Revokes an inherited role from a group on a project."""
-        resp, body = self.delete(
-            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_group_has_flag_on_inherited_to_project(
-            self, project_id, group_id, role_id):
-        """Checks whether a group has a role assignment"""
-        """with the inherited_to_projects flag on a project."""
-        resp, body = self.head(
-            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index a7db30e..ec36fb7 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -195,7 +195,6 @@
 
         # Read the 100 status prior to sending the data
         response = conn.response_class(conn.sock,
-                                       strict=conn.strict,
                                        method=conn._method)
         _, status, _ = response._read_status()
 
diff --git a/tempest/services/volume/base/admin/__init__.py b/tempest/services/volume/base/admin/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/volume/base/admin/__init__.py
+++ /dev/null
diff --git a/tempest/services/volume/base/base_backups_client.py b/tempest/services/volume/base/base_backups_client.py
index a57e628..1b35feb 100644
--- a/tempest/services/volume/base/base_backups_client.py
+++ b/tempest/services/volume/base/base_backups_client.py
@@ -13,11 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import time
-
 from oslo_serialization import jsonutils as json
 
-from tempest import exceptions
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions as lib_exc
 
@@ -96,26 +93,6 @@
         self.expected_success(202, resp.status)
         return rest_client.ResponseBody(resp, body)
 
-    def wait_for_backup_status(self, backup_id, status):
-        """Waits for a Backup to reach a given status."""
-        body = self.show_backup(backup_id)['backup']
-        backup_status = body['status']
-        start = int(time.time())
-
-        while backup_status != status:
-            time.sleep(self.build_interval)
-            body = self.show_backup(backup_id)['backup']
-            backup_status = body['status']
-            if backup_status == 'error' and backup_status != status:
-                raise exceptions.VolumeBackupException(backup_id=backup_id)
-
-            if int(time.time()) - start >= self.build_timeout:
-                message = ('Volume backup %s failed to reach %s status '
-                           '(current %s) within the required time (%s s).' %
-                           (backup_id, status, backup_status,
-                            self.build_timeout))
-                raise exceptions.TimeoutException(message)
-
     def is_resource_deleted(self, id):
         try:
             self.show_backup(id)
diff --git a/tempest/services/volume/base/base_volumes_client.py b/tempest/services/volume/base/base_volumes_client.py
index 308f818..1cb1ef5 100755
--- a/tempest/services/volume/base/base_volumes_client.py
+++ b/tempest/services/volume/base/base_volumes_client.py
@@ -52,34 +52,6 @@
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, body)
 
-    def show_pools(self, detail=False):
-        """List all the volumes pools (hosts).
-
-        Output params: see http://developer.openstack.org/
-                           api-ref-blockstorage-v2.html#listPools
-        """
-        url = 'scheduler-stats/get_pools'
-        if detail:
-            url += '?detail=True'
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_backend_capabilities(self, host):
-        """Shows capabilities for a storage back end.
-
-         Output params: see http://developer.openstack.org/
-                            api-ref-blockstorage-v2.html
-                            #showBackendCapabilities
-        """
-        url = 'capabilities/%s' % host
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
     def show_volume(self, volume_id):
         """Returns the details of a single volume."""
         url = "volumes/%s" % volume_id
@@ -316,28 +288,6 @@
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, body)
 
-    def update_volume_image_metadata(self, volume_id, **kwargs):
-        """Update image metadata for the volume.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html
-                              #setVolumeimagemetadata
-        """
-        post_body = json.dumps({'os-set_image_metadata': {'metadata': kwargs}})
-        url = "volumes/%s/action" % (volume_id)
-        resp, body = self.post(url, post_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_volume_image_metadata(self, volume_id, key_name):
-        """Delete image metadata item for the volume."""
-        post_body = json.dumps({'os-unset_image_metadata': {'key': key_name}})
-        url = "volumes/%s/action" % (volume_id)
-        resp, body = self.post(url, post_body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
     def retype_volume(self, volume_id, **kwargs):
         """Updates volume with new volume type."""
         post_body = json.dumps({'os-retype': kwargs})
diff --git a/tempest/services/volume/v1/__init__.py b/tempest/services/volume/v1/__init__.py
index 72868bc..e386faf 100644
--- a/tempest/services/volume/v1/__init__.py
+++ b/tempest/services/volume/v1/__init__.py
@@ -14,19 +14,20 @@
 
 from tempest.lib.services.volume.v1.availability_zone_client import \
     AvailabilityZoneClient
+from tempest.lib.services.volume.v1.encryption_types_client import \
+    EncryptionTypesClient
 from tempest.lib.services.volume.v1.extensions_client import ExtensionsClient
 from tempest.lib.services.volume.v1.hosts_client import HostsClient
+from tempest.lib.services.volume.v1.qos_client import QosSpecsClient
 from tempest.lib.services.volume.v1.quotas_client import QuotasClient
 from tempest.lib.services.volume.v1.services_client import ServicesClient
-from tempest.services.volume.v1.json.admin.types_client import TypesClient
+from tempest.lib.services.volume.v1.snapshots_client import SnapshotsClient
+from tempest.lib.services.volume.v1.types_client import TypesClient
 from tempest.services.volume.v1.json.backups_client import BackupsClient
-from tempest.services.volume.v1.json.encryption_types_client import \
-    EncryptionTypesClient
-from tempest.services.volume.v1.json.qos_client import QosSpecsClient
-from tempest.services.volume.v1.json.snapshots_client import SnapshotsClient
 from tempest.services.volume.v1.json.volumes_client import VolumesClient
 
-__all__ = ['HostsClient', 'QuotasClient', 'ServicesClient', 'TypesClient',
-           'AvailabilityZoneClient', 'BackupsClient', 'ExtensionsClient',
-           'QosSpecsClient', 'SnapshotsClient', 'VolumesClient',
-           'EncryptionTypesClient']
+__all__ = ['AvailabilityZoneClient', 'EncryptionTypesClient',
+           'ExtensionsClient', 'HostsClient', 'QuotasClient',
+           'QosSpecsClient', 'ServicesClient',
+           'SnapshotsClient', 'TypesClient', 'BackupsClient',
+           'VolumesClient', ]
diff --git a/tempest/services/volume/v1/json/admin/__init__.py b/tempest/services/volume/v1/json/admin/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/volume/v1/json/admin/__init__.py
+++ /dev/null
diff --git a/tempest/services/volume/v1/json/admin/types_client.py b/tempest/services/volume/v1/json/admin/types_client.py
deleted file mode 100644
index 0e84296..0000000
--- a/tempest/services/volume/v1/json/admin/types_client.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2012 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.services.volume.base.admin import base_types_client
-
-
-class TypesClient(base_types_client.BaseTypesClient):
-    """Volume V1 Volume Types client"""
diff --git a/tempest/services/volume/v1/json/qos_client.py b/tempest/services/volume/v1/json/qos_client.py
deleted file mode 100644
index b2b2195..0000000
--- a/tempest/services/volume/v1/json/qos_client.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# 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.services.volume.base import base_qos_client
-
-
-class QosSpecsClient(base_qos_client.BaseQosSpecsClient):
-    """Volume V1 QoS client."""
diff --git a/tempest/services/volume/v1/json/snapshots_client.py b/tempest/services/volume/v1/json/snapshots_client.py
deleted file mode 100644
index b039c2b..0000000
--- a/tempest/services/volume/v1/json/snapshots_client.py
+++ /dev/null
@@ -1,17 +0,0 @@
-#    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.services.volume.base import base_snapshots_client
-
-
-class SnapshotsClient(base_snapshots_client.BaseSnapshotsClient):
-    """Client class to send CRUD Volume V1 API requests."""
diff --git a/tempest/services/volume/v2/__init__.py b/tempest/services/volume/v2/__init__.py
index 4afcc29..fcc34f9 100644
--- a/tempest/services/volume/v2/__init__.py
+++ b/tempest/services/volume/v2/__init__.py
@@ -14,19 +14,19 @@
 
 from tempest.lib.services.volume.v2.availability_zone_client import \
     AvailabilityZoneClient
+from tempest.lib.services.volume.v2.encryption_types_client import \
+    EncryptionTypesClient
 from tempest.lib.services.volume.v2.extensions_client import ExtensionsClient
 from tempest.lib.services.volume.v2.hosts_client import HostsClient
+from tempest.lib.services.volume.v2.qos_client import QosSpecsClient
 from tempest.lib.services.volume.v2.quotas_client import QuotasClient
 from tempest.lib.services.volume.v2.services_client import ServicesClient
-from tempest.services.volume.v2.json.admin.types_client import TypesClient
+from tempest.lib.services.volume.v2.snapshots_client import SnapshotsClient
+from tempest.lib.services.volume.v2.types_client import TypesClient
 from tempest.services.volume.v2.json.backups_client import BackupsClient
-from tempest.services.volume.v2.json.encryption_types_client import \
-    EncryptionTypesClient
-from tempest.services.volume.v2.json.qos_client import QosSpecsClient
-from tempest.services.volume.v2.json.snapshots_client import SnapshotsClient
 from tempest.services.volume.v2.json.volumes_client import VolumesClient
 
-__all__ = ['HostsClient', 'QuotasClient', 'ServicesClient', 'TypesClient',
-           'AvailabilityZoneClient', 'BackupsClient', 'ExtensionsClient',
-           'QosSpecsClient', 'SnapshotsClient', 'VolumesClient',
-           'EncryptionTypesClient']
+__all__ = ['AvailabilityZoneClient', 'EncryptionTypesClient',
+           'ExtensionsClient', 'HostsClient', 'QosSpecsClient',
+           'QuotasClient', 'ServicesClient', 'SnapshotsClient',
+           'TypesClient', 'BackupsClient', 'VolumesClient', ]
diff --git a/tempest/services/volume/v2/json/admin/__init__.py b/tempest/services/volume/v2/json/admin/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/volume/v2/json/admin/__init__.py
+++ /dev/null
diff --git a/tempest/services/volume/v2/json/admin/types_client.py b/tempest/services/volume/v2/json/admin/types_client.py
deleted file mode 100644
index f76e8dc..0000000
--- a/tempest/services/volume/v2/json/admin/types_client.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2012 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 oslo_serialization import jsonutils as json
-
-from tempest.lib.common import rest_client
-from tempest.services.volume.base.admin import base_types_client
-
-
-class TypesClient(base_types_client.BaseTypesClient):
-    """Client class to send CRUD Volume V2 API requests"""
-    api_version = "v2"
-
-    def add_type_access(self, volume_type_id, **kwargs):
-        """Adds volume type access for the given project.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html
-                              #createVolumeTypeAccessExt
-        """
-        post_body = json.dumps({'addProjectAccess': kwargs})
-        url = 'types/%s/action' % volume_type_id
-        resp, body = self.post(url, post_body)
-        self.expected_success(202, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def remove_type_access(self, volume_type_id, **kwargs):
-        """Removes volume type access for the given project.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html
-                              #removeVolumeTypeAccessExt
-        """
-        post_body = json.dumps({'removeProjectAccess': kwargs})
-        url = 'types/%s/action' % volume_type_id
-        resp, body = self.post(url, post_body)
-        self.expected_success(202, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_type_access(self, volume_type_id):
-        """Print access information about the given volume type.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#
-                              listVolumeTypeAccessExt
-        """
-        url = 'types/%s/os-volume-type-access' % volume_type_id
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/v2/json/qos_client.py b/tempest/services/volume/v2/json/qos_client.py
deleted file mode 100644
index 3c0f74f..0000000
--- a/tempest/services/volume/v2/json/qos_client.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# 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.services.volume.base import base_qos_client
-
-
-class QosSpecsClient(base_qos_client.BaseQosSpecsClient):
-    api_version = "v2"
diff --git a/tempest/services/volume/v2/json/snapshots_client.py b/tempest/services/volume/v2/json/snapshots_client.py
deleted file mode 100644
index a2d415f..0000000
--- a/tempest/services/volume/v2/json/snapshots_client.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#    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.services.volume.base import base_snapshots_client
-
-
-class SnapshotsClient(base_snapshots_client.BaseSnapshotsClient):
-    """Client class to send CRUD Volume V2 API requests."""
-    api_version = "v2"
-    create_resp = 202
diff --git a/tempest/services/volume/v2/json/volumes_client.py b/tempest/services/volume/v2/json/volumes_client.py
index b7d9dfb..f21a1a3 100644
--- a/tempest/services/volume/v2/json/volumes_client.py
+++ b/tempest/services/volume/v2/json/volumes_client.py
@@ -13,6 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
 from tempest.services.volume.base import base_volumes_client
 
 
@@ -20,3 +23,49 @@
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
     create_resp = 202
+
+    def update_volume_image_metadata(self, volume_id, **kwargs):
+        """Update image metadata for the volume.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html
+                              #setVolumeimagemetadata
+        """
+        post_body = json.dumps({'os-set_image_metadata': {'metadata': kwargs}})
+        url = "volumes/%s/action" % (volume_id)
+        resp, body = self.post(url, post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_volume_image_metadata(self, volume_id, key_name):
+        """Delete image metadata item for the volume."""
+        post_body = json.dumps({'os-unset_image_metadata': {'key': key_name}})
+        url = "volumes/%s/action" % (volume_id)
+        resp, body = self.post(url, post_body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_pools(self, detail=False):
+        # List all the volumes pools (hosts)
+        url = 'scheduler-stats/get_pools'
+        if detail:
+            url += '?detail=True'
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_backend_capabilities(self, host):
+        """Shows capabilities for a storage back end.
+
+         Output params: see http://developer.openstack.org/
+                            api-ref-blockstorage-v2.html
+                            #showBackendCapabilities
+        """
+        url = 'capabilities/%s' % host
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/stress/actions/server_create_destroy.py b/tempest/stress/actions/server_create_destroy.py
index 44b6f62..183bc6c 100644
--- a/tempest/stress/actions/server_create_destroy.py
+++ b/tempest/stress/actions/server_create_destroy.py
@@ -27,7 +27,7 @@
         self.flavor = CONF.compute.flavor_ref
 
     def run(self):
-        name = data_utils.rand_name("instance")
+        name = data_utils.rand_name(self.__class__.__name__ + "-instance")
         self.logger.info("creating %s" % name)
         server = self.manager.servers_client.create_server(
             name=name, imageRef=self.image, flavorRef=self.flavor)['server']
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index c9a4d38..845b4a7 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -70,7 +70,8 @@
                          self.server_id, self.floating['ip'])
 
     def _create_vm(self):
-        self.name = name = data_utils.rand_name("instance")
+        self.name = name = data_utils.rand_name(
+            self.__class__.__name__ + "-instance")
         servers_client = self.manager.servers_client
         self.logger.info("creating %s" % name)
         vm_args = self.vm_extra_args.copy()
@@ -92,7 +93,7 @@
 
     def _create_sec_group(self):
         sec_grp_cli = self.manager.compute_security_groups_client
-        s_name = data_utils.rand_name('sec_grp')
+        s_name = data_utils.rand_name(self.__class__.__name__ + '-sec_grp')
         s_description = data_utils.rand_name('desc')
         self.sec_grp = sec_grp_cli.create_security_group(
             name=s_name, description=s_description)['security_group']
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index e06c364..5fc006e 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -27,7 +27,7 @@
 
     def run(self):
         # Step 1: create volume
-        name = data_utils.rand_name("volume")
+        name = data_utils.rand_name(self.__class__.__name__ + "-volume")
         self.logger.info("creating volume: %s" % name)
         volume = self.manager.volumes_client.create_volume(
             display_name=name, size=CONF.volume.volume_size)['volume']
@@ -36,7 +36,7 @@
         self.logger.info("created volume: %s" % volume['id'])
 
         # Step 2: create vm instance
-        vm_name = data_utils.rand_name("instance")
+        vm_name = data_utils.rand_name(self.__class__.__name__ + "-instance")
         self.logger.info("creating vm: %s" % vm_name)
         server = self.manager.servers_client.create_server(
             name=vm_name, imageRef=self.image, flavorRef=self.flavor)['server']
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index 743cb11..4fbb851 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -33,7 +33,8 @@
         self.manager.keypairs_client.delete_keypair(self.key['name'])
 
     def _create_vm(self):
-        self.name = name = data_utils.rand_name("instance")
+        self.name = name = data_utils.rand_name(
+            self.__class__.__name__ + "-instance")
         servers_client = self.manager.servers_client
         self.logger.info("creating %s" % name)
         vm_args = self.vm_extra_args.copy()
@@ -55,7 +56,7 @@
 
     def _create_sec_group(self):
         sec_grp_cli = self.manager.compute_security_groups_client
-        s_name = data_utils.rand_name('sec_grp')
+        s_name = data_utils.rand_name(self.__class__.__name__ + '-sec_grp')
         s_description = data_utils.rand_name('desc')
         self.sec_grp = sec_grp_cli.create_security_group(
             name=s_name, description=s_description)['security_group']
@@ -81,7 +82,7 @@
         self.logger.info("Deleted Floating IP %s", str(self.floating['ip']))
 
     def _create_volume(self):
-        name = data_utils.rand_name("volume")
+        name = data_utils.rand_name(self.__class__.__name__ + "-volume")
         self.logger.info("creating volume: %s" % name)
         volumes_client = self.manager.volumes_client
         self.volume = volumes_client.create_volume(
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 925d765..1e33e88 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -20,8 +20,6 @@
 from oslo_log import log as logging
 from oslo_utils import importutils
 import six
-from six import moves
-
 
 from tempest import clients
 from tempest.common import cred_client
@@ -142,7 +140,7 @@
             manager = admin_manager
         else:
             raise NotImplemented('Non admin tests are not supported')
-        for p_number in moves.xrange(test.get('threads', default_thread_num)):
+        for p_number in range(test.get('threads', default_thread_num)):
             if test.get('use_isolated_tenants', False):
                 username = data_utils.rand_name("stress_user")
                 tenant_name = data_utils.rand_name("stress_tenant")
diff --git a/tempest/tests/cmd/test_tempest_init.py b/tempest/tests/cmd/test_tempest_init.py
index 2844371..79510be 100644
--- a/tempest/tests/cmd/test_tempest_init.py
+++ b/tempest/tests/cmd/test_tempest_init.py
@@ -137,3 +137,18 @@
         self.assertTrue(os.path.isfile(fake_file_moved))
         self.assertTrue(os.path.isfile(local_conf_file))
         self.assertTrue(os.path.isfile(local_testr_conf))
+
+    def test_take_action_fails(self):
+        class ParsedArgs(object):
+            workspace_dir = self.useFixture(fixtures.TempDir()).path
+            workspace_path = os.path.join(workspace_dir, 'workspace.yaml')
+            name = 'test'
+            dir_base = self.useFixture(fixtures.TempDir()).path
+            dir = os.path.join(dir_base, 'foo', 'bar')
+            config_dir = self.useFixture(fixtures.TempDir()).path
+            show_global_dir = False
+        pa = ParsedArgs()
+        init_cmd = init.TempestInit(None, None)
+        self.assertRaises(OSError, init_cmd.take_action, pa)
+        # one more trying should be a same error not "workspace already exists"
+        self.assertRaises(OSError, init_cmd.take_action, pa)
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index d74734e..0033d4e 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -28,14 +28,15 @@
     v2_tenants_client
 from tempest.lib.services.identity.v2 import token_client as v2_token_client
 from tempest.lib.services.identity.v2 import users_client as v2_users_client
+from tempest.lib.services.identity.v3 import identity_client as v3_iden_client
 from tempest.lib.services.identity.v3 import projects_client as \
     v3_projects_client
+from tempest.lib.services.identity.v3 import roles_client as v3_roles_client
 from tempest.lib.services.identity.v3 import token_client as v3_token_client
+from tempest.lib.services.identity.v3 import users_client as \
+    v3_users_client
 from tempest.lib.services.network import routers_client
 from tempest.services.identity.v3.json import domains_client
-from tempest.services.identity.v3.json import identity_client as v3_iden_client
-from tempest.services.identity.v3.json import roles_client as v3_roles_client
-from tempest.services.identity.v3.json import users_clients as v3_users_client
 from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests.lib import fake_http
diff --git a/tempest/tests/fake_auth_provider.py b/tempest/tests/fake_auth_provider.py
deleted file mode 100644
index 769f6a6..0000000
--- a/tempest/tests/fake_auth_provider.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2014 Hewlett-Packard Development Company, L.P.
-# 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.
-
-
-class FakeAuthProvider(object):
-
-    def auth_request(self, method, url, headers=None, body=None, filters=None):
-        return url, headers, body
-
-    def get_token(self):
-        return "faketoken"
-
-    def base_url(self, filters, auth_data=None):
-        return "https://example.com"
diff --git a/tempest/tests/lib/common/utils/test_data_utils.py b/tempest/tests/lib/common/utils/test_data_utils.py
index 94a4847..4446e5c 100644
--- a/tempest/tests/lib/common/utils/test_data_utils.py
+++ b/tempest/tests/lib/common/utils/test_data_utils.py
@@ -125,13 +125,13 @@
 
     def test_random_bytes(self):
         actual = data_utils.random_bytes()  # default size=1024
-        self.assertIsInstance(actual, str)
-        self.assertRegex(actual, "^[\x00-\xFF]{1024}")
+        self.assertIsInstance(actual, bytes)
+        self.assertEqual(1024, len(actual))
         actual2 = data_utils.random_bytes()
         self.assertNotEqual(actual, actual2)
 
         actual = data_utils.random_bytes(size=2048)
-        self.assertRegex(actual, "^[\x00-\xFF]{2048}")
+        self.assertEqual(2048, len(actual))
 
     def test_get_ipv6_addr_by_EUI64(self):
         actual = data_utils.get_ipv6_addr_by_EUI64('2001:db8::',
diff --git a/tempest/tests/lib/fake_auth_provider.py b/tempest/tests/lib/fake_auth_provider.py
index fa8ab47..e4582f8 100644
--- a/tempest/tests/lib/fake_auth_provider.py
+++ b/tempest/tests/lib/fake_auth_provider.py
@@ -27,6 +27,9 @@
     def base_url(self, filters, auth_data=None):
         return self.fake_base_url or "https://example.com"
 
+    def get_token(self):
+        return "faketoken"
+
 
 class FakeCredentials(object):
 
diff --git a/tempest/tests/lib/services/identity/v3/test_credentials_client.py b/tempest/tests/lib/services/identity/v3/test_credentials_client.py
new file mode 100644
index 0000000..29d7496
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_credentials_client.py
@@ -0,0 +1,179 @@
+# Copyright 2016 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.lib.services.identity.v3 import credentials_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestCredentialsClient(base.BaseServiceTest):
+    FAKE_CREATE_CREDENTIAL = {
+        "credential": {
+            "blob": "{\"access\":\"181920\",\"secret\":\"secretKey\"}",
+            "project_id": "731fc6f265cd486d900f16e84c5cb594",
+            "type": "ec2",
+            "user_id": "bb5476fd12884539b41d5a88f838d773"
+        }
+    }
+
+    FAKE_INFO_CREDENTIAL = {
+        "credential": {
+            "user_id": "bb5476fd12884539b41d5a88f838d773",
+            "links": {
+                "self": "http://example.com/identity/v3/credentials/" +
+                        "207e9b76935efc03804d3dd6ab52d22e9b22a0711e4" +
+                        "ada4ff8b76165a07311d7"
+            },
+            "blob": "{\"access\": \"a42a27755ce6442596b049bd7dd8a563\"," +
+                    " \"secret\": \"71faf1d40bb24c82b479b1c6fbbd9f0c\"}",
+            "project_id": "6e01855f345f4c59812999b5e459137d",
+            "type": "ec2",
+            "id": "207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f"
+        }
+    }
+
+    FAKE_LIST_CREDENTIALS = {
+        "credentials": [
+            {
+                "user_id": "bb5476fd12884539b41d5a88f838d773",
+                "links": {
+                    "self": "http://example.com/identity/v3/credentials/" +
+                            "207e9b76935efc03804d3dd6ab52d22e9b22a0711e4" +
+                            "ada4ff8b76165a07311d7"
+                },
+                "blob": "{\"access\": \"a42a27755ce6442596b049bd7dd8a563\"," +
+                        " \"secret\": \"71faf1d40bb24c82b479b1c6fbbd9f0c\"," +
+                        " \"trust_id\": null}",
+                "project_id": "6e01855f345f4c59812999b5e459137d",
+                "type": "ec2",
+                "id": "207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f"
+            },
+            {
+                "user_id": "6f556708d04b4ea6bc72d7df2296b71a",
+                "links": {
+                    "self": "http://example.com/identity/v3/credentials/" +
+                            "2441494e52ab6d594a34d74586075cb299489bdd1e9" +
+                            "389e3ab06467a4f460609"
+                },
+                "blob": "{\"access\": \"7da79ff0aa364e1396f067e352b9b79a\"," +
+                        " \"secret\": \"7a18d68ba8834b799d396f3ff6f1e98c\"," +
+                        " \"trust_id\": null}",
+                "project_id": "1a1d14690f3c4ec5bf5f321c5fde3c16",
+                "type": "ec2",
+                "id": "2441494e52ab6d594a34d74586075cb299489bdd1e9389e3"
+            },
+            {
+                "user_id": "c14107e65d5c4a7f8894fc4b3fc209ff",
+                "links": {
+                    "self": "http://example.com/identity/v3/credentials/" +
+                            "3397b204b5f04c495bcdc8f34c8a39996f280f91726" +
+                            "58241873e15f070ec79d7"
+                },
+                "blob": "{\"access\": \"db9c58a558534a10a070110de4f9f20c\"," +
+                        " \"secret\": \"973e790b88db447ba6f93bca02bc745b\"," +
+                        " \"trust_id\": null}",
+                "project_id": "7396e43183db40dcbf40dd727637b548",
+                "type": "ec2",
+                "id": "3397b204b5f04c495bcdc8f34c8a39996f280f9172658241"
+            },
+            {
+                "user_id": "bb5476fd12884539b41d5a88f838d773",
+                "links": {
+                    "self": "http://example.com/identity/v3/credentials/" +
+                            "7ef4faa904ae7b8b4ddc7bad15b05ee359dad7d7a9b" +
+                            "82861d4ad92fdbbb2eb4e"
+                },
+                "blob": "{\"access\": \"7d7559359b57419eb5f5f5dcd65ab57d\"," +
+                        " \"secret\": \"570652bcf8c2483c86eb29e9734eed3c\"," +
+                        " \"trust_id\": null}",
+                "project_id": "731fc6f265cd486d900f16e84c5cb594",
+                "type": "ec2",
+                "id": "7ef4faa904ae7b8b4ddc7bad15b05ee359dad7d7a9b82861"
+            },
+        ],
+        "links": {
+            "self": "http://example.com/identity/v3/credentials",
+            "previous": None,
+            "next": None
+        }
+    }
+
+    def setUp(self):
+        super(TestCredentialsClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = credentials_client.CredentialsClient(fake_auth,
+                                                           'identity',
+                                                           'regionOne')
+
+    def _test_create_credential(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_credential,
+            'tempest.lib.common.rest_client.RestClient.post',
+            self.FAKE_CREATE_CREDENTIAL,
+            bytes_body, status=201)
+
+    def _test_show_credential(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_credential,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_INFO_CREDENTIAL,
+            bytes_body,
+            credential_id="207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f")
+
+    def _test_update_credential(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.update_credential,
+            'tempest.lib.common.rest_client.RestClient.patch',
+            self.FAKE_INFO_CREDENTIAL,
+            bytes_body,
+            credential_id="207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f")
+
+    def _test_list_credentials(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_credentials,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_CREDENTIALS,
+            bytes_body)
+
+    def test_create_credential_with_str_body(self):
+        self._test_create_credential()
+
+    def test_create_credential_with_bytes_body(self):
+        self._test_create_credential(bytes_body=True)
+
+    def test_show_credential_with_str_body(self):
+        self._test_show_credential()
+
+    def test_show_credential_with_bytes_body(self):
+        self._test_show_credential(bytes_body=True)
+
+    def test_update_credential_with_str_body(self):
+        self._test_update_credential()
+
+    def test_update_credential_with_bytes_body(self):
+        self._test_update_credential(bytes_body=True)
+
+    def test_list_credentials_with_str_body(self):
+        self._test_list_credentials()
+
+    def test_list_credentials_with_bytes_body(self):
+        self._test_list_credentials(bytes_body=True)
+
+    def test_delete_credential(self):
+        self.check_service_client_function(
+            self.client.delete_credential,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            credential_id="207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f",
+            status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_groups_client.py b/tempest/tests/lib/services/identity/v3/test_groups_client.py
new file mode 100644
index 0000000..38cf3ae
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_groups_client.py
@@ -0,0 +1,213 @@
+# Copyright 2016 Red Hat, 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.
+
+from tempest.lib.services.identity.v3 import groups_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestGroupsClient(base.BaseServiceTest):
+    FAKE_CREATE_GROUP = {
+        'group': {
+            'description': 'Tempest Group Description',
+            'domain_id': 'TempestDomain',
+            'name': 'Tempest Group',
+        }
+    }
+
+    FAKE_GROUP_INFO = {
+        'group': {
+            'description': 'Tempest Group Description',
+            'domain_id': 'TempestDomain',
+            'id': '6e13e2068cf9466e98950595baf6bb35',
+            'links': {
+                'self': 'http://example.com/identity/v3/groups/' +
+                        '6e13e2068cf9466e98950595baf6bb35'
+            },
+            'name': 'Tempest Group',
+        }
+    }
+
+    FAKE_GROUP_LIST = {
+        'links': {
+            'self': 'http://example.com/identity/v3/groups',
+            'previous': None,
+            'next': None,
+        },
+        'groups': [
+            {
+                'description': 'Tempest Group One Description',
+                'domain_id': 'TempestDomain',
+                'id': '1c92f3453ed34291a074b87493455b8f',
+                'links': {
+                    'self': 'http://example.com/identity/v3/groups/' +
+                            '1c92f3453ed34291a074b87493455b8f'
+                },
+                'name': 'Tempest Group One',
+            },
+            {
+                'description': 'Tempest Group Two Description',
+                'domain_id': 'TempestDomain',
+                'id': 'ce9e7dafed3b4877a7d4466ed730a9ee',
+                'links': {
+                    'self': 'http://example.com/identity/v3/groups/' +
+                            'ce9e7dafed3b4877a7d4466ed730a9ee'
+                },
+                'name': 'Tempest Group Two',
+            },
+        ]
+    }
+
+    FAKE_USER_LIST = {
+        'links': {
+            'self': 'http://example.com/identity/v3/groups/' +
+                    '6e13e2068cf9466e98950595baf6bb35/users',
+            'previous': None,
+            'next': None,
+        },
+        'users': [
+            {
+                'domain_id': 'TempestDomain',
+                'description': 'Tempest Test User One Description',
+                'enabled': True,
+                'id': '642688fa65a84217b86cef3c063de2b9',
+                'name': 'TempestUserOne',
+                'links': {
+                    'self': 'http://example.com/identity/v3/users/' +
+                            '642688fa65a84217b86cef3c063de2b9'
+                }
+            },
+            {
+                'domain_id': 'TempestDomain',
+                'description': 'Tempest Test User Two Description',
+                'enabled': True,
+                'id': '1048ead6f8ef4a859b44ffbce3ac0b52',
+                'name': 'TempestUserTwo',
+                'links': {
+                    'self': 'http://example.com/identity/v3/users/' +
+                            '1048ead6f8ef4a859b44ffbce3ac0b52'
+                }
+            },
+        ]
+    }
+
+    def setUp(self):
+        super(TestGroupsClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = groups_client.GroupsClient(fake_auth, 'identity',
+                                                 'regionOne')
+
+    def _test_create_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_group,
+            'tempest.lib.common.rest_client.RestClient.post',
+            self.FAKE_CREATE_GROUP,
+            bytes_body,
+            status=201,
+        )
+
+    def _test_show_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_group,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_GROUP_INFO,
+            bytes_body,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+        )
+
+    def _test_list_groups(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_groups,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_GROUP_LIST,
+            bytes_body,
+        )
+
+    def _test_update_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.update_group,
+            'tempest.lib.common.rest_client.RestClient.patch',
+            self.FAKE_GROUP_INFO,
+            bytes_body,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+            name='NewName',
+        )
+
+    def _test_list_users_in_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_group_users,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_USER_LIST,
+            bytes_body,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+        )
+
+    def test_create_group_with_string_body(self):
+        self._test_create_group()
+
+    def test_create_group_with_bytes_body(self):
+        self._test_create_group(bytes_body=True)
+
+    def test_show_group_with_string_body(self):
+        self._test_show_group()
+
+    def test_show_group_with_bytes_body(self):
+        self._test_show_group(bytes_body=True)
+
+    def test_list_groups_with_string_body(self):
+        self._test_list_groups()
+
+    def test_list_groups_with_bytes_body(self):
+        self._test_list_groups(bytes_body=True)
+
+    def test_update_group_with_string_body(self):
+        self._test_update_group()
+
+    def test_update_group_with_bytes_body(self):
+        self._test_update_group(bytes_body=True)
+
+    def test_list_users_in_group_with_string_body(self):
+        self._test_list_users_in_group()
+
+    def test_list_users_in_group_with_bytes_body(self):
+        self._test_list_users_in_group(bytes_body=True)
+
+    def test_delete_group(self):
+        self.check_service_client_function(
+            self.client.delete_group,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+            status=204,
+        )
+
+    def test_add_user_to_group(self):
+        self.check_service_client_function(
+            self.client.add_group_user,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            status=204,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+            user_id='642688fa65a84217b86cef3c063de2b9',
+        )
+
+    def test_check_user_in_group(self):
+        self.check_service_client_function(
+            self.client.check_group_user_existence,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            status=204,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+            user_id='642688fa65a84217b86cef3c063de2b9',
+        )
diff --git a/tempest/tests/lib/services/identity/v3/test_identity_client.py b/tempest/tests/lib/services/identity/v3/test_identity_client.py
new file mode 100644
index 0000000..9eaaaaf
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_identity_client.py
@@ -0,0 +1,75 @@
+# Copyright 2016 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.lib.services.identity.v3 import identity_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestIdentityClient(base.BaseServiceTest):
+    FAKE_TOKEN = {
+        "tokens": {
+            "id": "cbc36478b0bd8e67e89",
+            "name": "FakeToken",
+            "type": "token",
+        }
+    }
+
+    FAKE_API_INFO = {
+        "name": "API_info",
+        "type": "API",
+        "description": "test_description"
+    }
+
+    def setUp(self):
+        super(TestIdentityClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = identity_client.IdentityClient(fake_auth,
+                                                     'identity',
+                                                     'regionOne')
+
+    def _test_show_api_description(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_api_description,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_API_INFO,
+            bytes_body)
+
+    def _test_show_token(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_token,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_TOKEN,
+            bytes_body,
+            resp_token="cbc36478b0bd8e67e89")
+
+    def test_show_api_description_with_str_body(self):
+        self._test_show_api_description()
+
+    def test_show_api_description_with_bytes_body(self):
+        self._test_show_api_description(bytes_body=True)
+
+    def test_show_token_with_str_body(self):
+        self._test_show_token()
+
+    def test_show_token_with_bytes_body(self):
+        self._test_show_token(bytes_body=True)
+
+    def test_delete_token(self):
+        self.check_service_client_function(
+            self.client.delete_token,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            resp_token="cbc36478b0bd8e67e89",
+            status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_inherited_roles_client.py b/tempest/tests/lib/services/identity/v3/test_inherited_roles_client.py
new file mode 100644
index 0000000..9da3cce
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_inherited_roles_client.py
@@ -0,0 +1,220 @@
+# Copyright 2016 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.lib.services.identity.v3 import inherited_roles_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestInheritedRolesClient(base.BaseServiceTest):
+    FAKE_LIST_INHERITED_ROLES = {
+        "roles": [
+            {
+                "id": "1",
+                "name": "test",
+                "links": "example.com"
+            },
+            {
+                "id": "2",
+                "name": "test2",
+                "links": "example.com"
+            }
+        ]
+    }
+
+    def setUp(self):
+        super(TestInheritedRolesClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = inherited_roles_client.InheritedRolesClient(
+            fake_auth, 'identity', 'regionOne')
+
+    def _test_create_inherited_role_on_domains_user(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_inherited_role_on_domains_user,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            bytes_body,
+            domain_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def _test_list_inherited_project_role_for_user_on_domain(
+        self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_inherited_project_role_for_user_on_domain,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_INHERITED_ROLES,
+            bytes_body,
+            domain_id="b344506af7644f6794d9cb316600b020",
+            user_id="123")
+
+    def _test_create_inherited_role_on_domains_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_inherited_role_on_domains_group,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            bytes_body,
+            domain_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def _test_list_inherited_project_role_for_group_on_domain(
+        self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_inherited_project_role_for_group_on_domain,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_INHERITED_ROLES,
+            bytes_body,
+            domain_id="b344506af7644f6794d9cb316600b020",
+            group_id="123")
+
+    def _test_create_inherited_role_on_projects_user(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_inherited_role_on_projects_user,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            bytes_body,
+            project_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def _test_create_inherited_role_on_projects_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_inherited_role_on_projects_group,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            bytes_body,
+            project_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_create_inherited_role_on_domains_user_with_str_body(self):
+        self._test_create_inherited_role_on_domains_user()
+
+    def test_create_inherited_role_on_domains_user_with_bytes_body(self):
+        self._test_create_inherited_role_on_domains_user(bytes_body=True)
+
+    def test_create_inherited_role_on_domains_group_with_str_body(self):
+        self._test_create_inherited_role_on_domains_group()
+
+    def test_create_inherited_role_on_domains_group_with_bytes_body(self):
+        self._test_create_inherited_role_on_domains_group(bytes_body=True)
+
+    def test_create_inherited_role_on_projects_user_with_str_body(self):
+        self._test_create_inherited_role_on_projects_user()
+
+    def test_create_inherited_role_on_projects_group_with_bytes_body(self):
+        self._test_create_inherited_role_on_projects_group(bytes_body=True)
+
+    def test_list_inherited_project_role_for_user_on_domain_with_str_body(
+        self):
+        self._test_list_inherited_project_role_for_user_on_domain()
+
+    def test_list_inherited_project_role_for_user_on_domain_with_bytes_body(
+        self):
+        self._test_list_inherited_project_role_for_user_on_domain(
+            bytes_body=True)
+
+    def test_list_inherited_project_role_for_group_on_domain_with_str_body(
+        self):
+        self._test_list_inherited_project_role_for_group_on_domain()
+
+    def test_list_inherited_project_role_for_group_on_domain_with_bytes_body(
+        self):
+        self._test_list_inherited_project_role_for_group_on_domain(
+            bytes_body=True)
+
+    def test_delete_inherited_role_from_user_on_domain(self):
+        self.check_service_client_function(
+            self.client.delete_inherited_role_from_user_on_domain,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            domain_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_check_user_inherited_project_role_on_domain(self):
+        self.check_service_client_function(
+            self.client.check_user_inherited_project_role_on_domain,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            domain_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_delete_inherited_role_from_group_on_domain(self):
+        self.check_service_client_function(
+            self.client.delete_inherited_role_from_group_on_domain,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            domain_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_check_group_inherited_project_role_on_domain(self):
+        self.check_service_client_function(
+            self.client.check_group_inherited_project_role_on_domain,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            domain_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_delete_inherited_role_from_user_on_project(self):
+        self.check_service_client_function(
+            self.client.delete_inherited_role_from_user_on_project,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            project_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_check_user_has_flag_on_inherited_to_project(self):
+        self.check_service_client_function(
+            self.client.check_user_has_flag_on_inherited_to_project,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            project_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_delete_inherited_role_from_group_on_project(self):
+        self.check_service_client_function(
+            self.client.delete_inherited_role_from_group_on_project,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            project_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_check_group_has_flag_on_inherited_to_project(self):
+        self.check_service_client_function(
+            self.client.check_group_has_flag_on_inherited_to_project,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            project_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_roles_client.py b/tempest/tests/lib/services/identity/v3/test_roles_client.py
new file mode 100644
index 0000000..bad1ef9
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_roles_client.py
@@ -0,0 +1,313 @@
+# Copyright 2016 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.lib.services.identity.v3 import roles_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestRolesClient(base.BaseServiceTest):
+    FAKE_ROLE_INFO = {
+        "role": {
+            "domain_id": "1",
+            "id": "1",
+            "name": "test",
+            "links": "example.com"
+        }
+    }
+
+    FAKE_LIST_ROLES = {
+        "roles": [
+            {
+                "domain_id": "1",
+                "id": "1",
+                "name": "test",
+                "links": "example.com"
+            },
+            {
+                "domain_id": "2",
+                "id": "2",
+                "name": "test2",
+                "links": "example.com"
+            }
+        ]
+    }
+
+    def setUp(self):
+        super(TestRolesClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = roles_client.RolesClient(fake_auth,
+                                               'identity', 'regionOne')
+
+    def _test_create_role(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_role,
+            'tempest.lib.common.rest_client.RestClient.post',
+            self.FAKE_ROLE_INFO,
+            bytes_body,
+            domain_id="1",
+            name="test",
+            status=201)
+
+    def _test_show_role(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_role,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_ROLE_INFO,
+            bytes_body,
+            role_id="1")
+
+    def _test_list_roles(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_roles,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_ROLES,
+            bytes_body)
+
+    def _test_update_role(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.update_role,
+            'tempest.lib.common.rest_client.RestClient.patch',
+            self.FAKE_ROLE_INFO,
+            bytes_body,
+            role_id="1",
+            name="test")
+
+    def _test_create_user_role_on_project(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_user_role_on_project,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            bytes_body,
+            project_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def _test_create_user_role_on_domain(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_user_role_on_domain,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            bytes_body,
+            domain_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def _test_list_user_roles_on_project(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_user_roles_on_project,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_ROLES,
+            bytes_body,
+            project_id="b344506af7644f6794d9cb316600b020",
+            user_id="123")
+
+    def _test_list_user_roles_on_domain(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_user_roles_on_domain,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_ROLES,
+            bytes_body,
+            domain_id="b344506af7644f6794d9cb316600b020",
+            user_id="123")
+
+    def _test_create_group_role_on_project(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_group_role_on_project,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            bytes_body,
+            project_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def _test_create_group_role_on_domain(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_group_role_on_domain,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            bytes_body,
+            domain_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def _test_list_group_roles_on_project(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_group_roles_on_project,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_ROLES,
+            bytes_body,
+            project_id="b344506af7644f6794d9cb316600b020",
+            group_id="123")
+
+    def _test_list_group_roles_on_domain(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_group_roles_on_domain,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_ROLES,
+            bytes_body,
+            domain_id="b344506af7644f6794d9cb316600b020",
+            group_id="123")
+
+    def test_create_role_with_str_body(self):
+        self._test_create_role()
+
+    def test_create_role_with_bytes_body(self):
+        self._test_create_role(bytes_body=True)
+
+    def test_show_role_with_str_body(self):
+        self._test_show_role()
+
+    def test_show_role_with_bytes_body(self):
+        self._test_show_role(bytes_body=True)
+
+    def test_list_roles_with_str_body(self):
+        self._test_list_roles()
+
+    def test_list_roles_with_bytes_body(self):
+        self._test_list_roles(bytes_body=True)
+
+    def test_update_role_with_str_body(self):
+        self._test_update_role()
+
+    def test_update_role_with_bytes_body(self):
+        self._test_update_role(bytes_body=True)
+
+    def test_delete_role(self):
+        self.check_service_client_function(
+            self.client.delete_role,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            role_id="1",
+            status=204)
+
+    def test_create_user_role_on_project_with_str_body(self):
+        self._test_create_user_role_on_project()
+
+    def test_create_user_role_on_project_with_bytes_body(self):
+        self._test_create_user_role_on_project(bytes_body=True)
+
+    def test_create_user_role_on_domain_with_str_body(self):
+        self._test_create_user_role_on_domain()
+
+    def test_create_user_role_on_domain_with_bytes_body(self):
+        self._test_create_user_role_on_domain(bytes_body=True)
+
+    def test_create_group_role_on_domain_with_str_body(self):
+        self._test_create_group_role_on_domain()
+
+    def test_create_group_role_on_domain_with_bytes_body(self):
+        self._test_create_group_role_on_domain(bytes_body=True)
+
+    def test_list_user_roles_on_project_with_str_body(self):
+        self._test_list_user_roles_on_project()
+
+    def test_list_user_roles_on_project_with_bytes_body(self):
+        self._test_list_user_roles_on_project(bytes_body=True)
+
+    def test_list_user_roles_on_domain_with_str_body(self):
+        self._test_list_user_roles_on_domain()
+
+    def test_list_user_roles_on_domain_with_bytes_body(self):
+        self._test_list_user_roles_on_domain(bytes_body=True)
+
+    def test_list_group_roles_on_domain_with_str_body(self):
+        self._test_list_group_roles_on_domain()
+
+    def test_list_group_roles_on_domain_with_bytes_body(self):
+        self._test_list_group_roles_on_domain(bytes_body=True)
+
+    def test_delete_role_from_user_on_project(self):
+        self.check_service_client_function(
+            self.client.delete_role_from_user_on_project,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            project_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_delete_role_from_user_on_domain(self):
+        self.check_service_client_function(
+            self.client.delete_role_from_user_on_domain,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            domain_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_delete_role_from_group_on_project(self):
+        self.check_service_client_function(
+            self.client.delete_role_from_group_on_project,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            project_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_delete_role_from_group_on_domain(self):
+        self.check_service_client_function(
+            self.client.delete_role_from_group_on_domain,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            domain_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_check_user_role_existence_on_project(self):
+        self.check_service_client_function(
+            self.client.check_user_role_existence_on_project,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            project_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_check_user_role_existence_on_domain(self):
+        self.check_service_client_function(
+            self.client.check_user_role_existence_on_domain,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            domain_id="b344506af7644f6794d9cb316600b020",
+            user_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_check_role_from_group_on_project_existence(self):
+        self.check_service_client_function(
+            self.client.check_role_from_group_on_project_existence,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            project_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
+
+    def test_check_role_from_group_on_domain_existence(self):
+        self.check_service_client_function(
+            self.client.check_role_from_group_on_domain_existence,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            domain_id="b344506af7644f6794d9cb316600b020",
+            group_id="123",
+            role_id="1234",
+            status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_trusts_client.py b/tempest/tests/lib/services/identity/v3/test_trusts_client.py
new file mode 100644
index 0000000..a1ca020
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_trusts_client.py
@@ -0,0 +1,150 @@
+# Copyright 2016 Red Hat, 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.
+
+from tempest.lib.services.identity.v3 import trusts_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestTrustsClient(base.BaseServiceTest):
+    FAKE_CREATE_TRUST = {
+        "trust": {
+            "expires_at": "2013-02-27T18:30:59.999999Z",
+            "impersonation": True,
+            "allow_redelegation": True,
+            "project_id": "ddef321",
+            "roles": [
+                {
+                    "name": "member"
+                    }
+                ],
+            "trustee_user_id": "86c0d5",
+            "trustor_user_id": "a0fdfd"
+            }
+        }
+
+    FAKE_LIST_TRUSTS = {
+        "trusts": [
+            {
+                "id": "1ff900",
+                "expires_at":
+                "2013-02-27T18:30:59.999999Z",
+                "impersonation": True,
+                "links": {
+                    "self":
+                    "http://example.com/identity/v3/OS-TRUST/trusts/1ff900"
+                    },
+                "project_id": "0f1233",
+                "trustee_user_id": "86c0d5",
+                "trustor_user_id": "a0fdfd"
+                },
+            {
+                "id": "f4513a",
+                "impersonation": False,
+                "links": {
+                    "self":
+                    "http://example.com/identity/v3/OS-TRUST/trusts/f45513a"
+                    },
+                "project_id": "0f1233",
+                "trustee_user_id": "86c0d5",
+                "trustor_user_id": "3cd2ce"
+                }
+            ]
+        }
+
+    FAKE_TRUST_INFO = {
+        "trust": {
+            "id": "987fe8",
+            "expires_at": "2013-02-27T18:30:59.999999Z",
+            "impersonation": True,
+            "links": {
+                "self":
+                "http://example.com/identity/v3/OS-TRUST/trusts/987fe8"
+                },
+            "roles": [
+                {
+                    "id": "ed7b78",
+                    "links": {
+                        "self":
+                        "http://example.com/identity/v3/roles/ed7b78"
+                        },
+                    "name": "member"
+                    }
+                ],
+            "roles_links": {
+                "next": None,
+                "previous": None,
+                "self":
+                "http://example.com/identity/v3/OS-TRUST/trusts/1ff900/roles"
+                },
+            "project_id": "0f1233",
+            "trustee_user_id": "be34d1",
+            "trustor_user_id": "56ae32"
+            }
+        }
+
+    def setUp(self):
+        super(TestTrustsClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = trusts_client.TrustsClient(fake_auth, 'identity',
+                                                 'regionOne')
+
+    def _test_create_trust(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_trust,
+            'tempest.lib.common.rest_client.RestClient.post',
+            self.FAKE_CREATE_TRUST,
+            bytes_body,
+            status=201)
+
+    def _test_show_trust(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_trust,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_TRUST_INFO,
+            bytes_body,
+            trust_id="1ff900")
+
+    def _test_list_trusts(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_trusts,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_TRUSTS,
+            bytes_body)
+
+    def test_create_trust_with_str_body(self):
+        self._test_create_trust()
+
+    def test_create_trust_with_bytes_body(self):
+        self._test_create_trust(bytes_body=True)
+
+    def test_show_trust_with_str_body(self):
+        self._test_show_trust()
+
+    def test_show_trust_with_bytes_body(self):
+        self._test_show_trust(bytes_body=True)
+
+    def test_list_trusts_with_str_body(self):
+        self._test_list_trusts()
+
+    def test_list_trusts_with_bytes_body(self):
+        self._test_list_trusts(bytes_body=True)
+
+    def test_delete_trust(self):
+        self.check_service_client_function(
+            self.client.delete_trust,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            trust_id="1ff900",
+            status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_users_client.py b/tempest/tests/lib/services/identity/v3/test_users_client.py
new file mode 100644
index 0000000..5b572f5
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_users_client.py
@@ -0,0 +1,205 @@
+# Copyright 2016 Red Hat, 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.
+
+from tempest.lib.services.identity.v3 import users_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestUsersClient(base.BaseServiceTest):
+    FAKE_CREATE_USER = {
+        'user': {
+            'default_project_id': '95f8c3f8e7b54409a418fc30717f9ae0',
+            'domain_id': '8347b31afc3545c4b311cb4cce788a08',
+            'enabled': True,
+            'name': 'Tempest User',
+            'password': 'TempestPassword',
+        }
+    }
+
+    FAKE_USER_INFO = {
+        'user': {
+            'default_project_id': '95f8c3f8e7b54409a418fc30717f9ae0',
+            'domain_id': '8347b31afc3545c4b311cb4cce788a08',
+            'enabled': True,
+            'id': '817fb3c23fd7465ba6d7fe1b1320121d',
+            'links': {
+                'self': 'http://example.com/identity',
+            },
+            'name': 'Tempest User',
+            'password_expires_at': '2016-11-06T15:32:17.000000',
+        }
+    }
+
+    FAKE_USER_LIST = {
+        'links': {
+            'next': None,
+            'previous': None,
+            'self': 'http://example.com/identity/v3/users',
+        },
+        'users': [
+            {
+                'domain_id': 'TempestDomain',
+                'enabled': True,
+                'id': '817fb3c23fd7465ba6d7fe1b1320121d',
+                'links': {
+                    'self': 'http://example.com/identity/v3/users/' +
+                            '817fb3c23fd7465ba6d7fe1b1320121d',
+                },
+                'name': 'Tempest User',
+                'password_expires_at': '2016-11-06T15:32:17.000000',
+            },
+            {
+                'domain_id': 'TempestDomain',
+                'enabled': True,
+                'id': 'bdbfb1e2f1344be197e90a778379cca1',
+                'links': {
+                    'self': 'http://example.com/identity/v3/users/' +
+                            'bdbfb1e2f1344be197e90a778379cca1',
+                },
+                'name': 'Tempest User',
+                'password_expires_at': None,
+            },
+        ]
+    }
+
+    FAKE_GROUP_LIST = {
+        'links': {
+            'self': 'http://example.com/identity/v3/groups',
+            'previous': None,
+            'next': None,
+        },
+        'groups': [
+            {
+                'description': 'Tempest Group One Description',
+                'domain_id': 'TempestDomain',
+                'id': '1c92f3453ed34291a074b87493455b8f',
+                'links': {
+                    'self': 'http://example.com/identity/v3/groups/' +
+                            '1c92f3453ed34291a074b87493455b8f'
+                },
+                'name': 'Tempest Group One',
+            },
+            {
+                'description': 'Tempest Group Two Description',
+                'domain_id': 'TempestDomain',
+                'id': 'ce9e7dafed3b4877a7d4466ed730a9ee',
+                'links': {
+                    'self': 'http://example.com/identity/v3/groups/' +
+                            'ce9e7dafed3b4877a7d4466ed730a9ee'
+                },
+                'name': 'Tempest Group Two',
+            },
+        ]
+    }
+
+    def setUp(self):
+        super(TestUsersClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = users_client.UsersClient(fake_auth, 'identity',
+                                               'regionOne')
+
+    def _test_create_user(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_user,
+            'tempest.lib.common.rest_client.RestClient.post',
+            self.FAKE_CREATE_USER,
+            bytes_body,
+            status=201,
+        )
+
+    def _test_show_user(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_user,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_USER_INFO,
+            bytes_body,
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+        )
+
+    def _test_list_users(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_users,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_USER_LIST,
+            bytes_body,
+        )
+
+    def _test_update_user(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.update_user,
+            'tempest.lib.common.rest_client.RestClient.patch',
+            self.FAKE_USER_INFO,
+            bytes_body,
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+            name='NewName',
+        )
+
+    def _test_list_user_groups(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_user_groups,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_GROUP_LIST,
+            bytes_body,
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+        )
+
+    def test_create_user_with_string_body(self):
+        self._test_create_user()
+
+    def test_create_user_with_bytes_body(self):
+        self._test_create_user(bytes_body=True)
+
+    def test_show_user_with_string_body(self):
+        self._test_show_user()
+
+    def test_show_user_with_bytes_body(self):
+        self._test_show_user(bytes_body=True)
+
+    def test_list_users_with_string_body(self):
+        self._test_list_users()
+
+    def test_list_users_with_bytes_body(self):
+        self._test_list_users(bytes_body=True)
+
+    def test_update_user_with_string_body(self):
+        self._test_update_user()
+
+    def test_update_user_with_bytes_body(self):
+        self._test_update_user(bytes_body=True)
+
+    def test_list_user_groups_with_string_body(self):
+        self._test_list_user_groups()
+
+    def test_list_user_groups_with_bytes_body(self):
+        self._test_list_user_groups(bytes_body=True)
+
+    def test_delete_user(self):
+        self.check_service_client_function(
+            self.client.delete_user,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+            status=204,
+        )
+
+    def test_change_user_password(self):
+        self.check_service_client_function(
+            self.client.update_user_password,
+            'tempest.lib.common.rest_client.RestClient.post',
+            {},
+            status=204,
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+            password='NewTempestPassword',
+            original_password='OldTempestPassword')
diff --git a/tempest/tests/negative/test_negative_generators.py b/tempest/tests/negative/test_negative_generators.py
index 2e45ef7..7e1ee2c 100644
--- a/tempest/tests/negative/test_negative_generators.py
+++ b/tempest/tests/negative/test_negative_generators.py
@@ -107,7 +107,7 @@
 
     def _validate_result(self, valid_schema, invalid_schema):
         for k, v in six.iteritems(valid_schema):
-            self.assertTrue(k in invalid_schema)
+            self.assertIn(k, invalid_schema)
 
     def test_generator_mandatory_functions(self):
         for data_type in self.types:
diff --git a/tempest/tests/services/object_storage/test_object_client.py b/tempest/tests/services/object_storage/test_object_client.py
index cd8c8f1..cc1dc1a 100644
--- a/tempest/tests/services/object_storage/test_object_client.py
+++ b/tempest/tests/services/object_storage/test_object_client.py
@@ -20,7 +20,7 @@
 from tempest.lib import exceptions
 from tempest.services.object_storage import object_client
 from tempest.tests import base
-from tempest.tests import fake_auth_provider
+from tempest.tests.lib import fake_auth_provider
 
 
 class TestObjectClient(base.TestCase):
diff --git a/tempest/tests/test_negative_rest_client.py b/tempest/tests/test_negative_rest_client.py
index 9d9c20f..05f9f3e 100644
--- a/tempest/tests/test_negative_rest_client.py
+++ b/tempest/tests/test_negative_rest_client.py
@@ -21,8 +21,8 @@
 from tempest.common import negative_rest_client
 from tempest import config
 from tempest.tests import base
-from tempest.tests import fake_auth_provider
 from tempest.tests import fake_config
+from tempest.tests.lib import fake_auth_provider
 
 
 class TestNegativeRestClient(base.TestCase):
diff --git a/test-requirements.txt b/test-requirements.txt
index 04c3d6d..2d15daa 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,9 +3,9 @@
 # process, which may cause wedges in the gate later.
 hacking<0.12,>=0.11.0 # Apache-2.0
 # needed for doc build
-sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
+sphinx!=1.3b1,<1.4,>=1.2.1 # BSD
 python-subunit>=0.0.18 # Apache-2.0/BSD
-oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
+oslosphinx>=4.7.0 # Apache-2.0
 reno>=1.8.0 # Apache2
 mock>=2.0 # BSD
 coverage>=3.6 # Apache-2.0
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
index 03dbd9b..03e838e 100644
--- a/tools/generate-tempest-plugins-list.py
+++ b/tools/generate-tempest-plugins-list.py
@@ -48,6 +48,8 @@
 
 
 def has_tempest_plugin(proj):
+    if proj.startswith('openstack/deb-'):
+        return False
     r = requests.get(
         "https://git.openstack.org/cgit/%s/plain/setup.cfg" % proj)
     p = re.compile('^tempest\.test_plugins', re.M)
diff --git a/tools/pretty_tox.sh b/tools/pretty_tox.sh
index fb4e6d5..0b83b91 100755
--- a/tools/pretty_tox.sh
+++ b/tools/pretty_tox.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash
 
+echo "WARNING: This script is deprecated and will be removed in the near future. Please migrate to tempest run or another method of launching a test runner"
+
 set -o pipefail
 
 TESTRARGS=$1
diff --git a/tools/pretty_tox_serial.sh b/tools/pretty_tox_serial.sh
index e0fca0f..1f8204e 100755
--- a/tools/pretty_tox_serial.sh
+++ b/tools/pretty_tox_serial.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash
 
+echo "WARNING: This script is deprecated and will be removed in the near future. Please migrate to tempest run or another method of launching a test runner"
+
 set -o pipefail
 
 TESTRARGS=$@
diff --git a/tox.ini b/tox.ini
index a621492..7096e60 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = pep8,py35,py34,py27
+envlist = pep8,py35,py34,py27,pip-check-reqs
 minversion = 2.3.1
 skipsdist = True
 
@@ -16,6 +16,7 @@
 setenv =
     VIRTUAL_ENV={envdir}
     OS_TEST_PATH=./tempest/tests
+    PYTHONWARNINGS=default::DeprecationWarning
 passenv = OS_STDOUT_CAPTURE OS_STDERR_CAPTURE OS_TEST_TIMEOUT OS_TEST_LOCK_PATH OS_TEST_PATH TEMPEST_CONFIG TEMPEST_CONFIG_DIR http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY
 usedevelop = True
 install_command = pip install -U {opts} {packages}
@@ -44,7 +45,7 @@
 deps = {[tempestenv]deps}
 commands =
     find . -type f -name "*.pyc" -delete
-    bash tools/pretty_tox.sh '{posargs}'
+    tempest run --regex {posargs}
 
 [testenv:ostestr]
 sitepackages = {[tempestenv]sitepackages}
@@ -66,7 +67,7 @@
 deps = {[tempestenv]deps}
 commands =
     find . -type f -name "*.pyc" -delete
-    bash tools/pretty_tox.sh '{posargs}'
+    tempest run --regex {posargs}
 
 [testenv:full]
 envdir = .tox/tempest
@@ -77,7 +78,7 @@
 # See the testrepository bug: https://bugs.launchpad.net/testrepository/+bug/1208610
 commands =
     find . -type f -name "*.pyc" -delete
-    bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)) {posargs}'
+    tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))' {posargs}
 
 [testenv:full-serial]
 envdir = .tox/tempest
@@ -88,7 +89,7 @@
 # See the testrepository bug: https://bugs.launchpad.net/testrepository/+bug/1208610
 commands =
     find . -type f -name "*.pyc" -delete
-    bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)) {posargs}'
+    tempest run --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))' {posargs}
 
 [testenv:smoke]
 envdir = .tox/tempest
@@ -97,7 +98,7 @@
 deps = {[tempestenv]deps}
 commands =
     find . -type f -name "*.pyc" -delete
-    bash tools/pretty_tox.sh '\[.*\bsmoke\b.*\] {posargs}'
+    tempest run --regex '\[.*\bsmoke\b.*\]' {posargs}
 
 [testenv:smoke-serial]
 envdir = .tox/tempest
@@ -109,7 +110,7 @@
 # job would fail if we moved it to parallel.
 commands =
     find . -type f -name "*.pyc" -delete
-    bash tools/pretty_tox_serial.sh '\[.*\bsmoke\b.*\] {posargs}'
+    tempest run --serial --regex '\[.*\bsmoke\b.*\]' {posargs}
 
 [testenv:stress]
 envdir = .tox/tempest
@@ -153,7 +154,18 @@
 # Skipped because of new hacking 0.9: H405
 ignore = E125,E123,E129
 show-source = True
-exclude = .git,.venv,.tox,dist,doc,openstack,*egg
+exclude = .git,.venv,.tox,dist,doc,*egg
 
 [testenv:releasenotes]
 commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
+
+[testenv:pip-check-reqs]
+# Do not install test-requirements as that will pollute the virtualenv for
+# determining missing packages.
+# This also means that pip-check-reqs must be installed separately, outside
+# of the requirements.txt files
+deps = pip_check_reqs
+       -r{toxinidir}/requirements.txt
+commands=
+    pip-extra-reqs -d --ignore-file=tempest/tests/* tempest
+    pip-missing-reqs -d --ignore-file=tempest/tests/* tempest