Merge "Use an instance method instead of class method"
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 127613d..2edaddb 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -14,6 +14,7 @@
 import sys
 import os
 import subprocess
+import warnings
 
 # Build the plugin registry
 def build_plugin_registry(app):
@@ -140,9 +141,13 @@
 # using the given strftime format.
 git_cmd = ["git", "log", "--pretty=format:'%ad, commit %h'", "--date=local",
    "-n1"]
-html_last_updated_fmt = subprocess.Popen(git_cmd,
-                                         stdout=subprocess.PIPE).\
-                                         communicate()[0]
+try:
+    html_last_updated_fmt = subprocess.Popen(git_cmd,
+                                             stdout=subprocess.PIPE).\
+                                             communicate()[0]
+except Exception:
+    warnings.warn('Cannot get last updated time from git repository. '
+                  'Not setting "html_last_updated_fmt".')
 
 # If true, SmartyPants will be used to convert quotes and dashes to
 # typographically correct entities.
diff --git a/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
new file mode 100644
index 0000000..9e828f6
--- /dev/null
+++ b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
@@ -0,0 +1,15 @@
+---
+features:
+  - |
+    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/move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml b/releasenotes/notes/move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml
new file mode 100644
index 0000000..543cf7b
--- /dev/null
+++ b/releasenotes/notes/move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml
@@ -0,0 +1,5 @@
+---
+deprecations:
+  - The ``call_until_true`` function is moved from the ``tempest.test`` module
+   to the ``tempest.lib.common.utils.test_utils`` module. Backward
+   compatibilty is preserved until Ocata.
diff --git a/requirements.txt b/requirements.txt
index d698cda..a773d16 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -22,3 +22,4 @@
 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
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index ac1bfee..fbcc1d1 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -25,8 +25,6 @@
 class AggregatesAdminTestJSON(base.BaseV2ComputeAdminTest):
     """Tests Aggregates API that require admin privileges"""
 
-    _host_key = 'OS-EXT-SRV-ATTR:host'
-
     @classmethod
     def setup_clients(cls):
         super(AggregatesAdminTestJSON, cls).setup_clients()
@@ -223,4 +221,4 @@
                                          availability_zone=az_name,
                                          wait_until='ACTIVE')
         body = admin_servers_client.show_server(server['id'])['server']
-        self.assertEqual(self.host, body[self._host_key])
+        self.assertEqual(self.host, body['OS-EXT-SRV-ATTR:host'])
diff --git a/tempest/api/compute/admin/test_auto_allocate_network.py b/tempest/api/compute/admin/test_auto_allocate_network.py
index 052c17d..ee8ed14 100644
--- a/tempest/api/compute/admin/test_auto_allocate_network.py
+++ b/tempest/api/compute/admin/test_auto_allocate_network.py
@@ -16,6 +16,7 @@
 
 from tempest.api.compute import base
 from tempest.common import compute
+from tempest.common import credentials_factory as credentials
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
@@ -45,6 +46,11 @@
     @classmethod
     def skip_checks(cls):
         super(AutoAllocateNetworkTest, cls).skip_checks()
+        identity_version = cls.get_identity_version()
+        if not credentials.is_admin_available(
+                identity_version=identity_version):
+            msg = "Missing Identity Admin API credentials in configuration."
+            raise cls.skipException(msg)
         if not CONF.service_available.neutron:
             raise cls.skipException('Neutron is required')
         if not test.is_extension_enabled('auto-allocated-topology', 'network'):
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index dd7beaa..18a6afc 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -26,7 +26,6 @@
 
 
 class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
-    _host_key = 'OS-EXT-SRV-ATTR:host'
     max_microversion = '2.24'
     block_migration = None
 
@@ -63,7 +62,7 @@
         return body
 
     def _get_host_for_server(self, server_id):
-        return self._get_server_details(server_id)[self._host_key]
+        return self._get_server_details(server_id)['OS-EXT-SRV-ATTR:host']
 
     def _migrate_server_to(self, server_id, dest_host, volume_backed=False):
         kwargs = dict()
@@ -157,7 +156,7 @@
         target_host = self._get_host_other_than(actual_host)
 
         volume = self.volumes_client.create_volume(
-            display_name='test')['volume']
+            size=CONF.volume.volume_size, display_name='test')['volume']
 
         waiters.wait_for_volume_status(self.volumes_client,
                                        volume['id'], 'available')
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 dd4a533..aabb40c 100755
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -24,8 +24,6 @@
 class ServersAdminTestJSON(base.BaseV2ComputeAdminTest):
     """Tests Servers API using admin privileges"""
 
-    _host_key = 'OS-EXT-SRV-ATTR:host'
-
     @classmethod
     def setup_clients(cls):
         super(ServersAdminTestJSON, cls).setup_clients()
@@ -47,13 +45,6 @@
                                         wait_until='ACTIVE')
         cls.s2_id = server['id']
 
-    @test.idempotent_id('51717b38-bdc1-458b-b636-1cf82d99f62f')
-    def test_list_servers_by_admin(self):
-        # Listing servers by admin user returns empty list by default
-        body = self.client.list_servers(detail=True)
-        servers = body['servers']
-        self.assertEqual([], servers)
-
     @test.idempotent_id('06f960bb-15bb-48dc-873d-f96e89be7870')
     def test_list_servers_filter_by_error_status(self):
         # Filter the list of servers by server error status
@@ -77,6 +68,19 @@
         servers = body['servers']
         self.assertEqual([], servers)
 
+    @test.idempotent_id('51717b38-bdc1-458b-b636-1cf82d99f62f')
+    def test_list_servers_by_admin(self):
+        # Listing servers by admin user returns a list which doesn't
+        # contain the other tenants' server by default
+        body = self.client.list_servers(detail=True)
+        servers = body['servers']
+
+        # This case is for the test environments which contain
+        # the existing servers before testing
+        servers_name = [server['name'] for server in servers]
+        self.assertNotIn(self.s1_name, servers_name)
+        self.assertNotIn(self.s2_name, servers_name)
+
     @test.idempotent_id('9f5579ae-19b4-4985-a091-2a5d56106580')
     def test_list_servers_by_admin_with_all_tenants(self):
         # Listing servers by admin user with all tenants parameter
@@ -121,7 +125,7 @@
         self.addCleanup(self.client.delete_server, test_server['id'])
         server = self.client.show_server(test_server['id'])['server']
         self.assertEqual(server['status'], 'ACTIVE')
-        hostname = server[self._host_key]
+        hostname = server['OS-EXT-SRV-ATTR:host']
         params = {'host': hostname}
         body = self.client.list_servers(**params)
         servers = body['servers']
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage.py b/tempest/api/compute/admin/test_simple_tenant_usage.py
index a4ed8dc..dbc22e0 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage.py
@@ -16,6 +16,7 @@
 import datetime
 
 from tempest.api.compute import base
+from tempest.lib.common.utils import test_utils
 from tempest.lib import exceptions as e
 from tempest import test
 
@@ -59,8 +60,8 @@
                 return True
             except e.InvalidHTTPResponseBody:
                 return False
-        self.assertEqual(test.call_until_true(is_valid, duration, 1), True,
-                         "%s not return valid response in %s secs" % (
+        self.assertEqual(test_utils.call_until_true(is_valid, duration, 1),
+                         True, "%s not return valid response in %s secs" % (
                              func.__name__, duration))
         return self.resp
 
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/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_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index baa4f9a..cd90473 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,
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/test_live_block_migration_negative.py b/tempest/api/compute/test_live_block_migration_negative.py
index dc57396..ffd274f 100644
--- a/tempest/api/compute/test_live_block_migration_negative.py
+++ b/tempest/api/compute/test_live_block_migration_negative.py
@@ -24,8 +24,6 @@
 
 
 class LiveBlockMigrationNegativeTestJSON(base.BaseV2ComputeAdminTest):
-    _host_key = 'OS-EXT-SRV-ATTR:host'
-
     @classmethod
     def skip_checks(cls):
         super(LiveBlockMigrationNegativeTestJSON, cls).skip_checks()
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index a5c303c..ff5dc49 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -57,124 +57,105 @@
             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_and_attach(self, shelve_server=False):
+    def _create_server(self):
         # Start a server and wait for it to become ready
-        self.admin_pass = self.image_ssh_password
-        self.server = self.create_test_server(
+        server = self.create_test_server(
             validatable=True,
             wait_until='ACTIVE',
-            adminPass=self.admin_pass)
+            adminPass=self.image_ssh_password)
 
         # Record addresses so that we can ssh later
-        self.server['addresses'] = self.servers_client.list_addresses(
-            self.server['id'])['addresses']
+        server['addresses'] = self.servers_client.list_addresses(
+            server['id'])['addresses']
+        return server
 
+    def _create_and_attach_volume(self, server):
         # Create a volume and wait for it to become ready
-        self.volume = self.volumes_client.create_volume(
+        volume = self.volumes_client.create_volume(
             size=CONF.volume.volume_size, display_name='test')['volume']
-        self.addCleanup(self._delete_volume)
+        self.addCleanup(self.delete_volume, volume['id'])
         waiters.wait_for_volume_status(self.volumes_client,
-                                       self.volume['id'], 'available')
-
-        if shelve_server:
-            if CONF.validation.run_validation:
-                # NOTE(andreaf) If we are going to shelve a server, we should
-                # check first whether the server is ssh-able. Otherwise we
-                # won't be able to distinguish failures introduced by shelve
-                # from pre-existing ones. Also it's good to wait for cloud-init
-                # to be done and sshd server to be running before shelving to
-                # avoid breaking the VM
-                linux_client = remote_client.RemoteClient(
-                    self.get_server_ip(self.server),
-                    self.image_ssh_user,
-                    self.admin_pass,
-                    self.validation_resources['keypair']['private_key'])
-                linux_client.validate_authentication()
-
-            # If validation went ok, or it was skipped, shelve the server
-            compute.shelve_server(self.servers_client, self.server['id'])
+                                       volume['id'], 'available')
 
         # Attach the volume to the server
         self.attachment = self.servers_client.attach_volume(
-            self.server['id'],
-            volumeId=self.volume['id'],
+            server['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, self.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.
-        self._create_and_attach()
+        server = self._create_server()
+        volume = self._create_and_attach_volume(server)
 
-        self.servers_client.stop_server(self.server['id'])
-        waiters.wait_for_server_status(self.servers_client, self.server['id'],
+        self.servers_client.stop_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
                                        'SHUTOFF')
 
-        self.servers_client.start_server(self.server['id'])
-        waiters.wait_for_server_status(self.servers_client, self.server['id'],
+        self.servers_client.start_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
                                        'ACTIVE')
 
         if CONF.validation.run_validation:
             linux_client = remote_client.RemoteClient(
-                self.get_server_ip(self.server),
+                self.get_server_ip(server),
                 self.image_ssh_user,
-                self.admin_pass,
+                self.image_ssh_password,
                 self.validation_resources['keypair']['private_key'],
-                server=self.server,
+                server=server,
                 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(self.server['id'], self.volume['id'])
+        self._detach(server['id'], volume['id'])
         self.attachment = None
-        self.servers_client.stop_server(self.server['id'])
-        waiters.wait_for_server_status(self.servers_client, self.server['id'],
+        self.servers_client.stop_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
                                        'SHUTOFF')
 
-        self.servers_client.start_server(self.server['id'])
-        waiters.wait_for_server_status(self.servers_client, self.server['id'],
+        self.servers_client.start_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
                                        'ACTIVE')
 
         if CONF.validation.run_validation:
             linux_client = remote_client.RemoteClient(
-                self.get_server_ip(self.server),
+                self.get_server_ip(server),
                 self.image_ssh_user,
-                self.admin_pass,
+                self.image_ssh_password,
                 self.validation_resources['keypair']['private_key'],
-                server=self.server,
+                server=server,
                 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
-        self._create_and_attach()
+        server = self._create_server()
+        volume = self._create_and_attach_volume(server)
+
         # List Volume attachment of the server
         body = self.servers_client.list_volume_attachments(
-            self.server['id'])['volumeAttachments']
+            server['id'])['volumeAttachments']
         self.assertEqual(1, len(body))
         self.assertIn(self.attachment, body)
 
         # Get Volume attachment of the server
         body = self.servers_client.show_volume_attachment(
-            self.server['id'],
+            server['id'],
             self.attachment['id'])['volumeAttachment']
-        self.assertEqual(self.server['id'], body['serverId'])
-        self.assertEqual(self.volume['id'], body['volumeId'])
+        self.assertEqual(server['id'], body['serverId'])
+        self.assertEqual(volume['id'], body['volumeId'])
         self.assertEqual(self.attachment['id'], body['id'])
 
 
@@ -188,39 +169,71 @@
     min_microversion = '2.20'
     max_microversion = 'latest'
 
-    def _unshelve_server_and_check_volumes(self, number_of_partition):
-        # Unshelve the instance and check that there are expected volumes
-        self.servers_client.unshelve_server(self.server['id'])
-        waiters.wait_for_server_status(self.servers_client,
-                                       self.server['id'],
-                                       'ACTIVE')
+    def _count_volumes(self, server):
+        # Count number of volumes on an instance
+        volumes = 0
         if CONF.validation.run_validation:
             linux_client = remote_client.RemoteClient(
-                self.get_server_ip(self.server['id']),
+                self.get_server_ip(server),
                 self.image_ssh_user,
-                self.admin_pass,
+                self.image_ssh_password,
                 self.validation_resources['keypair']['private_key'],
-                server=self.server,
+                server=server,
                 servers_client=self.servers_client)
 
-            command = 'grep [vs]d /proc/partitions | wc -l'
-            nb_partitions = linux_client.exec_command(command).strip()
-            self.assertEqual(number_of_partition, nb_partitions)
+            command = 'grep -c -E [vs]d.$ /proc/partitions'
+            volumes = int(linux_client.exec_command(command).strip())
+        return volumes
+
+    def _shelve_server(self, server):
+        # NOTE(andreaf) If we are going to shelve a server, we should
+        # check first whether the server is ssh-able. Otherwise we
+        # won't be able to distinguish failures introduced by shelve
+        # from pre-existing ones. Also it's good to wait for cloud-init
+        # to be done and sshd server to be running before shelving to
+        # avoid breaking the VM
+        if CONF.validation.run_validation:
+            linux_client = remote_client.RemoteClient(
+                self.get_server_ip(server),
+                self.image_ssh_user,
+                self.image_ssh_password,
+                self.validation_resources['keypair']['private_key'],
+                server=server,
+                servers_client=self.servers_client)
+            linux_client.validate_authentication()
+
+        # If validation went ok, or it was skipped, shelve the server
+        compute.shelve_server(self.servers_client, server['id'])
+
+    def _unshelve_server_and_check_volumes(self, server, number_of_volumes):
+        # Unshelve the instance and check that there are expected volumes
+        self.servers_client.unshelve_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client,
+                                       server['id'],
+                                       'ACTIVE')
+        if CONF.validation.run_validation:
+            counted_volumes = self._count_volumes(server)
+            self.assertEqual(number_of_volumes, counted_volumes)
 
     @test.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     def test_attach_volume_shelved_or_offload_server(self):
-        self._create_and_attach(shelve_server=True)
+        # Create server, count number of volumes on it, shelve
+        # server and attach pre-created volume to shelved server
+        server = self._create_server()
+        num_vol = self._count_volumes(server)
+        self._shelve_server(server)
+        self._create_and_attach_volume(server)
 
-        # Unshelve the instance and check that there are two volumes
-        self._unshelve_server_and_check_volumes('2')
+        # Unshelve the instance and check that attached volume exists
+        self._unshelve_server_and_check_volumes(server, num_vol + 1)
 
         # Get Volume attachment of the server
         volume_attachment = self.servers_client.show_volume_attachment(
-            self.server['id'],
+            server['id'],
             self.attachment['id'])['volumeAttachment']
-        self.assertEqual(self.server['id'], volume_attachment['serverId'])
+        self.assertEqual(server['id'], volume_attachment['serverId'])
         self.assertEqual(self.attachment['id'], volume_attachment['id'])
         # Check the mountpoint is not None after unshelve server even in
         # case of shelved_offloaded.
@@ -230,11 +243,17 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     def test_detach_volume_shelved_or_offload_server(self):
-        self._create_and_attach(shelve_server=True)
+        # Create server, count number of volumes on it, shelve
+        # server and attach pre-created volume to shelved server
+        server = self._create_server()
+        num_vol = self._count_volumes(server)
+        self._shelve_server(server)
+        volume = self._create_and_attach_volume(server)
 
         # Detach the volume
-        self._detach(self.server['id'], self.volume['id'])
+        self._detach(server['id'], volume['id'])
         self.attachment = None
 
-        # Unshelve the instance and check that there is only one volume
-        self._unshelve_server_and_check_volumes('1')
+        # Unshelve the instance and check that we have the expected number of
+        # volume(s)
+        self._unshelve_server_and_check_volumes(server, num_vol)
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/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index 3616e77..59ffc19 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -69,7 +69,7 @@
         admin_role_id = admin_role['id']
 
         # grant the admin role to the user on his project
-        self.roles_client.assign_user_role_on_project(proj_id, user_id,
+        self.roles_client.create_user_role_on_project(proj_id, user_id,
                                                       admin_role_id)
 
         # create a new client with user's credentials (NOTE: unscoped token!)
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..373d44b 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,13 @@
             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']))
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 4ecf0a5..f5bf923 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -94,7 +94,7 @@
 
     @test.idempotent_id('c6b80012-fe4a-498b-9ce8-eb391c05169f')
     def test_grant_list_revoke_role_to_user_on_project(self):
-        self.roles_client.assign_user_role_on_project(self.project['id'],
+        self.roles_client.create_user_role_on_project(self.project['id'],
                                                       self.user_body['id'],
                                                       self.role['id'])
 
@@ -115,7 +115,7 @@
 
     @test.idempotent_id('6c9a2940-3625-43a3-ac02-5dcec62ef3bd')
     def test_grant_list_revoke_role_to_user_on_domain(self):
-        self.roles_client.assign_user_role_on_domain(
+        self.roles_client.create_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
         roles = self.roles_client.list_user_roles_on_domain(
@@ -136,7 +136,7 @@
     @test.idempotent_id('cbf11737-1904-4690-9613-97bcbb3df1c4')
     def test_grant_list_revoke_role_to_group_on_project(self):
         # Grant role to group on project
-        self.roles_client.assign_group_role_on_project(
+        self.roles_client.create_group_role_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
         # List group roles on project
         roles = self.roles_client.list_group_roles_on_project(
@@ -170,7 +170,7 @@
 
     @test.idempotent_id('4bf8a70b-e785-413a-ad53-9f91ce02faa7')
     def test_grant_list_revoke_role_to_group_on_domain(self):
-        self.roles_client.assign_group_role_on_domain(
+        self.roles_client.create_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
         roles = self.roles_client.list_group_roles_on_domain(
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index fcf4772..8706cf7 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -83,11 +83,11 @@
         self.addCleanup(self.roles_client.delete_role, role['id'])
 
         # Grant the user the role on both projects.
-        self.roles_client.assign_user_role_on_project(project1['id'],
+        self.roles_client.create_user_role_on_project(project1['id'],
                                                       user['id'],
                                                       role['id'])
 
-        self.roles_client.assign_user_role_on_project(project2['id'],
+        self.roles_client.create_user_role_on_project(project2['id'],
                                                       user['id'],
                                                       role['id'])
 
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 58e2ab8..4e69de8 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -77,11 +77,11 @@
         self.not_delegated_role_id = role['id']
 
         # Assign roles to trustor
-        self.roles_client.assign_user_role_on_project(
+        self.roles_client.create_user_role_on_project(
             self.trustor_project_id,
             self.trustor_user_id,
             self.delegated_role_id)
-        self.roles_client.assign_user_role_on_project(
+        self.roles_client.create_user_role_on_project(
             self.trustor_project_id,
             self.trustor_user_id,
             self.not_delegated_role_id)
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 1bcec62..fd2683e 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -130,7 +130,7 @@
             self.addCleanup(
                 self.projects_client.delete_project, project_body['id'])
             # Assigning roles to user on project
-            self.roles_client.assign_user_role_on_project(project['id'],
+            self.roles_client.create_user_role_on_project(project['id'],
                                                           user['id'],
                                                           role['id'])
             assigned_project_ids.append(project['id'])
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index deb5413..f5e4943 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)
@@ -119,10 +125,6 @@
         super(BaseIdentityV2AdminTest, cls).resource_setup()
         cls.projects_client = cls.tenants_client
 
-    @classmethod
-    def resource_cleanup(cls):
-        super(BaseIdentityV2AdminTest, cls).resource_cleanup()
-
     def setup_test_user(self, password=None):
         """Set up a test user."""
         tenant = self.setup_test_tenant()
@@ -171,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
@@ -187,14 +190,6 @@
             cls.os_adm.auth_provider.scope = 'domain'
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseIdentityV3AdminTest, cls).resource_setup()
-
-    @classmethod
-    def resource_cleanup(cls):
-        super(BaseIdentityV3AdminTest, cls).resource_cleanup()
-
-    @classmethod
     def disable_user(cls, user_name, domain_id=None):
         user = cls.get_user_by_name(user_name, domain_id)
         cls.users_client.update_user(user['id'], name=user_name, enabled=False)
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/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 42a4352..443e332 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,
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 723b870..a0c0a5f 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)
@@ -78,7 +77,16 @@
         # container request, the response does not contain 'accept-ranges'
         # header. This is a special case, therefore the existence of response
         # headers is checked without custom matcher.
-        self.assertIn('content-length', resp)
+        #
+        # As the expected response is 204 No Content, Content-Length presence
+        # is not checked here intensionally. 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
+        # any implementation violating it like Swift [1] or some versions of
+        # Ceph RadosGW [2].
+        # [1] https://bugs.launchpad.net/swift/+bug/1537811
+        # [2] http://tracker.ceph.com/issues/13582
         self.assertIn('x-timestamp', resp)
         self.assertIn('x-account-bytes-used', resp)
         self.assertIn('x-account-container-count', resp)
@@ -131,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)
@@ -152,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):
@@ -171,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):
@@ -206,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_object_services.py b/tempest/api/object_storage/test_object_services.py
index a707ebb..919f695 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
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index f665e69..120dbb1 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -66,8 +66,8 @@
         cls.type = cls.create_volume_type(name=type_name,
                                           extra_specs=extra_specs)
 
-        params = {cls.name_field: vol_name, 'volume_type': type_name}
-
+        params = {cls.name_field: vol_name, 'volume_type': type_name,
+                  'size': CONF.volume.volume_size}
         cls.volume = cls.admin_volume_client.create_volume(
             **params)['volume']
         if with_prefix:
diff --git a/tempest/api/volume/admin/test_qos.py b/tempest/api/volume/admin/test_qos.py
index f1101e1..98139e7 100755
--- a/tempest/api/volume/admin/test_qos.py
+++ b/tempest/api/volume/admin/test_qos.py
@@ -119,8 +119,7 @@
         self.admin_volume_qos_client.unset_qos_key(self.created_qos['id'],
                                                    keys)
         operation = 'qos-key-unset'
-        self.admin_volume_qos_client.wait_for_qos_operations(
-            self.created_qos['id'], operation, keys)
+        self.wait_for_qos_operations(self.created_qos['id'], operation, keys)
         body = self.admin_volume_qos_client.show_qos(
             self.created_qos['id'])['qos_specs']
         self.assertNotIn(keys[0], body['specs'])
@@ -154,8 +153,8 @@
         self.admin_volume_qos_client.disassociate_qos(
             self.created_qos['id'], vol_type[0]['id'])
         operation = 'disassociate'
-        self.admin_volume_qos_client.wait_for_qos_operations(
-            self.created_qos['id'], operation, vol_type[0]['id'])
+        self.wait_for_qos_operations(self.created_qos['id'],
+                                     operation, vol_type[0]['id'])
         associations = self._test_get_association_qos()
         self.assertNotIn(vol_type[0]['id'], associations)
 
@@ -163,8 +162,7 @@
         self.admin_volume_qos_client.disassociate_all_qos(
             self.created_qos['id'])
         operation = 'disassociate-all'
-        self.admin_volume_qos_client.wait_for_qos_operations(
-            self.created_qos['id'], operation)
+        self.wait_for_qos_operations(self.created_qos['id'], operation)
         associations = self._test_get_association_qos()
         self.assertEmpty(associations)
 
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index 89e4d18..c19b1c4 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -14,9 +14,12 @@
 #    under the License.
 
 from tempest.api.volume import base
+from tempest import config
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
+CONF = config.CONF
+
 
 class BaseVolumeQuotasNegativeV2TestJSON(base.BaseVolumeAdminTest):
     force_tenant_isolation = True
@@ -29,8 +32,7 @@
     @classmethod
     def resource_setup(cls):
         super(BaseVolumeQuotasNegativeV2TestJSON, cls).resource_setup()
-        cls.default_volume_size = cls.volumes_client.default_volume_size
-        cls.shared_quota_set = {'gigabytes': 2 * cls.default_volume_size,
+        cls.shared_quota_set = {'gigabytes': 2 * CONF.volume.volume_size,
                                 'volumes': 1}
 
         # NOTE(gfidente): no need to restore original quota set
@@ -47,7 +49,8 @@
     @test.idempotent_id('bf544854-d62a-47f2-a681-90f7a47d86b6')
     def test_quota_volumes(self):
         self.assertRaises(lib_exc.OverLimit,
-                          self.volumes_client.create_volume)
+                          self.volumes_client.create_volume,
+                          size=CONF.volume.volume_size)
 
     @test.attr(type='negative')
     @test.idempotent_id('2dc27eee-8659-4298-b900-169d71a91374')
@@ -58,13 +61,14 @@
         self.addCleanup(self.admin_quotas_client.update_quota_set,
                         self.demo_tenant_id,
                         **self.shared_quota_set)
-        new_quota_set = {'gigabytes': self.default_volume_size,
+        new_quota_set = {'gigabytes': CONF.volume.volume_size,
                          'volumes': 2, 'snapshots': 1}
         self.admin_quotas_client.update_quota_set(
             self.demo_tenant_id,
             **new_quota_set)
         self.assertRaises(lib_exc.OverLimit,
-                          self.volumes_client.create_volume)
+                          self.volumes_client.create_volume,
+                          size=CONF.volume.volume_size)
 
 
 class VolumeQuotasNegativeV1TestJSON(BaseVolumeQuotasNegativeV2TestJSON):
diff --git a/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py b/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
index 1565a8c..09af7fe 100644
--- a/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
@@ -38,7 +38,7 @@
     @classmethod
     def resource_setup(cls):
         super(VolumeSnapshotQuotasNegativeV2TestJSON, cls).resource_setup()
-        cls.default_volume_size = cls.volumes_client.default_volume_size
+        cls.default_volume_size = CONF.volume.volume_size
         cls.shared_quota_set = {'gigabytes': 3 * cls.default_volume_size,
                                 'volumes': 1, 'snapshots': 1}
 
diff --git a/tempest/api/volume/admin/test_volume_type_access.py b/tempest/api/volume/admin/test_volume_type_access.py
index fac71a8..91ff5af 100644
--- a/tempest/api/volume/admin/test_volume_type_access.py
+++ b/tempest/api/volume/admin/test_volume_type_access.py
@@ -17,9 +17,12 @@
 
 from tempest.api.volume import base
 from tempest.common import waiters
+from tempest import config
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
+CONF = config.CONF
+
 
 class VolumeTypesAccessV2Test(base.BaseVolumeAdminTest):
 
@@ -38,7 +41,8 @@
 
         # Try creating a volume from volume type in primary tenant
         self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
-                          volume_type=volume_type['id'])
+                          volume_type=volume_type['id'],
+                          size=CONF.volume.volume_size)
 
         # Adding volume type access for primary tenant
         self.admin_volume_types_client.add_type_access(
@@ -49,7 +53,8 @@
 
         # Creating a volume from primary tenant
         volume = self.volumes_client.create_volume(
-            volume_type=volume_type['id'])['volume']
+            volume_type=volume_type['id'],
+            size=CONF.volume.volume_size)['volume']
         self.addCleanup(self.delete_volume, self.volumes_client, volume['id'])
         waiters.wait_for_volume_status(self.volumes_client, volume['id'],
                                        'available')
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 7b4379b..646bc68 100755
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -50,7 +50,8 @@
                 extra_specs=extra_specs)
             volume_types.append(vol_type)
         params = {self.name_field: vol_name,
-                  'volume_type': volume_types[0]['id']}
+                  'volume_type': volume_types[0]['id'],
+                  'size': CONF.volume.volume_size}
 
         # Create volume
         volume = self.volumes_client.create_volume(**params)['volume']
@@ -127,7 +128,7 @@
         body = self.create_volume_type(name=name)
         # Create encryption type
         encryption_type = \
-            self.admin_volume_types_client.create_encryption_type(
+            self.admin_encryption_types_client.create_encryption_type(
                 body['id'], provider=provider,
                 control_location=control_location)['encryption']
         self.assertIn('volume_type_id', encryption_type)
@@ -140,7 +141,7 @@
 
         # Get encryption type
         fetched_encryption_type = (
-            self.admin_volume_types_client.show_encryption_type(
+            self.admin_encryption_types_client.show_encryption_type(
                 encryption_type['volume_type_id']))
         self.assertEqual(provider,
                          fetched_encryption_type['provider'],
@@ -152,14 +153,11 @@
                          'different from the created encryption_type')
 
         # Delete encryption type
-        self.admin_volume_types_client.delete_encryption_type(
-            encryption_type['volume_type_id'])
-        resource = {"id": encryption_type['volume_type_id'],
-                    "type": "encryption-type"}
-        self.admin_volume_types_client.wait_for_resource_deletion(resource)
+        type_id = encryption_type['volume_type_id']
+        self.admin_encryption_types_client.delete_encryption_type(type_id)
+        self.admin_encryption_types_client.wait_for_resource_deletion(type_id)
         deleted_encryption_type = (
-            self.admin_volume_types_client.show_encryption_type(
-                encryption_type['volume_type_id']))
+            self.admin_encryption_types_client.show_encryption_type(type_id))
         self.assertEmpty(deleted_encryption_type)
 
     @test.idempotent_id('cf9f07c6-db9e-4462-a243-5933ad65e9c8')
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 03927e6..9686473 100755
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -16,8 +16,11 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils as utils
 from tempest.common import waiters
+from tempest import config
 from tempest import test
 
+CONF = config.CONF
+
 
 class VolumesActionsV2Test(base.BaseVolumeAdminTest):
 
@@ -33,7 +36,7 @@
         # Create a test shared volume for tests
         vol_name = utils.rand_name(cls.__name__ + '-Volume')
         cls.name_field = cls.special_fields['name_field']
-        params = {cls.name_field: vol_name}
+        params = {cls.name_field: vol_name, 'size': CONF.volume.volume_size}
 
         cls.volume = cls.client.create_volume(**params)['volume']
         waiters.wait_for_volume_status(cls.client,
@@ -60,7 +63,7 @@
     def _create_temp_volume(self):
         # Create a temp volume for force delete tests
         vol_name = utils.rand_name(self.__class__.__name__ + '-Volume')
-        params = {self.name_field: vol_name}
+        params = {self.name_field: vol_name, 'size': CONF.volume.volume_size}
         temp_volume = self.client.create_volume(**params)['volume']
         waiters.wait_for_volume_status(self.client,
                                        temp_volume['id'], 'available')
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index f7013d8..a26052c 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)
diff --git a/tempest/api/volume/admin/test_volumes_list.py b/tempest/api/volume/admin/test_volumes_list.py
index 70c16f3..4437803 100644
--- a/tempest/api/volume/admin/test_volumes_list.py
+++ b/tempest/api/volume/admin/test_volumes_list.py
@@ -17,8 +17,11 @@
 
 from tempest.api.volume import base
 from tempest.common import waiters
+from tempest import config
 from tempest import test
 
+CONF = config.CONF
+
 
 class VolumesListAdminV2TestJSON(base.BaseVolumeAdminTest):
 
@@ -38,7 +41,8 @@
     def test_volume_list_param_tenant(self):
         # Test to list volumes from single tenant
         # Create a volume in admin tenant
-        adm_vol = self.admin_volume_client.create_volume()['volume']
+        adm_vol = self.admin_volume_client.create_volume(
+            size=CONF.volume.volume_size)['volume']
         waiters.wait_for_volume_status(self.admin_volume_client,
                                        adm_vol['id'], 'available')
         self.addCleanup(self.admin_volume_client.delete_volume, adm_vol['id'])
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 07b1a3f..d1549e2 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -13,12 +13,15 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import time
+
 from tempest.common import compute
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
 from tempest.lib.common.utils import test_utils
+from tempest.lib import exceptions as lib_exc
 import tempest.test
 
 CONF = config.CONF
@@ -110,6 +113,9 @@
     @classmethod
     def create_volume(cls, **kwargs):
         """Wrapper utility that returns a test volume."""
+        if 'size' not in kwargs:
+            kwargs['size'] = CONF.volume.volume_size
+
         name = data_utils.rand_name(cls.__name__ + '-Volume')
 
         name_field = cls.special_fields['name_field']
@@ -205,6 +211,8 @@
             cls.admin_hosts_client = cls.os_adm.volume_hosts_client
             cls.admin_snapshots_client = cls.os_adm.snapshots_client
             cls.admin_backups_client = cls.os_adm.backups_client
+            cls.admin_encryption_types_client = \
+                cls.os_adm.encryption_types_client
             cls.admin_quotas_client = cls.os_adm.volume_quotas_client
         elif cls._api_version == 2:
             cls.admin_volume_qos_client = cls.os_adm.volume_qos_v2_client
@@ -215,6 +223,8 @@
             cls.admin_hosts_client = cls.os_adm.volume_hosts_v2_client
             cls.admin_snapshots_client = cls.os_adm.snapshots_v2_client
             cls.admin_backups_client = cls.os_adm.backups_v2_client
+            cls.admin_encryption_types_client = \
+                cls.os_adm.encryption_types_v2_client
             cls.admin_quotas_client = cls.os_adm.volume_quotas_v2_client
 
     @classmethod
@@ -266,9 +276,38 @@
                 cls.admin_volume_types_client.delete_volume_type, vol_type)
 
         for vol_type in cls.volume_types:
-            # Resource dictionary uses for is_resource_deleted method,
-            # to distinguish between volume-type to encryption-type.
-            resource = {'id': vol_type, 'type': 'volume-type'}
             test_utils.call_and_ignore_notfound_exc(
                 cls.admin_volume_types_client.wait_for_resource_deletion,
-                resource)
+                vol_type)
+
+    def wait_for_qos_operations(self, qos_id, operation, args=None):
+        """Waits for a qos operations to be completed.
+
+        NOTE : operation value is required for  wait_for_qos_operations()
+        operation = 'qos-key' / 'disassociate' / 'disassociate-all'
+        args = keys[] when operation = 'qos-key'
+        args = volume-type-id disassociated when operation = 'disassociate'
+        args = None when operation = 'disassociate-all'
+        """
+        start_time = int(time.time())
+        client = self.admin_volume_qos_client
+        while True:
+            if operation == 'qos-key-unset':
+                body = client.show_qos(qos_id)['qos_specs']
+                if not any(key in body['specs'] for key in args):
+                    return
+            elif operation == 'disassociate':
+                body = client.show_association_qos(qos_id)['qos_associations']
+                if not any(args in body[i]['id'] for i in range(0, len(body))):
+                    return
+            elif operation == 'disassociate-all':
+                body = client.show_association_qos(qos_id)['qos_associations']
+                if not body:
+                    return
+            else:
+                msg = (" operation value is either not defined or incorrect.")
+                raise lib_exc.UnprocessableEntity(msg)
+
+            if int(time.time()) - start_time >= self.build_timeout:
+                raise exceptions.TimeoutException
+            time.sleep(self.build_interval)
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index f9ab605..b80a4a4 100755
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -110,7 +110,8 @@
         self.addCleanup(self.client.detach_volume, self.volume['id'])
         volume = self.client.show_volume(self.volume['id'])['volume']
         self.assertIn('attachments', volume)
-        attachment = self.client.get_attachment_from_volume(volume)
+        attachment = volume['attachments'][0]
+
         self.assertEqual('/dev/%s' %
                          CONF.compute.volume_device_name,
                          attachment['device'])
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 7a1c0a1..07f799b 100755
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -105,7 +105,8 @@
         # then test volume update if display_name is duplicated
         new_v_desc = data_utils.rand_name('@#$%^* description')
         params = {self.descrip_field: new_v_desc,
-                  'availability_zone': volume['availability_zone']}
+                  'availability_zone': volume['availability_zone'],
+                  'size': CONF.volume.volume_size}
         new_volume = self.client.create_volume(**params)['volume']
         self.assertIn('id', new_volume)
         self.addCleanup(self.delete_volume, self.client, new_volume['id'])
@@ -124,7 +125,7 @@
     @test.attr(type='smoke')
     @test.idempotent_id('27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51')
     def test_volume_create_get_update_delete(self):
-        self._volume_create_get_update_delete()
+        self._volume_create_get_update_delete(size=CONF.volume.volume_size)
 
     @test.attr(type='smoke')
     @test.idempotent_id('54a01030-c7fc-447c-86ee-c1182beae638')
@@ -142,7 +143,8 @@
                           'Cinder volume clones are disabled')
     def test_volume_create_get_update_delete_as_clone(self):
         origin = self.create_volume()
-        self._volume_create_get_update_delete(source_volid=origin['id'])
+        self._volume_create_get_update_delete(source_volid=origin['id'],
+                                              size=CONF.volume.volume_size)
 
 
 class VolumesV1GetTest(VolumesV2GetTest):
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index d4d8214..5bef7f3 100755
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -296,4 +296,3 @@
 
 class VolumesV1NegativeTest(VolumesV2NegativeTest):
     _api_version = 1
-    _name = 'display_name'
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index ab01684..8f7996a 100755
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -36,7 +36,7 @@
         cls.name_field = cls.special_fields['name_field']
         cls.descrip_field = cls.special_fields['descrip_field']
         # Create 2 snapshots
-        for _ in xrange(2):
+        for _ in range(2):
             cls.create_snapshot(cls.volume_origin['id'])
 
     def _detach(self, volume_id):
diff --git a/tempest/api/volume/v3/admin/test_user_messages.py b/tempest/api/volume/v3/admin/test_user_messages.py
index 517c8d7..39a5dfa 100755
--- a/tempest/api/volume/v3/admin/test_user_messages.py
+++ b/tempest/api/volume/v3/admin/test_user_messages.py
@@ -16,9 +16,12 @@
 from tempest.api.volume.v3 import base
 from tempest.common.utils import data_utils
 from tempest.common import waiters
+from tempest import config
 from tempest import exceptions
 from tempest import test
 
+CONF = config.CONF
+
 MESSAGE_KEYS = [
     'created_at',
     'event_id',
@@ -49,7 +52,8 @@
             extra_specs=extra_specs)['volume_type']
         self.addCleanup(self.admin_volume_types_client.delete_volume_type,
                         bogus_type['id'])
-        params = {'volume_type': bogus_type['id']}
+        params = {'volume_type': bogus_type['id'],
+                  'size': CONF.volume.volume_size}
         volume = self.volumes_client.create_volume(**params)['volume']
         self.addCleanup(self.delete_volume, self.volumes_client, volume['id'])
         try:
diff --git a/tempest/clients.py b/tempest/clients.py
index e14f6f8..4c677f0 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -246,6 +246,8 @@
             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.identity_services_v3_client = identity.v3.ServicesClient(
             self.auth_provider, **params_v3)
         self.policies_client = identity.v3.PoliciesClient(self.auth_provider,
@@ -293,16 +295,18 @@
                                                       **params)
         self.backups_v2_client = volume.v2.BackupsClient(self.auth_provider,
                                                          **params)
+        self.encryption_types_client = volume.v1.EncryptionTypesClient(
+            self.auth_provider, **params)
+        self.encryption_types_v2_client = volume.v2.EncryptionTypesClient(
+            self.auth_provider, **params)
         self.snapshots_client = volume.v1.SnapshotsClient(self.auth_provider,
                                                           **params)
         self.snapshots_v2_client = volume.v2.SnapshotsClient(
             self.auth_provider, **params)
-        self.volumes_client = volume.v1.VolumesClient(
-            self.auth_provider, default_volume_size=CONF.volume.volume_size,
-            **params)
-        self.volumes_v2_client = volume.v2.VolumesClient(
-            self.auth_provider, default_volume_size=CONF.volume.volume_size,
-            **params)
+        self.volumes_client = volume.v1.VolumesClient(self.auth_provider,
+                                                      **params)
+        self.volumes_v2_client = volume.v2.VolumesClient(self.auth_provider,
+                                                         **params)
         self.volume_messages_client = volume.v3.MessagesClient(
             self.auth_provider, **params)
         self.volume_types_client = volume.v1.TypesClient(self.auth_provider,
diff --git a/tempest/cmd/init.py b/tempest/cmd/init.py
index eeca063..ba1f1fa 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):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 9947f2a..c36c9be 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
 
 
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 194b9e9..8e9f0b0 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -107,7 +107,8 @@
             volumes_client = clients.volumes_client
         volume = volumes_client.create_volume(
             display_name=volume_name,
-            imageRef=image_id)
+            imageRef=image_id,
+            size=CONF.volume.volume_size)
         waiters.wait_for_volume_status(volumes_client,
                                        volume['volume']['id'], 'available')
 
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index 4e3c395..ad968f1 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -17,7 +17,7 @@
 
 from tempest.lib import auth
 from tempest.lib import exceptions as lib_exc
-from tempest.services.identity.v2.json import identity_client as v2_identity
+from tempest.lib.services.identity.v2 import identity_client as v2_identity
 
 LOG = logging.getLogger(__name__)
 
@@ -74,7 +74,9 @@
             msg = 'No "%s" role found' % role_name
             raise lib_exc.NotFound(msg)
         try:
-            self._assign_user_role(project, user, role)
+            self.roles_client.create_user_role_on_project(project['id'],
+                                                          user['id'],
+                                                          role['id'])
         except lib_exc.Conflict:
             LOG.debug("Role %s already assigned on project %s for user %s" % (
                 role['id'], project['id'], user['id']))
@@ -124,11 +126,6 @@
             tenant_name=project['name'], tenant_id=project['id'],
             password=password)
 
-    def _assign_user_role(self, project, user, role):
-        self.roles_client.create_user_role_on_project(project['id'],
-                                                      user['id'],
-                                                      role['id'])
-
 
 class V3CredsClient(CredsClient):
     project_id_param = 'project_id'
@@ -176,11 +173,6 @@
             domain_id=self.creds_domain['id'],
             domain_name=self.creds_domain['name'])
 
-    def _assign_user_role(self, project, user, role):
-        self.roles_client.assign_user_role_on_project(project['id'],
-                                                      user['id'],
-                                                      role['id'])
-
     def assign_user_role_on_domain(self, user, role_name, domain=None):
         """Assign the specified role on a domain
 
@@ -198,7 +190,7 @@
             msg = 'No "%s" role found' % role_name
             raise lib_exc.NotFound(msg)
         try:
-            self.roles_client.assign_user_role_on_domain(
+            self.roles_client.create_user_role_on_domain(
                 domain['id'], user['id'], role['id'])
         except lib_exc.Conflict:
             LOG.debug("Role %s already assigned on domain %s for user %s",
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index 8ba33ed..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,14 +36,34 @@
         """
         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.
+        # Take into account the exceptions defined in RFC 7230.
+        if resp.status in range(100, 200) or resp.status == 204:
+            return False
+
+        return True
 
     def match(self, actual):
         """Check headers
 
-        param: actual HTTP response headers
+        param: actual HTTP response object containing headers and status
         """
-        # Check common headers for all HTTP methods
-        if 'content-length' not in actual:
+        # Check common headers for all HTTP methods.
+        #
+        # Please note that for 1xx and 204 responses Content-Length presence
+        # is not checked intensionally. 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
+        # any implementation violating it like Swift [1] or some versions of
+        # Ceph RadosGW [2].
+        # [1] https://bugs.launchpad.net/swift/+bug/1537811
+        # [2] http://tracker.ceph.com/issues/13582
+        if ('content-length' not in actual and
+                self._content_length_required(actual)):
             return NonExistentHeader('content-length')
         if 'content-type' not in actual:
             return NonExistentHeader('content-type')
@@ -65,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')
@@ -95,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"""
 
@@ -108,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/lib/common/ssh.py b/tempest/lib/common/ssh.py
index 8e83775..c13f41a 100644
--- a/tempest/lib/common/ssh.py
+++ b/tempest/lib/common/ssh.py
@@ -77,7 +77,7 @@
                          self.username, self.host)
                 return ssh
             except (EOFError,
-                    socket.error,
+                    socket.error, socket.timeout,
                     paramiko.SSHException) as e:
                 if self._is_timed_out(_start_time):
                     LOG.exception("Failed to establish authenticated ssh"
diff --git a/tempest/lib/common/utils/data_utils.py b/tempest/lib/common/utils/data_utils.py
index 6b6548e..70be40c 100644
--- a/tempest/lib/common/utils/data_utils.py
+++ b/tempest/lib/common/utils/data_utils.py
@@ -171,7 +171,7 @@
     :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)])
 
 
@@ -204,5 +204,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/common/utils/test_utils.py b/tempest/lib/common/utils/test_utils.py
index 50a1a7d..3b28701 100644
--- a/tempest/lib/common/utils/test_utils.py
+++ b/tempest/lib/common/utils/test_utils.py
@@ -14,6 +14,7 @@
 #    under the License.
 import inspect
 import re
+import time
 
 from oslo_log import log as logging
 
@@ -83,3 +84,24 @@
         return func(*args, **kwargs)
     except exceptions.NotFound:
         pass
+
+
+def call_until_true(func, duration, sleep_for):
+    """Call the given function until it returns True (and return True)
+
+    or until the specified duration (in seconds) elapses (and return False).
+
+    :param func: A zero argument callable that returns True on success.
+    :param duration: The number of seconds for which to attempt a
+        successful call of the function.
+    :param sleep_for: The number of seconds to sleep after an unsuccessful
+                      invocation of the function.
+    """
+    now = time.time()
+    timeout = now + duration
+    while now < timeout:
+        if func():
+            return True
+        time.sleep(sleep_for)
+        now = time.time()
+    return False
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/lib/services/identity/v2/identity_client.py
similarity index 100%
rename from tempest/services/identity/v2/json/identity_client.py
rename to tempest/lib/services/identity/v2/identity_client.py
diff --git a/tempest/lib/services/identity/v2/tenants_client.py b/tempest/lib/services/identity/v2/tenants_client.py
index 77ddaa5..f92c703 100644
--- a/tempest/lib/services/identity/v2/tenants_client.py
+++ b/tempest/lib/services/identity/v2/tenants_client.py
@@ -25,7 +25,8 @@
         """Create a tenant
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#createTenant
+                              api-ref/identity/v2-admin/index.html#
+                              create-tenant
         """
         post_body = json.dumps({'tenant': kwargs})
         resp, body = self.post('tenants', post_body)
@@ -59,7 +60,8 @@
         """Returns tenants.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#admin-listTenants
+                              api-ref/identity/v2-admin/index.html#
+                              list-tenants-admin-endpoint
         """
         url = 'tenants'
         if params:
@@ -73,7 +75,8 @@
         """Updates a tenant.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#updateTenant
+                              api-ref/identity/v2-admin/index.html#
+                              update-tenant
         """
         if 'id' not in kwargs:
             kwargs['id'] = tenant_id
@@ -87,7 +90,8 @@
         """List users for a Tenant.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v2-ext.html#listUsersForTenant
+                              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 4ea17f9..2a266d9 100644
--- a/tempest/lib/services/identity/v2/users_client.py
+++ b/tempest/lib/services/identity/v2/users_client.py
@@ -23,7 +23,8 @@
         """Create a user.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-admin-v2.html#admin-createUser
+                              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,7 +36,8 @@
         """Updates a user.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-admin-v2.html#admin-updateUser
+                              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)
@@ -68,7 +70,8 @@
         """Get the list of users.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-admin-v2.html#admin-listUsers
+                              api-ref/identity/v2-admin/index.html#
+                              list-users-admin-endpoint
         """
         url = "users"
         if params:
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/lib/services/identity/v3/credentials_client.py
similarity index 89%
rename from tempest/services/identity/v3/json/credentials_client.py
rename to tempest/lib/services/identity/v3/credentials_client.py
index 55eeee4..c063cae 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
@@ -30,7 +30,7 @@
         """Creates a credential.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#create-credential
+                              api-ref/identity/v3/index.html#create-credential
         """
         post_body = json.dumps({'credential': kwargs})
         resp, body = self.post('credentials', post_body)
@@ -43,7 +43,7 @@
         """Updates a credential.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#update-credential
+                              api-ref/identity/v3/index.html#update-credential
         """
         post_body = json.dumps({'credential': kwargs})
         resp, body = self.patch('credentials/%s' % credential_id, post_body)
@@ -56,7 +56,8 @@
         """To GET Details of a credential.
 
         For API details, see http://developer.openstack.org/
-                             api-ref-identity-v3.html#show-credential-details
+                             api-ref/identity/v3/index.html#
+                             show-credential-details
         """
         resp, body = self.get('credentials/%s' % credential_id)
         self.expected_success(200, resp.status)
diff --git a/tempest/lib/services/identity/v3/endpoints_client.py b/tempest/lib/services/identity/v3/endpoints_client.py
index db30508..3bb3deb 100644
--- a/tempest/lib/services/identity/v3/endpoints_client.py
+++ b/tempest/lib/services/identity/v3/endpoints_client.py
@@ -36,7 +36,7 @@
         """Create endpoint.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createEndpoint
+                              api-ref/identity/v3/index.html#create-endpoint
         """
         post_body = json.dumps({'endpoint': kwargs})
         resp, body = self.post('endpoints', post_body)
@@ -48,7 +48,7 @@
         """Updates an endpoint with given parameters.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateEndpoint
+                              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 96%
rename from tempest/services/identity/v3/json/groups_client.py
rename to tempest/lib/services/identity/v3/groups_client.py
index 3674496..200cb43 100644
--- a/tempest/services/identity/v3/json/groups_client.py
+++ b/tempest/lib/services/identity/v3/groups_client.py
@@ -30,7 +30,7 @@
         """Creates a group.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createGroup
+                              api-ref/identity/v3/index.html#create-group
         """
         post_body = json.dumps({'group': kwargs})
         resp, body = self.post('groups', post_body)
@@ -63,7 +63,7 @@
         """Updates a group.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateGroup
+                              api-ref/identity/v3/index.html#update-group
         """
         post_body = json.dumps({'group': kwargs})
         resp, body = self.patch('groups/%s' % group_id, post_body)
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..4c1b4ae 100644
--- a/tempest/lib/services/identity/v3/policies_client.py
+++ b/tempest/lib/services/identity/v3/policies_client.py
@@ -29,7 +29,7 @@
         """Creates a Policy.
 
         Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#createPolicy
+                          api-ref/identity/v3/index.html#create-policy
         """
         post_body = json.dumps({'policy': kwargs})
         resp, body = self.post('policies', post_body)
@@ -56,7 +56,7 @@
         """Updates a policy.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updatePolicy
+                              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..ff06a19 100644
--- a/tempest/lib/services/identity/v3/projects_client.py
+++ b/tempest/lib/services/identity/v3/projects_client.py
@@ -26,7 +26,7 @@
         """Create a Project.
 
         Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#createProject
+                          api-ref/identity/v3/index.html#create-project
 
         """
         # Include the project name to the kwargs parameters
@@ -50,7 +50,7 @@
         """Update a Project.
 
         Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#updateProject
+                          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..bddfc7b 100644
--- a/tempest/lib/services/identity/v3/regions_client.py
+++ b/tempest/lib/services/identity/v3/regions_client.py
@@ -30,10 +30,7 @@
         """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
+                              api-ref/identity/v3/index.html#create-region
         """
         if region_id is not None:
             method = self.put
@@ -51,7 +48,7 @@
         """Updates a region.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateRegion
+                              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..2a97caf
--- /dev/null
+++ b/tempest/lib/services/identity/v3/roles_client.py
@@ -0,0 +1,190 @@
+# 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/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.
+
+        Available params: see 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..efa0d89 100644
--- a/tempest/lib/services/identity/v3/services_client.py
+++ b/tempest/lib/services/identity/v3/services_client.py
@@ -30,7 +30,7 @@
         """Updates a service.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateService
+                              api-ref/identity/v3/index.html#update-service
         """
         patch_body = json.dumps({'service': kwargs})
         resp, body = self.patch('services/%s' % service_id, patch_body)
@@ -50,7 +50,7 @@
         """Creates a service.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createService
+                              api-ref/identity/v3/index.html#create-service
         """
         body = json.dumps({'service': kwargs})
         resp, body = self.post("services", body)
diff --git a/tempest/services/identity/v3/json/trusts_client.py b/tempest/lib/services/identity/v3/trusts_client.py
similarity index 83%
rename from tempest/services/identity/v3/json/trusts_client.py
rename to tempest/lib/services/identity/v3/trusts_client.py
index dedee05..e3d5a41 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
 
@@ -24,7 +25,7 @@
         """Creates a trust.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3-ext.html#createTrust
+                              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 +39,16 @@
         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
+
+        Available params: see 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 94%
rename from tempest/services/identity/v3/json/users_clients.py
rename to tempest/lib/services/identity/v3/users_client.py
index 0dcdacd..5398621 100644
--- a/tempest/services/identity/v3/json/users_clients.py
+++ b/tempest/lib/services/identity/v3/users_client.py
@@ -37,7 +37,7 @@
         """Updates a user.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#updateUser
+                              api-ref/identity/v3/#update-user
         """
         if 'id' not in kwargs:
             kwargs['id'] = user_id
@@ -51,7 +51,8 @@
         """Update a user password
 
         Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#changeUserPassword
+                              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)
diff --git a/tempest/lib/services/image/v2/image_members_client.py b/tempest/lib/services/image/v2/image_members_client.py
index d0ab165..941e2e3 100644
--- a/tempest/lib/services/image/v2/image_members_client.py
+++ b/tempest/lib/services/image/v2/image_members_client.py
@@ -22,7 +22,7 @@
         """List image members.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#listImageMembers-v2
+                          api-ref/image/v2/#list-image-members
         """
         url = 'images/%s/members' % image_id
         resp, body = self.get(url)
@@ -34,7 +34,7 @@
         """Create an image member.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#createImageMember-v2
+                              api-ref/image/v2/#create-image-member
         """
         url = 'images/%s/members' % image_id
         data = json.dumps(kwargs)
@@ -47,7 +47,7 @@
         """Update an image member.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#updateImageMember-v2
+                              api-ref/image/v2/#update-image-member
         """
         url = 'images/%s/members/%s' % (image_id, member_id)
         data = json.dumps(kwargs)
@@ -60,7 +60,7 @@
         """Show an image member.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#showImageMember-v2
+                          api-ref/image/v2/#show-image-member-details
         """
         url = 'images/%s/members/%s' % (image_id, member_id)
         resp, body = self.get(url)
@@ -71,7 +71,7 @@
         """Delete an image member.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#deleteImageMember-v2
+                          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..a6016a4 100644
--- a/tempest/lib/services/image/v2/images_client.py
+++ b/tempest/lib/services/image/v2/images_client.py
@@ -31,7 +31,7 @@
         """Update an image.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#updateImage-v2
+                              api-ref/image/v2/index.html#update-an-image
         """
         data = json.dumps(patch)
         headers = {"Content-Type": "application/openstack-images-v2.0"
@@ -45,7 +45,7 @@
         """Create an image.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#createImage-v2
+                              api-ref/image/v2/index.html#create-an-image
         """
         data = json.dumps(kwargs)
         resp, body = self.post('images', data)
@@ -57,7 +57,7 @@
         """Deactivate image.
 
          Available params: see http://developer.openstack.org/
-                               api-ref-image-v2.html#deactivateImage-v2
+                               api-ref/image/v2/#deactivate-image
          """
         url = 'images/%s/actions/deactivate' % image_id
         resp, body = self.post(url, None)
@@ -68,7 +68,7 @@
         """Reactivate image.
 
          Available params: see http://developer.openstack.org/
-                               api-ref-image-v2.html#reactivateImage-v2
+                               api-ref/image/v2/#reactivate-image
          """
         url = 'images/%s/actions/reactivate' % image_id
         resp, body = self.post(url, None)
@@ -79,7 +79,7 @@
         """Delete image.
 
          Available params: see http://developer.openstack.org/
-                               api-ref-image-v2.html#deleteImage-v2
+                               /api-ref/image/v2/#delete-an-image
          """
         url = 'images/%s' % image_id
         resp, _ = self.delete(url)
@@ -90,7 +90,7 @@
         """List images.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#listImages-v2
+                              api-ref/image/v2/#show-images
         """
         url = 'images'
 
@@ -106,7 +106,7 @@
         """Show image details.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#showImage-v2
+                          api-ref/image/v2/#show-image-details
         """
         url = 'images/%s' % image_id
         resp, body = self.get(url)
@@ -130,7 +130,7 @@
         """Upload binary image data.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#storeImageFile-v2
+                          api-ref/image/v2/#upload-binary-image-data
         """
         url = 'images/%s/file' % image_id
 
@@ -148,7 +148,7 @@
         """Download binary image data.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#showImageFile-v2
+                          api-ref/image/v2/#download-binary-image-data
         """
         url = 'images/%s/file' % image_id
         resp, body = self.get(url)
@@ -159,7 +159,7 @@
         """Add an image tag.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#addImageTag-v2
+                          api-ref/image/v2/#add-image-tag
         """
         url = 'images/%s/tags/%s' % (image_id, tag)
         resp, body = self.put(url, body=None)
@@ -170,7 +170,7 @@
         """Delete an image tag.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#deleteImageTag-v2
+                          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..aafa936 100644
--- a/tempest/lib/services/image/v2/namespaces_client.py
+++ b/tempest/lib/services/image/v2/namespaces_client.py
@@ -25,7 +25,7 @@
         """Create a namespace.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#createNamespace-v2
+                              api-ref/image/v2/metadefs-index.html#create-namespace
         """
         data = json.dumps(kwargs)
         resp, body = self.post('metadefs/namespaces', data)
@@ -34,6 +34,11 @@
         return rest_client.ResponseBody(resp, body)
 
     def show_namespace(self, namespace):
+        """Show namespace details.
+
+        Available params: see 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)
@@ -44,7 +49,7 @@
         """Update a namespace.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-image-v2.html#updateNamespace-v2
+                              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.
@@ -61,7 +66,7 @@
         """Delete a namespace.
 
         Available params: http://developer.openstack.org/
-                          api-ref-image-v2.html#deleteNamespace-v2
+                          api-ref/image/v2/metadefs-index.html#delete-namespace
         """
         url = 'metadefs/namespaces/%s' % namespace
         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..24e0e7d 100755
--- a/tempest/lib/services/network/floating_ips_client.py
+++ b/tempest/lib/services/network/floating_ips_client.py
@@ -22,7 +22,8 @@
         internal port.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#createFloatingIp
+                              api-ref/networking/v2/index.html#
+                              create-floating-ip
         """
         uri = '/floatingips'
         post_data = {'floatingip': kwargs}
@@ -32,7 +33,8 @@
         """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
+                              api-ref/networking/v2/index.html#
+                              update-floating-ip
         """
         uri = '/floatingips/%s' % floatingip_id
         post_data = {'floatingip': kwargs}
@@ -42,7 +44,8 @@
         """Shows details for a floating IP.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showFloatingIp
+                              api-ref/networking/v2/index.html#
+                              show-floating-ip-details
         """
         uri = '/floatingips/%s' % floatingip_id
         return self.show_resource(uri, **fields)
@@ -55,7 +58,8 @@
         """Lists floating IPs.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listFloatingIps
+                              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..6932a62 100755
--- a/tempest/lib/services/network/metering_labels_client.py
+++ b/tempest/lib/services/network/metering_labels_client.py
@@ -19,8 +19,8 @@
         """Creates an L3 metering label.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              createMeteringLabel
+                              api-ref/networking/v2/index.html#
+                              create-metering-label
         """
         uri = '/metering/metering-labels'
         post_data = {'metering_label': kwargs}
@@ -30,7 +30,8 @@
         """Shows details for a metering label.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showMeteringLabel
+                              api-ref/networking/v2/index.html#
+                              show-metering-label-details
         """
         uri = '/metering/metering-labels/%s' % metering_label_id
         return self.show_resource(uri, **fields)
@@ -39,8 +40,8 @@
         """Deletes an L3 metering label.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              deleteMeteringLabel
+                              api-ref/networking/v2/index.html#
+                              delete-metering-label
         """
         uri = '/metering/metering-labels/%s' % metering_label_id
         return self.delete_resource(uri)
@@ -49,8 +50,8 @@
         """Lists all L3 metering labels that belong to the tenant.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              listMeteringLabels
+                              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/ports_client.py b/tempest/lib/services/network/ports_client.py
index 71f1103..85f5a1d 100755
--- a/tempest/lib/services/network/ports_client.py
+++ b/tempest/lib/services/network/ports_client.py
@@ -20,7 +20,7 @@
         """Creates a port on a network.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#createPort
+                              api-ref/networking/v2/index.html#create-port
         """
         uri = '/ports'
         post_data = {'port': kwargs}
@@ -30,7 +30,7 @@
         """Updates a port.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#updatePort
+                              api-ref/networking/v2/index.html#update-port
         """
         uri = '/ports/%s' % port_id
         post_data = {'port': kwargs}
@@ -40,7 +40,7 @@
         """Shows details for a port.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#showPort
+                              api-ref/networking/v2/index.html#show-port-details
         """
         uri = '/ports/%s' % port_id
         return self.show_resource(uri, **fields)
@@ -49,7 +49,7 @@
         """Deletes a port.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#removePort
+                              api-ref/networking/v2/index.html#delete-port
         """
         uri = '/ports/%s' % port_id
         return self.delete_resource(uri)
@@ -58,7 +58,7 @@
         """Lists ports to which the tenant has access.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#listPorts
+                              api-ref/networking/v2/index.html#list-ports
         """
         uri = '/ports'
         return self.list_resources(uri, **filters)
@@ -67,7 +67,7 @@
         """Create multiple ports in a single request.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#bulkCreatePorts
+                              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..5a72b5e 100755
--- a/tempest/lib/services/network/routers_client.py
+++ b/tempest/lib/services/network/routers_client.py
@@ -19,7 +19,7 @@
         """Create a router.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#createRouter
+                              api-ref/networking/v2/index.html#create-router
         """
         post_body = {'router': kwargs}
         uri = '/routers'
@@ -29,7 +29,7 @@
         """Updates a logical router.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#updateRouter
+                              api-ref/networking/v2/index.html#update-router
         """
         uri = '/routers/%s' % router_id
         update_body = {'router': kwargs}
@@ -39,7 +39,8 @@
         """Shows details for a router.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showRouter
+                              api-ref/networking/v2/index.html#
+                              show-router-details
         """
         uri = '/routers/%s' % router_id
         return self.show_resource(uri, **fields)
@@ -52,7 +53,7 @@
         """Lists logical routers.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listRouters
+                              api-ref/networking/v2/index.html#list-routers
         """
         uri = '/routers'
         return self.list_resources(uri, **filters)
@@ -61,8 +62,8 @@
         """Add router interface.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              addRouterInterface
+                              api-ref/networking/v2/index.html#
+                              add-interface-to-router
         """
         uri = '/routers/%s/add_router_interface' % router_id
         return self.update_resource(uri, kwargs)
@@ -71,8 +72,8 @@
         """Remove router interface.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              deleteRouterInterface
+                              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..e6f1bb8 100755
--- a/tempest/lib/services/network/security_group_rules_client.py
+++ b/tempest/lib/services/network/security_group_rules_client.py
@@ -19,8 +19,8 @@
         """Creates an OpenStack Networking security group rule.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#
-                              createSecGroupRule
+                              api-ref/networking/v2/index.html#
+                              create-security-group-rule
         """
         uri = '/security-group-rules'
         post_data = {'security_group_rule': kwargs}
@@ -30,7 +30,8 @@
         """Shows detailed information for a security group rule.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showSecGroupRule
+                              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)
@@ -43,7 +44,8 @@
         """Lists a summary of all OpenStack Networking security group rules.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listSecGroupRules
+                              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..d5ac61c 100755
--- a/tempest/lib/services/network/security_groups_client.py
+++ b/tempest/lib/services/network/security_groups_client.py
@@ -19,7 +19,8 @@
         """Creates an OpenStack Networking security group.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#createSecGroup
+                              api-ref/networking/v2/index.html#
+                              create-security-group
         """
         uri = '/security-groups'
         post_data = {'security_group': kwargs}
@@ -29,7 +30,8 @@
         """Updates a security group.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#updateSecGroup
+                              api-ref/networking/v2/index.html#
+                              update-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         post_data = {'security_group': kwargs}
@@ -39,7 +41,8 @@
         """Shows details for a security group.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showSecGroup
+                              api-ref/networking/v2/index.html#
+                              show-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         return self.show_resource(uri, **fields)
@@ -48,7 +51,8 @@
         """Deletes an OpenStack Networking security group.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#deleteSecGroup
+                              api-ref/networking/v2/index.html#
+                              delete-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         return self.delete_resource(uri)
@@ -57,7 +61,8 @@
         """Lists OpenStack Networking security groups.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listSecGroups
+                              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..ec110b9 100755
--- a/tempest/lib/services/network/subnetpools_client.py
+++ b/tempest/lib/services/network/subnetpools_client.py
@@ -21,7 +21,8 @@
         """Lists subnet pools to which the tenant has access.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#listSubnetPools
+                              api-ref/networking/v2/index.html#
+                              list-subnet-pools
         """
         uri = '/subnetpools'
         return self.list_resources(uri, **filters)
@@ -30,7 +31,8 @@
         """Creates a subnet pool.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#createSubnetPool
+                              api-ref/networking/v2/index.html#
+                              create-subnet-pool
         """
         uri = '/subnetpools'
         post_data = {'subnetpool': kwargs}
@@ -40,7 +42,7 @@
         """Shows information for a subnet pool.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#showSubnetPool
+                              api-ref/networking/v2/index.html#show-subnet-pool
         """
         uri = '/subnetpools/%s' % subnetpool_id
         return self.show_resource(uri, **fields)
@@ -49,7 +51,8 @@
         """Updates a subnet pool.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2-ext.html#updateSubnetPool
+                              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..203b360 100755
--- a/tempest/lib/services/network/subnets_client.py
+++ b/tempest/lib/services/network/subnets_client.py
@@ -19,7 +19,7 @@
         """Creates a subnet on a network.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#createSubnet
+                              api-ref/networking/v2/index.html#create-subnet
         """
         uri = '/subnets'
         post_data = {'subnet': kwargs}
@@ -29,7 +29,7 @@
         """Updates a subnet.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#updateSubnet
+                              api-ref/networking/v2/index.html#update-subnet
         """
         uri = '/subnets/%s' % subnet_id
         post_data = {'subnet': kwargs}
@@ -39,7 +39,7 @@
         """Shows details for a subnet.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#showSubnet
+                              api-ref/networking/v2/index.html#show-subnet-details
         """
         uri = '/subnets/%s' % subnet_id
         return self.show_resource(uri, **fields)
@@ -52,7 +52,7 @@
         """Lists subnets to which the tenant has access.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#listSubnets
+                              api-ref/networking/v2/index.html#list-subnets
         """
         uri = '/subnets'
         return self.list_resources(uri, **filters)
@@ -61,7 +61,7 @@
         """Create multiple subnets in a single request.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#bulkCreateSubnet
+                              api-ref/networking/v2/index.html#bulk-create-subnet
         """
         uri = '/subnets'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index fdccfc3..233d747 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -213,14 +213,15 @@
 
     def create_volume(self, size=None, name=None, snapshot_id=None,
                       imageRef=None, volume_type=None):
+        if size is None:
+            size = CONF.volume.volume_size
         if name is None:
             name = data_utils.rand_name(self.__class__.__name__)
         kwargs = {'display_name': name,
                   'snapshot_id': snapshot_id,
                   'imageRef': imageRef,
-                  'volume_type': volume_type}
-        if size is not None:
-            kwargs.update({'size': size})
+                  'volume_type': volume_type,
+                  'size': size}
         volume = self.volumes_client.create_volume(**kwargs)['volume']
 
         self.addCleanup(self.volumes_client.wait_for_resource_deletion,
@@ -513,7 +514,7 @@
                       'should_succeed':
                       'reachable' if should_succeed else 'unreachable'
                   })
-        result = tempest.test.call_until_true(ping, timeout, 1)
+        result = test_utils.call_until_true(ping, timeout, 1)
         LOG.debug('%(caller)s finishes ping %(ip)s in %(timeout)s sec and the '
                   'ping result is %(result)s' % {
                       'caller': caller, 'ip': ip_address, 'timeout': timeout,
@@ -857,9 +858,9 @@
                       show_floatingip(floatingip_id)['floatingip'])
             return status == result['status']
 
-        tempest.test.call_until_true(refresh,
-                                     CONF.network.build_timeout,
-                                     CONF.network.build_interval)
+        test_utils.call_until_true(refresh,
+                                   CONF.network.build_timeout,
+                                   CONF.network.build_interval)
         floating_ip = self.floating_ips_client.show_floatingip(
             floatingip_id)['floatingip']
         self.assertEqual(status, floating_ip['status'],
@@ -914,9 +915,9 @@
                 return not should_succeed
             return should_succeed
 
-        return tempest.test.call_until_true(ping_remote,
-                                            CONF.validation.ping_timeout,
-                                            1)
+        return test_utils.call_until_true(ping_remote,
+                                          CONF.validation.ping_timeout,
+                                          1)
 
     def _create_security_group(self, security_group_rules_client=None,
                                tenant_id=None,
@@ -1249,7 +1250,7 @@
                 return True
             return False
 
-        if not tempest.test.call_until_true(
+        if not test_utils.call_until_true(
             check_state, timeout, interval):
             msg = ("Timed out waiting for node %s to reach %s state(s) %s" %
                    (node_id, state_attr, target_states))
@@ -1273,7 +1274,7 @@
                 self.get_node, instance_id=instance_id)
             return node is not None
 
-        if not tempest.test.call_until_true(
+        if not test_utils.call_until_true(
             _get_node, CONF.baremetal.association_timeout, 1):
             msg = ('Timed out waiting to get Ironic node by instance id %s'
                    % instance_id)
@@ -1345,8 +1346,12 @@
         super(EncryptionScenarioTest, cls).setup_clients()
         if CONF.volume_feature_enabled.api_v1:
             cls.admin_volume_types_client = cls.os_adm.volume_types_client
+            cls.admin_encryption_types_client =\
+                cls.os_adm.encryption_types_client
         else:
             cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
+            cls.admin_encryption_types_client =\
+                cls.os_adm.encryption_types_v2_client
 
     def create_volume_type(self, client=None, name=None):
         if not client:
@@ -1365,7 +1370,7 @@
                                key_size=None, cipher=None,
                                control_location=None):
         if not client:
-            client = self.admin_volume_types_client
+            client = self.admin_encryption_types_client
         if not type_id:
             volume_type = self.create_volume_type()
             type_id = volume_type['id']
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index f7c7434..dba1c92 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -17,6 +17,7 @@
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
+from tempest.lib.common.utils import test_utils
 from tempest.scenario import manager
 from tempest import test
 
@@ -88,9 +89,9 @@
                     ['server'])
             return {'name': secgroup['name']} in body['security_groups']
 
-        if not test.call_until_true(wait_for_secgroup_add,
-                                    CONF.compute.build_timeout,
-                                    CONF.compute.build_interval):
+        if not test_utils.call_until_true(wait_for_secgroup_add,
+                                          CONF.compute.build_timeout,
+                                          CONF.compute.build_interval):
             msg = ('Timed out waiting for adding security group %s to server '
                    '%s' % (secgroup['id'], server['id']))
             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..8f27a5d 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -58,7 +58,7 @@
             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']}],
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index e0e1204..519dbec 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -263,8 +263,9 @@
                                   if port['id'] != old_port['id']]
             return len(self.new_port_list) == 1
 
-        if not test.call_until_true(check_ports, CONF.network.build_timeout,
-                                    CONF.network.build_interval):
+        if not test_utils.call_until_true(
+                check_ports, CONF.network.build_timeout,
+                CONF.network.build_interval):
             raise exceptions.TimeoutException(
                 "No new port attached to the server in time (%s sec)! "
                 "Old port: %s. Number of new ports: %d" % (
@@ -277,8 +278,9 @@
             self.diff_list = [n for n in new_nic_list if n not in old_nic_list]
             return len(self.diff_list) == 1
 
-        if not test.call_until_true(check_new_nic, CONF.network.build_timeout,
-                                    CONF.network.build_interval):
+        if not test_utils.call_until_true(
+                check_new_nic, CONF.network.build_timeout,
+                CONF.network.build_interval):
             raise exceptions.TimeoutException("Interface not visible on the "
                                               "guest after %s sec"
                                               % CONF.network.build_timeout)
@@ -593,9 +595,9 @@
                 return False
             return True
 
-        self.assertTrue(test.call_until_true(check_new_dns_server,
-                                             renew_timeout,
-                                             renew_delay),
+        self.assertTrue(test_utils.call_until_true(check_new_dns_server,
+                                                   renew_timeout,
+                                                   renew_delay),
                         msg="DHCP renewal failed to fetch "
                             "new DNS nameservers")
 
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 364b6f5..dd86d90 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -187,10 +187,10 @@
             srv2_v6_addr_assigned = functools.partial(
                 guest_has_address, sshv4_2, ips_from_api_2['6'][i])
 
-            self.assertTrue(test.call_until_true(srv1_v6_addr_assigned,
+            self.assertTrue(test_utils.call_until_true(srv1_v6_addr_assigned,
                             CONF.validation.ping_timeout, 1))
 
-            self.assertTrue(test.call_until_true(srv2_v6_addr_assigned,
+            self.assertTrue(test_utils.call_until_true(srv2_v6_addr_assigned,
                             CONF.validation.ping_timeout, 1))
 
         self._check_connectivity(sshv4_1, ips_from_api_2['4'])
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 60dca3d..e031ff7 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -18,6 +18,7 @@
 
 from tempest import config
 from tempest import exceptions
+from tempest.lib.common.utils import test_utils
 from tempest.scenario import manager
 from tempest import test
 
@@ -70,9 +71,9 @@
                     self.assertEqual(self.fip, result, msg)
                     return 'Verification is successful!'
 
-            if not test.call_until_true(exec_cmd_and_verify_output,
-                                        CONF.compute.build_timeout,
-                                        CONF.compute.build_interval):
+            if not test_utils.call_until_true(exec_cmd_and_verify_output,
+                                              CONF.compute.build_timeout,
+                                              CONF.compute.build_interval):
                 raise exceptions.TimeoutException('Timed out while waiting to '
                                                   'verify metadata on server. '
                                                   '%s is empty.' % md_url)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index e7223c7..5fd934c 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -22,6 +22,7 @@
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest.scenario import manager
@@ -89,9 +90,9 @@
             LOG.debug("Partitions:%s" % part)
             return CONF.compute.volume_device_name in part
 
-        if not test.call_until_true(_func,
-                                    CONF.compute.build_timeout,
-                                    CONF.compute.build_interval):
+        if not test_utils.call_until_true(_func,
+                                          CONF.compute.build_timeout,
+                                          CONF.compute.build_interval):
             raise exceptions.TimeoutException
 
     @decorators.skip_because(bug="1205344")
diff --git a/tempest/services/identity/v2/__init__.py b/tempest/services/identity/v2/__init__.py
index ac2a874..b7d3c74 100644
--- a/tempest/services/identity/v2/__init__.py
+++ b/tempest/services/identity/v2/__init__.py
@@ -13,12 +13,12 @@
 # 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
-from tempest.services.identity.v2.json.identity_client import IdentityClient
 
-__all__ = ['EndpointsClient', 'TokenClient', 'IdentityClient', 'RolesClient',
-           'ServicesClient', 'TenantsClient', 'UsersClient']
+__all__ = ['EndpointsClient', 'IdentityClient', 'RolesClient',
+           'ServicesClient', 'TenantsClient', 'TokenClient', 'UsersClient']
diff --git a/tempest/services/identity/v3/__init__.py b/tempest/services/identity/v3/__init__.py
index c77c78d..3f5c3d5 100644
--- a/tempest/services/identity/v3/__init__.py
+++ b/tempest/services/identity/v3/__init__.py
@@ -12,22 +12,24 @@
 # 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
 
-__all__ = ['EndPointsClient', 'PoliciesClient', 'ProjectsClient',
-           'RegionsClient', 'ServicesClient', 'V3TokenClient',
-           'CredentialsClient', 'DomainsClient', 'GroupsClient',
-           'IdentityClient', 'RolesClient', 'TrustsClient', 'UsersClient', ]
+__all__ = ['CredentialsClient', 'EndPointsClient', 'GroupsClient',
+           'IdentityClient', 'InheritedRolesClient', 'PoliciesClient',
+           'ProjectsClient', 'RegionsClient', 'RolesClient', 'ServicesClient',
+           'V3TokenClient', 'TrustsClient', 'UsersClient', 'DomainsClient', ]
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 aab203f..0000000
--- a/tempest/services/identity/v3/json/roles_client.py
+++ /dev/null
@@ -1,315 +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 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):
-        """Get the list of Roles."""
-        resp, body = self.get("roles")
-        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 assign_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 assign_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 assign_group_role_on_project(self, project_id, group_id, role_id):
-        """Add roles to a user 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 assign_group_role_on_domain(self, domain_id, group_id, role_id):
-        """Add roles to a user 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 user 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 user 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 user 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 user 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 user 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 user 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/admin/base_types_client.py b/tempest/services/volume/base/admin/base_types_client.py
deleted file mode 100755
index 83870ae..0000000
--- a/tempest/services/volume/base/admin/base_types_client.py
+++ /dev/null
@@ -1,204 +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 six.moves.urllib import parse as urllib
-
-from tempest.lib.common import rest_client
-from tempest.lib import exceptions as lib_exc
-
-
-class BaseTypesClient(rest_client.RestClient):
-    """Client class to send CRUD Volume Types API requests"""
-
-    def is_resource_deleted(self, resource):
-        # to use this method self.resource must be defined to respective value
-        # Resource is a dictionary containing resource id and type
-        # Resource : {"id" : resource_id
-        #             "type": resource_type}
-        try:
-            if resource['type'] == "volume-type":
-                self.show_volume_type(resource['id'])
-            elif resource['type'] == "encryption-type":
-                body = self.show_encryption_type(resource['id'])
-                if not body:
-                    return True
-            else:
-                msg = (" resource value is either not defined or incorrect.")
-                raise lib_exc.UnprocessableEntity(msg)
-        except lib_exc.NotFound:
-            return True
-        return False
-
-    @property
-    def resource_type(self):
-        """Returns the primary type of resource this client works with."""
-        return 'volume-type/encryption-type'
-
-    def list_volume_types(self, **params):
-        """List all the volume_types created.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#showVolumeTypes
-        """
-        url = 'types'
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_volume_type(self, volume_type_id):
-        """Returns the details of a single volume_type.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#showVolumeType
-        """
-        url = "types/%s" % volume_type_id
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_volume_type(self, **kwargs):
-        """Create volume type.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#createVolumeType
-        """
-        post_body = json.dumps({'volume_type': kwargs})
-        resp, body = self.post('types', post_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_volume_type(self, volume_type_id):
-        """Deletes the Specified Volume_type.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#deleteVolumeType
-        """
-        resp, body = self.delete("types/%s" % volume_type_id)
-        self.expected_success(202, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_volume_types_extra_specs(self, volume_type_id, **params):
-        """List all the volume_types extra specs created.
-
-        TODO: Current api-site doesn't contain this API description.
-        After fixing the api-site, we need to fix here also for putting
-        the link to api-site.
-        """
-        url = 'types/%s/extra_specs' % volume_type_id
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_volume_type_extra_specs(self, volume_type_id, extra_specs_name):
-        """Returns the details of a single volume_type extra spec."""
-        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_specs_name)
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_volume_type_extra_specs(self, volume_type_id, extra_specs):
-        """Creates a new Volume_type extra spec.
-
-        volume_type_id: Id of volume_type.
-        extra_specs: A dictionary of values to be used as extra_specs.
-        """
-        url = "types/%s/extra_specs" % volume_type_id
-        post_body = json.dumps({'extra_specs': extra_specs})
-        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_type_extra_specs(self, volume_type_id, extra_spec_name):
-        """Deletes the Specified Volume_type extra spec."""
-        resp, body = self.delete("types/%s/extra_specs/%s" % (
-            volume_type_id, extra_spec_name))
-        self.expected_success(202, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def update_volume_type(self, volume_type_id, **kwargs):
-        """Updates volume type name, description, and/or is_public.
-
-        Available params: see http://developer.openstack.org/
-        api-ref-blockstorage-v2.html#updateVolumeType
-        """
-        put_body = json.dumps({'volume_type': kwargs})
-        resp, body = self.put('types/%s' % volume_type_id, put_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def update_volume_type_extra_specs(self, volume_type_id, extra_spec_name,
-                                       extra_specs):
-        """Update a volume_type extra spec.
-
-        volume_type_id: Id of volume_type.
-        extra_spec_name: Name of the extra spec to be updated.
-        extra_spec: A dictionary of with key as extra_spec_name and the
-                     updated value.
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#
-                              updateVolumeTypeExtraSpecs
-        """
-        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_spec_name)
-        put_body = json.dumps(extra_specs)
-        resp, body = self.put(url, put_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_encryption_type(self, volume_type_id):
-        """Get the volume encryption type for the specified volume type.
-
-        volume_type_id: Id of volume_type.
-        """
-        url = "/types/%s/encryption" % volume_type_id
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_encryption_type(self, volume_type_id, **kwargs):
-        """Create encryption type.
-
-        TODO: Current api-site doesn't contain this API description.
-        After fixing the api-site, we need to fix here also for putting
-        the link to api-site.
-        """
-        url = "/types/%s/encryption" % volume_type_id
-        post_body = json.dumps({'encryption': kwargs})
-        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_encryption_type(self, volume_type_id):
-        """Delete the encryption type for the specified volume-type."""
-        resp, body = self.delete(
-            "/types/%s/encryption/provider" % volume_type_id)
-        self.expected_success(202, resp.status)
-        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/base/base_qos_client.py b/tempest/services/volume/base/base_qos_client.py
index e00ac68..0ce76a7 100644
--- a/tempest/services/volume/base/base_qos_client.py
+++ b/tempest/services/volume/base/base_qos_client.py
@@ -12,11 +12,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
 
@@ -36,37 +33,6 @@
         """Returns the primary type of resource this client works with."""
         return 'qos'
 
-    def wait_for_qos_operations(self, qos_id, operation, args=None):
-        """Waits for a qos operations to be completed.
-
-        NOTE : operation value is required for  wait_for_qos_operations()
-        operation = 'qos-key' / 'disassociate' / 'disassociate-all'
-        args = keys[] when operation = 'qos-key'
-        args = volume-type-id disassociated when operation = 'disassociate'
-        args = None when operation = 'disassociate-all'
-        """
-        start_time = int(time.time())
-        while True:
-            if operation == 'qos-key-unset':
-                body = self.show_qos(qos_id)['qos_specs']
-                if not any(key in body['specs'] for key in args):
-                    return
-            elif operation == 'disassociate':
-                body = self.show_association_qos(qos_id)['qos_associations']
-                if not any(args in body[i]['id'] for i in range(0, len(body))):
-                    return
-            elif operation == 'disassociate-all':
-                body = self.show_association_qos(qos_id)['qos_associations']
-                if not body:
-                    return
-            else:
-                msg = (" operation value is either not defined or incorrect.")
-                raise lib_exc.UnprocessableEntity(msg)
-
-            if int(time.time()) - start_time >= self.build_timeout:
-                raise exceptions.TimeoutException
-            time.sleep(self.build_interval)
-
     def create_qos(self, **kwargs):
         """Create a QoS Specification.
 
diff --git a/tempest/services/volume/base/base_volumes_client.py b/tempest/services/volume/base/base_volumes_client.py
index 8130089..11b6e1a 100755
--- a/tempest/services/volume/base/base_volumes_client.py
+++ b/tempest/services/volume/base/base_volumes_client.py
@@ -26,16 +26,6 @@
 
     create_resp = 200
 
-    def __init__(self, auth_provider, service, region,
-                 default_volume_size=1, **kwargs):
-        super(BaseVolumesClient, self).__init__(
-            auth_provider, service, region, **kwargs)
-        self.default_volume_size = default_volume_size
-
-    def get_attachment_from_volume(self, volume):
-        """Return the element 'attachment' from input volumes."""
-        return volume['attachments'][0]
-
     def _prepare_params(self, params):
         """Prepares params for use in get or _ext_get methods.
 
@@ -62,21 +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.
 
@@ -104,8 +79,6 @@
         Available params: see http://developer.openstack.org/
                               api-ref-blockstorage-v2.html#createVolume
         """
-        if 'size' not in kwargs:
-            kwargs['size'] = self.default_volume_size
         post_body = json.dumps({'volume': kwargs})
         resp, body = self.post('volumes', post_body)
         body = json.loads(body)
@@ -328,28 +301,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 945d2f2..72868bc 100644
--- a/tempest/services/volume/v1/__init__.py
+++ b/tempest/services/volume/v1/__init__.py
@@ -20,10 +20,13 @@
 from tempest.lib.services.volume.v1.services_client import ServicesClient
 from tempest.services.volume.v1.json.admin.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']
+           'QosSpecsClient', 'SnapshotsClient', 'VolumesClient',
+           'EncryptionTypesClient']
diff --git a/tempest/services/volume/v1/json/admin/types_client.py b/tempest/services/volume/v1/json/admin/types_client.py
index 0e84296..dce728d 100644
--- a/tempest/services/volume/v1/json/admin/types_client.py
+++ b/tempest/services/volume/v1/json/admin/types_client.py
@@ -13,8 +13,148 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.base.admin import base_types_client
+from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest.lib.common import rest_client
+from tempest.lib import exceptions as lib_exc
 
 
-class TypesClient(base_types_client.BaseTypesClient):
-    """Volume V1 Volume Types client"""
+class TypesClient(rest_client.RestClient):
+    """Client class to send CRUD Volume Types API requests"""
+
+    def is_resource_deleted(self, id):
+        try:
+            self.show_volume_type(id)
+        except lib_exc.NotFound:
+            return True
+        return False
+
+    @property
+    def resource_type(self):
+        """Returns the primary type of resource this client works with."""
+        return 'volume-type'
+
+    def list_volume_types(self, **params):
+        """List all the volume_types created.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#listVolumeTypes
+        """
+        url = 'types'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_volume_type(self, volume_type_id):
+        """Returns the details of a single volume_type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#showVolumeType
+        """
+        url = "types/%s" % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_volume_type(self, **kwargs):
+        """Create volume type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#createVolumeType
+        """
+        post_body = json.dumps({'volume_type': kwargs})
+        resp, body = self.post('types', post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_volume_type(self, volume_type_id):
+        """Deletes the Specified Volume_type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#deleteVolumeType
+        """
+        resp, body = self.delete("types/%s" % volume_type_id)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_volume_types_extra_specs(self, volume_type_id, **params):
+        """List all the volume_types extra specs created.
+
+        TODO: Current api-site doesn't contain this API description.
+        After fixing the api-site, we need to fix here also for putting
+        the link to api-site.
+        """
+        url = 'types/%s/extra_specs' % volume_type_id
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_volume_type_extra_specs(self, volume_type_id, extra_specs_name):
+        """Returns the details of a single volume_type extra spec."""
+        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_specs_name)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_volume_type_extra_specs(self, volume_type_id, extra_specs):
+        """Creates a new Volume_type extra spec.
+
+        volume_type_id: Id of volume_type.
+        extra_specs: A dictionary of values to be used as extra_specs.
+        """
+        url = "types/%s/extra_specs" % volume_type_id
+        post_body = json.dumps({'extra_specs': extra_specs})
+        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_type_extra_specs(self, volume_type_id, extra_spec_name):
+        """Deletes the Specified Volume_type extra spec."""
+        resp, body = self.delete("types/%s/extra_specs/%s" % (
+            volume_type_id, extra_spec_name))
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_volume_type(self, volume_type_id, **kwargs):
+        """Updates volume type name, description, and/or is_public.
+
+        Available params: see http://developer.openstack.org/
+        api-ref-blockstorage-v2.html#updateVolumeType
+        """
+        put_body = json.dumps({'volume_type': kwargs})
+        resp, body = self.put('types/%s' % volume_type_id, put_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_volume_type_extra_specs(self, volume_type_id, extra_spec_name,
+                                       extra_specs):
+        """Update a volume_type extra spec.
+
+        volume_type_id: Id of volume_type.
+        extra_spec_name: Name of the extra spec to be updated.
+        extra_spec: A dictionary of with key as extra_spec_name and the
+                     updated value.
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#
+                              updateVolumeTypeExtraSpecs
+        """
+        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_spec_name)
+        put_body = json.dumps(extra_specs)
+        resp, body = self.put(url, put_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/v1/json/encryption_types_client.py b/tempest/services/volume/v1/json/encryption_types_client.py
new file mode 100755
index 0000000..067b4e8
--- /dev/null
+++ b/tempest/services/volume/v1/json/encryption_types_client.py
@@ -0,0 +1,68 @@
+# 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.lib import exceptions as lib_exc
+
+
+class EncryptionTypesClient(rest_client.RestClient):
+
+    def is_resource_deleted(self, id):
+        try:
+            body = self.show_encryption_type(id)
+            if not body:
+                return True
+        except lib_exc.NotFound:
+            return True
+        return False
+
+    @property
+    def resource_type(self):
+        """Returns the primary type of resource this client works with."""
+        return 'encryption-type'
+
+    def show_encryption_type(self, volume_type_id):
+        """Get the volume encryption type for the specified volume type.
+
+        volume_type_id: Id of volume_type.
+        """
+        url = "/types/%s/encryption" % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_encryption_type(self, volume_type_id, **kwargs):
+        """Create encryption type.
+
+        TODO: Current api-site doesn't contain this API description.
+        After fixing the api-site, we need to fix here also for putting
+        the link to api-site.
+        """
+        url = "/types/%s/encryption" % volume_type_id
+        post_body = json.dumps({'encryption': kwargs})
+        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_encryption_type(self, volume_type_id):
+        """Delete the encryption type for the specified volume-type."""
+        resp, body = self.delete(
+            "/types/%s/encryption/provider" % volume_type_id)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/v2/__init__.py b/tempest/services/volume/v2/__init__.py
index 80f7a94..4afcc29 100644
--- a/tempest/services/volume/v2/__init__.py
+++ b/tempest/services/volume/v2/__init__.py
@@ -20,10 +20,13 @@
 from tempest.lib.services.volume.v2.services_client import ServicesClient
 from tempest.services.volume.v2.json.admin.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']
+           'QosSpecsClient', 'SnapshotsClient', 'VolumesClient',
+           'EncryptionTypesClient']
diff --git a/tempest/services/volume/v2/json/admin/types_client.py b/tempest/services/volume/v2/json/admin/types_client.py
index f76e8dc..d399e99 100644
--- a/tempest/services/volume/v2/json/admin/types_client.py
+++ b/tempest/services/volume/v2/json/admin/types_client.py
@@ -14,15 +14,152 @@
 #    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
-from tempest.services.volume.base.admin import base_types_client
+from tempest.lib import exceptions as lib_exc
 
 
-class TypesClient(base_types_client.BaseTypesClient):
+class TypesClient(rest_client.RestClient):
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
 
+    def is_resource_deleted(self, id):
+        try:
+            self.show_volume_type(id)
+        except lib_exc.NotFound:
+            return True
+        return False
+
+    @property
+    def resource_type(self):
+        """Returns the primary type of resource this client works with."""
+        return 'volume-type'
+
+    def list_volume_types(self, **params):
+        """List all the volume_types created.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#showVolumeTypes
+        """
+        url = 'types'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_volume_type(self, volume_type_id):
+        """Returns the details of a single volume_type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#showVolumeType
+        """
+        url = "types/%s" % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_volume_type(self, **kwargs):
+        """Create volume type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#createVolumeType
+        """
+        post_body = json.dumps({'volume_type': kwargs})
+        resp, body = self.post('types', post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_volume_type(self, volume_type_id):
+        """Deletes the Specified Volume_type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#deleteVolumeType
+        """
+        resp, body = self.delete("types/%s" % volume_type_id)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_volume_types_extra_specs(self, volume_type_id, **params):
+        """List all the volume_types extra specs created.
+
+        TODO: Current api-site doesn't contain this API description.
+        After fixing the api-site, we need to fix here also for putting
+        the link to api-site.
+        """
+        url = 'types/%s/extra_specs' % volume_type_id
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_volume_type_extra_specs(self, volume_type_id, extra_specs_name):
+        """Returns the details of a single volume_type extra spec."""
+        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_specs_name)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_volume_type_extra_specs(self, volume_type_id, extra_specs):
+        """Creates a new Volume_type extra spec.
+
+        volume_type_id: Id of volume_type.
+        extra_specs: A dictionary of values to be used as extra_specs.
+        """
+        url = "types/%s/extra_specs" % volume_type_id
+        post_body = json.dumps({'extra_specs': extra_specs})
+        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_type_extra_specs(self, volume_type_id, extra_spec_name):
+        """Deletes the Specified Volume_type extra spec."""
+        resp, body = self.delete("types/%s/extra_specs/%s" % (
+            volume_type_id, extra_spec_name))
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_volume_type(self, volume_type_id, **kwargs):
+        """Updates volume type name, description, and/or is_public.
+
+        Available params: see http://developer.openstack.org/
+        api-ref-blockstorage-v2.html#updateVolumeType
+        """
+        put_body = json.dumps({'volume_type': kwargs})
+        resp, body = self.put('types/%s' % volume_type_id, put_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_volume_type_extra_specs(self, volume_type_id, extra_spec_name,
+                                       extra_specs):
+        """Update a volume_type extra spec.
+
+        volume_type_id: Id of volume_type.
+        extra_spec_name: Name of the extra spec to be updated.
+        extra_spec: A dictionary of with key as extra_spec_name and the
+                     updated value.
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#
+                              updateVolumeTypeExtraSpecs
+        """
+        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_spec_name)
+        put_body = json.dumps(extra_specs)
+        resp, body = self.put(url, put_body)
+        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.
 
diff --git a/tempest/services/volume/v2/json/encryption_types_client.py b/tempest/services/volume/v2/json/encryption_types_client.py
new file mode 100755
index 0000000..8b01f11
--- /dev/null
+++ b/tempest/services/volume/v2/json/encryption_types_client.py
@@ -0,0 +1,69 @@
+# 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.lib import exceptions as lib_exc
+
+
+class EncryptionTypesClient(rest_client.RestClient):
+    api_version = "v2"
+
+    def is_resource_deleted(self, id):
+        try:
+            body = self.show_encryption_type(id)
+            if not body:
+                return True
+        except lib_exc.NotFound:
+            return True
+        return False
+
+    @property
+    def resource_type(self):
+        """Returns the primary type of resource this client works with."""
+        return 'encryption-type'
+
+    def show_encryption_type(self, volume_type_id):
+        """Get the volume encryption type for the specified volume type.
+
+        volume_type_id: Id of volume_type.
+        """
+        url = "/types/%s/encryption" % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_encryption_type(self, volume_type_id, **kwargs):
+        """Create encryption type.
+
+        TODO: Current api-site doesn't contain this API description.
+        After fixing the api-site, we need to fix here also for putting
+        the link to api-site.
+        """
+        url = "/types/%s/encryption" % volume_type_id
+        post_body = json.dumps({'encryption': kwargs})
+        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_encryption_type(self, volume_type_id):
+        """Delete the encryption type for the specified volume-type."""
+        resp, body = self.delete(
+            "/types/%s/encryption/provider" % volume_type_id)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/v2/json/volumes_client.py b/tempest/services/volume/v2/json/volumes_client.py
index b7d9dfb..2a435e7 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,36 @@
     """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)
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 4f8c6bd..845b4a7 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -16,8 +16,8 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
+from tempest.lib.common.utils import test_utils
 import tempest.stress.stressaction as stressaction
-import tempest.test
 
 CONF = config.CONF
 
@@ -52,8 +52,8 @@
     def check_port_ssh(self):
         def func():
             return self.tcp_connect_scan(self.floating['ip'], 22)
-        if not tempest.test.call_until_true(func, self.check_timeout,
-                                            self.check_interval):
+        if not test_utils.call_until_true(func, self.check_timeout,
+                                          self.check_interval):
             raise RuntimeError("Cannot connect to the ssh port.")
 
     def check_icmp_echo(self):
@@ -62,15 +62,16 @@
 
         def func():
             return self.ping_ip_address(self.floating['ip'])
-        if not tempest.test.call_until_true(func, self.check_timeout,
-                                            self.check_interval):
+        if not test_utils.call_until_true(func, self.check_timeout,
+                                          self.check_interval):
             raise RuntimeError("%s(%s): Cannot ping the machine.",
                                self.server_id, self.floating['ip'])
         self.logger.info("%s(%s): pong :)",
                          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']
@@ -153,8 +154,8 @@
                         ['floating_ip'])
             return floating['instance_id'] is None
 
-        if not tempest.test.call_until_true(func, self.check_timeout,
-                                            self.check_interval):
+        if not test_utils.call_until_true(func, self.check_timeout,
+                                          self.check_interval):
             raise RuntimeError("IP disassociate timeout!")
 
     def run_core(self):
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index 847f342..5fc006e 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -27,16 +27,16 @@
 
     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)['volume']
+            display_name=name, size=CONF.volume.volume_size)['volume']
         self.manager.volumes_client.wait_for_volume_status(volume['id'],
                                                            'available')
         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 8bbbfc4..4fbb851 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -16,8 +16,8 @@
 from tempest.common.utils.linux import remote_client
 from tempest.common import waiters
 from tempest import config
+from tempest.lib.common.utils import test_utils
 import tempest.stress.stressaction as stressaction
-import tempest.test
 
 CONF = config.CONF
 
@@ -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,11 +82,11 @@
         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(
-            display_name=name)['volume']
+            display_name=name, size=CONF.volume.volume_size)['volume']
         volumes_client.wait_for_volume_status(self.volume['id'],
                                               'available')
         self.logger.info("created volume: %s" % self.volume['id'])
@@ -105,8 +106,8 @@
                         ['floating_ip'])
             return floating['instance_id'] is None
 
-        if not tempest.test.call_until_true(func, CONF.compute.build_timeout,
-                                            CONF.compute.build_interval):
+        if not test_utils.call_until_true(func, CONF.compute.build_timeout,
+                                          CONF.compute.build_interval):
             raise RuntimeError("IP disassociate timeout!")
 
     def new_server_ops(self):
@@ -179,9 +180,9 @@
                 if self.part_line_re.match(part_line):
                     matching += 1
             return matching == num_match
-        if tempest.test.call_until_true(_part_state,
-                                        CONF.compute.build_timeout,
-                                        CONF.compute.build_interval):
+        if test_utils.call_until_true(_part_state,
+                                      CONF.compute.build_timeout,
+                                      CONF.compute.build_interval):
             return
         else:
             raise RuntimeError("Unexpected partitions: %s",
diff --git a/tempest/stress/actions/volume_create_delete.py b/tempest/stress/actions/volume_create_delete.py
index 3986748..66971ea 100644
--- a/tempest/stress/actions/volume_create_delete.py
+++ b/tempest/stress/actions/volume_create_delete.py
@@ -11,8 +11,11 @@
 #    limitations under the License.
 
 from tempest.common.utils import data_utils
+from tempest import config
 import tempest.stress.stressaction as stressaction
 
+CONF = config.CONF
+
 
 class VolumeCreateDeleteTest(stressaction.StressAction):
 
@@ -20,7 +23,8 @@
         name = data_utils.rand_name("volume")
         self.logger.info("creating %s" % name)
         volumes_client = self.manager.volumes_client
-        volume = volumes_client.create_volume(display_name=name)['volume']
+        volume = volumes_client.create_volume(
+            display_name=name, size=CONF.volume.volume_size)['volume']
         vol_id = volume['id']
         volumes_client.wait_for_volume_status(vol_id, 'available')
         self.logger.info("created %s" % volume['id'])
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/test.py b/tempest/test.py
index 97ab25c..609f1f6 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -18,8 +18,8 @@
 import os
 import re
 import sys
-import time
 
+import debtcollector.moves
 import fixtures
 from oslo_log import log as logging
 from oslo_serialization import jsonutils as json
@@ -38,6 +38,7 @@
 from tempest import config
 from tempest import exceptions
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 
@@ -866,22 +867,6 @@
     return klass
 
 
-def call_until_true(func, duration, sleep_for):
-    """Call the given function until it returns True (and return True)
-
-    or until the specified duration (in seconds) elapses (and return False).
-
-    :param func: A zero argument callable that returns True on success.
-    :param duration: The number of seconds for which to attempt a
-        successful call of the function.
-    :param sleep_for: The number of seconds to sleep after an unsuccessful
-                      invocation of the function.
-    """
-    now = time.time()
-    timeout = now + duration
-    while now < timeout:
-        if func():
-            return True
-        time.sleep(sleep_for)
-        now = time.time()
-    return False
+call_until_true = debtcollector.moves.moved_function(
+    test_utils.call_until_true, 'call_until_true', __name__,
+    version='Newton', removal_version='Ocata')
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index e7b9a4c..0033d4e 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -22,20 +22,21 @@
 from tempest import exceptions
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions as lib_exc
+from tempest.lib.services.identity.v2 import identity_client as v2_iden_client
 from tempest.lib.services.identity.v2 import roles_client as v2_roles_client
 from tempest.lib.services.identity.v2 import tenants_client as \
     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.v2.json import identity_client as v2_iden_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
@@ -55,7 +56,6 @@
     users_client = v2_users_client
     token_client_class = token_client.TokenClient
     fake_response = fake_identity._fake_v2_response
-    assign_role_on_project = 'create_user_role_on_project'
     tenants_client_class = tenants_client.TenantsClient
     delete_tenant = 'delete_tenant'
 
@@ -125,7 +125,7 @@
     def _mock_assign_user_role(self):
         tenant_fix = self.useFixture(mockpatch.PatchObject(
             self.roles_client.RolesClient,
-            self.assign_role_on_project,
+            'create_user_role_on_project',
             return_value=(rest_client.ResponseBody
                           (200, {}))))
         return tenant_fix
@@ -198,11 +198,11 @@
         self._mock_tenant_create('1234', 'fake_admin_tenant')
 
         user_mock = mock.patch.object(self.roles_client.RolesClient,
-                                      self.assign_role_on_project)
+                                      'create_user_role_on_project')
         user_mock.start()
         self.addCleanup(user_mock.stop)
         with mock.patch.object(self.roles_client.RolesClient,
-                               self.assign_role_on_project) as user_mock:
+                               'create_user_role_on_project') as user_mock:
             admin_creds = creds.get_admin_creds()
         user_mock.assert_has_calls([
             mock.call('1234', '1234', '1234')])
@@ -221,11 +221,11 @@
         self._mock_tenant_create('1234', 'fake_role_tenant')
 
         user_mock = mock.patch.object(self.roles_client.RolesClient,
-                                      self.assign_role_on_project)
+                                      'create_user_role_on_project')
         user_mock.start()
         self.addCleanup(user_mock.stop)
         with mock.patch.object(self.roles_client.RolesClient,
-                               self.assign_role_on_project) as user_mock:
+                               'create_user_role_on_project') as user_mock:
             role_creds = creds.get_creds_by_roles(
                 roles=['role1', 'role2'])
         calls = user_mock.mock_calls
@@ -612,7 +612,6 @@
     users_client = v3_users_client
     token_client_class = token_client.V3TokenClient
     fake_response = fake_identity._fake_v3_response
-    assign_role_on_project = 'assign_user_role_on_project'
     tenants_client_class = tenants_client.ProjectsClient
     delete_tenant = 'delete_project'
 
@@ -624,7 +623,7 @@
             return_value=dict(domains=[dict(id='default',
                                             name='Default')])))
         self.patchobject(self.roles_client.RolesClient,
-                         'assign_user_role_on_domain')
+                         'create_user_role_on_domain')
 
     def _mock_list_ec2_credentials(self, user_id, tenant_id):
         pass
diff --git a/tempest/tests/fake_auth_provider.py b/tempest/tests/fake_auth_provider.py
index 769f6a6..21bd8c6 100644
--- a/tempest/tests/fake_auth_provider.py
+++ b/tempest/tests/fake_auth_provider.py
@@ -16,9 +16,6 @@
 
 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"
 
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/common/utils/test_test_utils.py b/tempest/tests/lib/common/utils/test_test_utils.py
index 919e219..29c5684 100644
--- a/tempest/tests/lib/common/utils/test_test_utils.py
+++ b/tempest/tests/lib/common/utils/test_test_utils.py
@@ -17,6 +17,7 @@
 from tempest.lib.common.utils import test_utils
 from tempest.lib import exceptions
 from tempest.tests import base
+from tempest.tests import utils
 
 
 class TestTestUtils(base.TestCase):
@@ -76,3 +77,27 @@
         self.assertEqual(
             42, test_utils.call_and_ignore_notfound_exc(m, *args, **kwargs))
         m.assert_called_once_with(*args, **kwargs)
+
+    @mock.patch('time.sleep')
+    @mock.patch('time.time')
+    def test_call_until_true_when_f_never_returns_true(self, m_time, m_sleep):
+        timeout = 42  # The value doesn't matter as we mock time.time()
+        sleep = 60  # The value doesn't matter as we mock time.sleep()
+        m_time.side_effect = utils.generate_timeout_series(timeout)
+        self.assertEqual(
+            False, test_utils.call_until_true(lambda: False, timeout, sleep)
+        )
+        m_sleep.call_args_list = [mock.call(sleep)] * 2
+        m_time.call_args_list = [mock.call()] * 2
+
+    @mock.patch('time.sleep')
+    @mock.patch('time.time')
+    def test_call_until_true_when_f_returns_true(self, m_time, m_sleep):
+        timeout = 42  # The value doesn't matter as we mock time.time()
+        sleep = 60  # The value doesn't matter as we mock time.sleep()
+        m_time.return_value = 0
+        self.assertEqual(
+            True, test_utils.call_until_true(lambda: True, timeout, sleep)
+        )
+        self.assertEqual(0, m_sleep.call_count)
+        self.assertEqual(1, m_time.call_count)
diff --git a/tempest/tests/lib/services/base.py b/tempest/tests/lib/services/base.py
index a244aa2..3165689 100644
--- a/tempest/tests/lib/services/base.py
+++ b/tempest/tests/lib/services/base.py
@@ -12,6 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import copy
 from oslo_serialization import jsonutils as json
 from oslotest import mockpatch
 
@@ -31,7 +32,7 @@
 
     def check_service_client_function(self, function, function2mock,
                                       body, to_utf=False, status=200,
-                                      headers=None, **kwargs):
+                                      headers=None, cr_blob=False, **kwargs):
         mocked_response = self.create_response(body, to_utf, status, headers)
         self.useFixture(mockpatch.Patch(
             function2mock, return_value=mocked_response))
@@ -39,4 +40,11 @@
             resp = function(**kwargs)
         else:
             resp = function()
-        self.assertEqual(body, resp)
+
+        if cr_blob:
+            evaluated_body = copy.deepcopy(body)
+            nested_json = json.loads(evaluated_body['credential']['blob'])
+            evaluated_body['credential']['blob'] = nested_json
+            self.assertEqual(evaluated_body, resp)
+        else:
+            self.assertEqual(body, resp)
diff --git a/tempest/tests/lib/services/identity/v2/test_identity_client.py b/tempest/tests/lib/services/identity/v2/test_identity_client.py
new file mode 100644
index 0000000..96d50d7
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v2/test_identity_client.py
@@ -0,0 +1,175 @@
+# 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.v2 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"
+    }
+
+    FAKE_LIST_EXTENSIONS = {
+        "extensions": {
+            "values": [
+                {
+                    "updated": "2013-07-07T12:00:0-00:00",
+                    "name": "OpenStack S3 API",
+                    "links": [
+                        {
+                            "href": "https://github.com/openstack/" +
+                                    "identity-api",
+                            "type": "text/html",
+                            "rel": "describedby"
+                        }
+                    ],
+                    "namespace": "http://docs.openstack.org/identity/" +
+                                 "api/ext/s3tokens/v1.0",
+                    "alias": "s3tokens",
+                    "description": "OpenStack S3 API."
+                },
+                {
+                    "updated": "2013-12-17T12:00:0-00:00",
+                    "name": "OpenStack Federation APIs",
+                    "links": [
+                        {
+                            "href": "https://github.com/openstack/" +
+                                    "identity-api",
+                            "type": "text/html",
+                            "rel": "describedby"
+                        }
+                    ],
+                    "namespace": "http://docs.openstack.org/identity/" +
+                                 "api/ext/OS-FEDERATION/v1.0",
+                    "alias": "OS-FEDERATION",
+                    "description": "OpenStack Identity Providers Mechanism."
+                },
+                {
+                    "updated": "2014-01-20T12:00:0-00:00",
+                    "name": "OpenStack Simple Certificate API",
+                    "links": [
+                        {
+                            "href": "https://github.com/openstack/" +
+                                    "identity-api",
+                            "type": "text/html",
+                            "rel": "describedby"
+                        }
+                    ],
+                    "namespace": "http://docs.openstack.org/identity/api/" +
+                                 "ext/OS-SIMPLE-CERT/v1.0",
+                    "alias": "OS-SIMPLE-CERT",
+                    "description": "OpenStack simple certificate extension"
+                },
+                {
+                    "updated": "2013-07-07T12:00:0-00:00",
+                    "name": "OpenStack OAUTH1 API",
+                    "links": [
+                        {
+                            "href": "https://github.com/openstack/" +
+                                    "identity-api",
+                            "type": "text/html",
+                            "rel": "describedby"
+                        }
+                    ],
+                    "namespace": "http://docs.openstack.org/identity/" +
+                                 "api/ext/OS-OAUTH1/v1.0",
+                    "alias": "OS-OAUTH1",
+                    "description": "OpenStack OAuth Delegated Auth Mechanism."
+                },
+                {
+                    "updated": "2013-07-07T12:00:0-00:00",
+                    "name": "OpenStack EC2 API",
+                    "links": [
+                        {
+                            "href": "https://github.com/openstack/" +
+                                    "identity-api",
+                            "type": "text/html",
+                            "rel": "describedby"
+                        }
+                    ],
+                    "namespace": "http://docs.openstack.org/identity/api/" +
+                                 "ext/OS-EC2/v1.0",
+                    "alias": "OS-EC2",
+                    "description": "OpenStack EC2 Credentials backend."
+                }
+            ]
+        }
+    }
+
+    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_list_extensions(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_extensions,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_LIST_EXTENSIONS,
+            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,
+            token_id="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_list_extensions_with_str_body(self):
+        self._test_list_extensions()
+
+    def test_show_list_extensions_with_bytes_body(self):
+        self._test_list_extensions(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',
+            {},
+            token_id="cbc36478b0bd8e67e89",
+            status=204)
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..a2a22ff
--- /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, cr_blob=True)
+
+    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, cr_blob=True,
+            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, cr_blob=True,
+            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')