Merge "Move method to v2 volumes_client"
diff --git a/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
index d1635e3..9e828f6 100644
--- a/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
+++ b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
@@ -1,11 +1,15 @@
 ---
 features:
   - |
-    Define identity service clients as libraries
+    Define identity service clients as libraries.
     Add new service clients to the library interface so the other projects can use these modules as stable libraries without
     any maintenance changes.
 
       * identity_client(v2)
       * groups_client(v3)
+      * trusts_client(v3)
       * users_client(v3)
       * identity_client(v3)
+      * roles_client(v3)
+      * inherited_roles_client(v3)
+      * credentials_client(v3)
diff --git a/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/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 7c13ef0..ff5dc49 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -57,13 +57,6 @@
             waiters.wait_for_volume_status(self.volumes_client,
                                            volume_id, 'available')
 
-    def _delete_volume(self):
-        # Delete the created Volumes
-        if self.volume:
-            self.volumes_client.delete_volume(self.volume['id'])
-            self.volumes_client.wait_for_resource_deletion(self.volume['id'])
-            self.volume = None
-
     def _create_server(self):
         # Start a server and wait for it to become ready
         server = self.create_test_server(
@@ -78,28 +71,29 @@
 
     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')
+                                       volume['id'], 'available')
 
         # Attach the volume to the server
         self.attachment = self.servers_client.attach_volume(
             server['id'],
-            volumeId=self.volume['id'],
+            volumeId=volume['id'],
             device='/dev/%s' % self.device)['volumeAttachment']
         waiters.wait_for_volume_status(self.volumes_client,
-                                       self.volume['id'], 'in-use')
+                                       volume['id'], 'in-use')
 
-        self.addCleanup(self._detach, server['id'], self.volume['id'])
+        self.addCleanup(self._detach, server['id'], volume['id'])
+        return volume
 
     @test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
     def test_attach_detach_volume(self):
         # Stop and Start a server with an attached volume, ensuring that
         # the volume remains attached.
         server = self._create_server()
-        self._create_and_attach_volume(server)
+        volume = self._create_and_attach_volume(server)
 
         self.servers_client.stop_server(server['id'])
         waiters.wait_for_server_status(self.servers_client, server['id'],
@@ -122,7 +116,7 @@
             device_name_to_match = ' ' + self.device + '\n'
             self.assertIn(device_name_to_match, partitions)
 
-        self._detach(server['id'], self.volume['id'])
+        self._detach(server['id'], volume['id'])
         self.attachment = None
         self.servers_client.stop_server(server['id'])
         waiters.wait_for_server_status(self.servers_client, server['id'],
@@ -148,7 +142,7 @@
     def test_list_get_volume_attachments(self):
         # Create Server, Volume and attach that Volume to Server
         server = self._create_server()
-        self._create_and_attach_volume(server)
+        volume = self._create_and_attach_volume(server)
 
         # List Volume attachment of the server
         body = self.servers_client.list_volume_attachments(
@@ -161,7 +155,7 @@
             server['id'],
             self.attachment['id'])['volumeAttachment']
         self.assertEqual(server['id'], body['serverId'])
-        self.assertEqual(self.volume['id'], body['volumeId'])
+        self.assertEqual(volume['id'], body['volumeId'])
         self.assertEqual(self.attachment['id'], body['id'])
 
 
@@ -254,10 +248,10 @@
         server = self._create_server()
         num_vol = self._count_volumes(server)
         self._shelve_server(server)
-        self._create_and_attach_volume(server)
+        volume = self._create_and_attach_volume(server)
 
         # Detach the volume
-        self._detach(server['id'], self.volume['id'])
+        self._detach(server['id'], volume['id'])
         self.attachment = None
 
         # Unshelve the instance and check that we have the expected number of
diff --git a/tempest/api/identity/admin/v2/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
index 380920f..d284aac 100644
--- a/tempest/api/identity/admin/v2/test_roles.py
+++ b/tempest/api/identity/admin/v2/test_roles.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
-
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
@@ -27,7 +25,7 @@
     def resource_setup(cls):
         super(RolesTestJSON, cls).resource_setup()
         cls.roles = list()
-        for _ in moves.xrange(5):
+        for _ in range(5):
             role_name = data_utils.rand_name(name='role')
             role = cls.roles_client.create_role(name=role_name)['role']
             cls.roles.append(role)
diff --git a/tempest/api/identity/admin/v2/test_services.py b/tempest/api/identity/admin/v2/test_services.py
index 94291f8..3ed51f0 100644
--- a/tempest/api/identity/admin/v2/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
-
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest.lib import exceptions as lib_exc
@@ -84,7 +82,7 @@
     def test_list_services(self):
         # Create, List, Verify and Delete Services
         services = []
-        for _ in moves.xrange(3):
+        for _ in range(3):
             name = data_utils.rand_name('service')
             s_type = data_utils.rand_name('type')
             description = data_utils.rand_name('description')
diff --git a/tempest/api/identity/admin/v2/test_tenants.py b/tempest/api/identity/admin/v2/test_tenants.py
index 4faf184..f4fad53 100644
--- a/tempest/api/identity/admin/v2/test_tenants.py
+++ b/tempest/api/identity/admin/v2/test_tenants.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
-
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
@@ -27,7 +25,7 @@
     def test_tenant_list_delete(self):
         # Create several tenants and delete them
         tenants = []
-        for _ in moves.xrange(3):
+        for _ in range(3):
             tenant_name = data_utils.rand_name(name='tenant-new')
             tenant = self.tenants_client.create_tenant(
                 name=tenant_name)['tenant']
diff --git a/tempest/api/identity/admin/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/base.py b/tempest/api/identity/base.py
index 9e40c42..f5e4943 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -173,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
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 9e9f08b..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)
@@ -140,7 +139,8 @@
     @test.idempotent_id('5cfa4ab2-4373-48dd-a41f-a532b12b08b2')
     def test_list_containers_with_limit(self):
         # list containers one of them, half of them then all of them
-        for limit in (1, self.containers_count / 2, self.containers_count):
+        for limit in (1, self.containers_count // 2,
+                      self.containers_count):
             params = {'limit': limit}
             resp, container_list = \
                 self.account_client.list_account_containers(params=params)
@@ -161,12 +161,13 @@
 
         self.assertEqual(len(container_list), 0)
 
-        params = {'marker': self.containers[self.containers_count / 2]}
+        params = {'marker': self.containers[self.containers_count // 2]}
         resp, container_list = \
             self.account_client.list_account_containers(params=params)
         self.assertHeaders(resp, 'Account', 'GET')
 
-        self.assertEqual(len(container_list), self.containers_count / 2 - 1)
+        self.assertEqual(len(container_list),
+                         self.containers_count // 2 - 1)
 
     @test.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
     def test_list_containers_with_end_marker(self):
@@ -180,11 +181,11 @@
         self.assertHeaders(resp, 'Account', 'GET')
         self.assertEqual(len(container_list), 0)
 
-        params = {'end_marker': self.containers[self.containers_count / 2]}
+        params = {'end_marker': self.containers[self.containers_count // 2]}
         resp, container_list = \
             self.account_client.list_account_containers(params=params)
         self.assertHeaders(resp, 'Account', 'GET')
-        self.assertEqual(len(container_list), self.containers_count / 2)
+        self.assertEqual(len(container_list), self.containers_count // 2)
 
     @test.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
     def test_list_containers_with_marker_and_end_marker(self):
@@ -215,12 +216,12 @@
         # list containers combining limit and end_marker param
         limit = random.randint(1, self.containers_count)
         params = {'limit': limit,
-                  'end_marker': self.containers[self.containers_count / 2]}
+                  'end_marker': self.containers[self.containers_count // 2]}
         resp, container_list = self.account_client.list_account_containers(
             params=params)
         self.assertHeaders(resp, 'Account', 'GET')
         self.assertEqual(len(container_list),
-                         min(limit, self.containers_count / 2))
+                         min(limit, self.containers_count // 2))
 
     @test.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
     def test_list_containers_with_limit_and_marker_and_end_marker(self):
diff --git a/tempest/api/object_storage/test_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_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/base.py b/tempest/api/volume/base.py
index 183452c..d1549e2 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -175,14 +175,21 @@
             except Exception:
                 pass
 
-    @classmethod
-    def create_server(cls, name, **kwargs):
-        tenant_network = cls.get_tenant_network()
+    def create_server(self, name, wait_for_deletion=False, **kwargs):
+        tenant_network = self.get_tenant_network()
         body, _ = compute.create_test_server(
-            cls.os,
+            self.os,
             tenant_network=tenant_network,
             name=name,
             **kwargs)
+
+        if wait_for_deletion:
+            self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                            waiters.wait_for_server_termination,
+                            self.servers_client, body['id'])
+
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.servers_client.delete_server, body['id'])
         return body
 
 
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 7783c18..b80a4a4 100755
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -45,34 +45,25 @@
     @classmethod
     def resource_setup(cls):
         super(VolumesV2ActionsTest, cls).resource_setup()
-        # Create a test shared instance
-        srv_name = data_utils.rand_name(cls.__name__ + '-Instance')
-        cls.server = cls.create_server(
-            name=srv_name,
-            wait_until='ACTIVE')
 
         # Create a test shared volume for attach/detach tests
         cls.volume = cls.create_volume()
         waiters.wait_for_volume_status(cls.client,
                                        cls.volume['id'], 'available')
 
-    @classmethod
-    def resource_cleanup(cls):
-        # Delete the test instance
-        cls.servers_client.delete_server(cls.server['id'])
-        waiters.wait_for_server_termination(cls.servers_client,
-                                            cls.server['id'])
-
-        super(VolumesV2ActionsTest, cls).resource_cleanup()
-
     @test.idempotent_id('fff42874-7db5-4487-a8e1-ddda5fb5288d')
     @test.stresstest(class_setup_per='process')
     @test.attr(type='smoke')
     @test.services('compute')
     def test_attach_detach_volume_to_instance(self):
+        # Create a server
+        srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
+        server = self.create_server(
+            name=srv_name,
+            wait_until='ACTIVE')
         # Volume is attached and detached successfully from an instance
         self.client.attach_volume(self.volume['id'],
-                                  instance_uuid=self.server['id'],
+                                  instance_uuid=server['id'],
                                   mountpoint='/dev/%s' %
                                              CONF.compute.volume_device_name)
         waiters.wait_for_volume_status(self.client,
@@ -99,9 +90,14 @@
     @test.stresstest(class_setup_per='process')
     @test.services('compute')
     def test_get_volume_attachment(self):
+        # Create a server
+        srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
+        server = self.create_server(
+            name=srv_name,
+            wait_until='ACTIVE')
         # Verify that a volume's attachment information is retrieved
         self.client.attach_volume(self.volume['id'],
-                                  instance_uuid=self.server['id'],
+                                  instance_uuid=server['id'],
                                   mountpoint='/dev/%s' %
                                              CONF.compute.volume_device_name)
         waiters.wait_for_volume_status(self.client,
@@ -119,7 +115,7 @@
         self.assertEqual('/dev/%s' %
                          CONF.compute.volume_device_name,
                          attachment['device'])
-        self.assertEqual(self.server['id'], attachment['server_id'])
+        self.assertEqual(server['id'], attachment['server_id'])
         self.assertEqual(self.volume['id'], attachment['id'])
         self.assertEqual(self.volume['id'], attachment['volume_id'])
 
diff --git a/tempest/api/volume/test_volumes_backup.py b/tempest/api/volume/test_volumes_backup.py
index 50a1360..74078cc 100755
--- a/tempest/api/volume/test_volumes_backup.py
+++ b/tempest/api/volume/test_volumes_backup.py
@@ -91,7 +91,6 @@
         server_name = data_utils.rand_name(
             self.__class__.__name__ + '-instance')
         server = self.create_server(name=server_name, wait_until='ACTIVE')
-        self.addCleanup(self.servers_client.delete_server, server['id'])
         # Attach volume to instance
         self.servers_client.attach_volume(server['id'],
                                           volumeId=volume['id'])
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 16c8571..5bef7f3 100755
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -15,7 +15,6 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest.common import waiters
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -180,10 +179,8 @@
         srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
         server = self.create_server(
             name=srv_name,
+            wait_for_deletion=True,
             wait_until='ACTIVE')
-        self.addCleanup(waiters.wait_for_server_termination,
-                        self.servers_client, server['id'])
-        self.addCleanup(self.servers_client.delete_server, server['id'])
 
         self.assertRaises(lib_exc.NotFound,
                           self.client.attach_volume,
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 20c647a..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):
@@ -80,7 +80,6 @@
         server = self.create_server(
             name=server_name,
             wait_until='ACTIVE')
-        self.addCleanup(self.servers_client.delete_server, server['id'])
         self.servers_client.attach_volume(
             server['id'], volumeId=self.volume_origin['id'],
             device='/dev/%s' % CONF.compute.volume_device_name)
diff --git a/tempest/clients.py b/tempest/clients.py
index f8c276a..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,
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/custom_matchers.py b/tempest/common/custom_matchers.py
index 998612b..b6ff241 100644
--- a/tempest/common/custom_matchers.py
+++ b/tempest/common/custom_matchers.py
@@ -28,7 +28,7 @@
     checked in each test code.
     """
 
-    def __init__(self, target, method):
+    def __init__(self, target, method, policies=None):
         """Initialization of ExistsAllResponseHeaders
 
         param: target Account/Container/Object
@@ -36,6 +36,7 @@
         """
         self.target = target
         self.method = method
+        self.policies = policies or []
 
     def _content_length_required(self, resp):
         # Verify whether given HTTP response must contain content-length.
@@ -84,11 +85,63 @@
                     return NonExistentHeader('x-account-container-count')
                 if 'x-account-object-count' not in actual:
                     return NonExistentHeader('x-account-object-count')
+                if actual['x-account-container-count'] > 0:
+                    acct_header = "x-account-storage-policy-"
+                    matched_policy_count = 0
+
+                    # Loop through the policies and look for account
+                    # usage data.  There should be at least 1 set
+                    for policy in self.policies:
+                        front_header = acct_header + policy['name'].lower()
+
+                        usage_policies = [
+                            front_header + '-bytes-used',
+                            front_header + '-object-count',
+                            front_header + '-container-count'
+                        ]
+
+                        # There should be 3 usage values for a give storage
+                        # policy in an account bytes, object count, and
+                        # container count
+                        policy_hdrs = sum(1 for use_hdr in usage_policies
+                                          if use_hdr in actual)
+
+                        # If there are less than 3 headers here then 1 is
+                        # missing, let's figure out which one and report
+                        if policy_hdrs == 3:
+                            matched_policy_count = matched_policy_count + 1
+                        else:
+                            if policy_hdrs > 0 and policy_hdrs < 3:
+                                for use_hdr in usage_policies:
+                                    if use_hdr not in actual:
+                                        return NonExistentHeader(use_hdr)
+
+                    # Only flag an error if actual policies have been read and
+                    # no usage has been found
+                    if self.policies and matched_policy_count == 0:
+                        return GenericError("No storage policy usage headers")
+
             elif self.target == 'Container':
                 if 'x-container-bytes-used' not in actual:
                     return NonExistentHeader('x-container-bytes-used')
                 if 'x-container-object-count' not in actual:
                     return NonExistentHeader('x-container-object-count')
+                if 'x-storage-policy' not in actual:
+                    return NonExistentHeader('x-storage-policy')
+                else:
+                    policy_name = actual['x-storage-policy']
+
+                    # loop through the policies and ensure that
+                    # the value in the container header matches
+                    # one of the storage policies
+                    for policy in self.policies:
+                        if policy['name'] == policy_name:
+                            break
+                    else:
+                        # Ensure that there are actual policies stored
+                        if self.policies:
+                            return InvalidHeaderValue('x-storage-policy',
+                                                      policy_name)
             elif self.target == 'Object':
                 if 'etag' not in actual:
                     return NonExistentHeader('etag')
@@ -114,6 +167,19 @@
         return None
 
 
+class GenericError(object):
+    """Informs an error message of a generic error during header evaluation"""
+
+    def __init__(self, body):
+        self.body = body
+
+    def describe(self):
+        return "%s" % self.body
+
+    def get_details(self):
+        return {}
+
+
 class NonExistentHeader(object):
     """Informs an error message in the case of missing a certain header"""
 
@@ -127,6 +193,20 @@
         return {}
 
 
+class InvalidHeaderValue(object):
+    """Informs an error message when a header contains a bad value"""
+
+    def __init__(self, header, value):
+        self.header = header
+        self.value = value
+
+    def describe(self):
+        return "InvalidValue (%s, %s)" % (self.header, self.value)
+
+    def get_details(self):
+        return {}
+
+
 class AreAllWellFormatted(object):
     """Specific matcher to check the correctness of formats of values
 
diff --git a/tempest/config.py b/tempest/config.py
index 3fd20ab..1d89eb0 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -370,7 +370,8 @@
                 default=True,
                 help='Enables returning of the instance password by the '
                      'relevant server API calls such as create, rebuild '
-                     'or rescue.'),
+                     'or rescue. This configuration value should be same as '
+                     'nova.conf: DEFAULT.enable_instance_password'),
     cfg.BoolOpt('interface_attach',
                 default=True,
                 help='Does the test environment support dynamic network '
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/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/lib/services/identity/v3/groups_client.py b/tempest/lib/services/identity/v3/groups_client.py
index 3674496..200cb43 100644
--- a/tempest/lib/services/identity/v3/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/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/lib/services/identity/v3/users_client.py b/tempest/lib/services/identity/v3/users_client.py
index 0dcdacd..5398621 100644
--- a/tempest/lib/services/identity/v3/users_client.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/services/identity/v3/__init__.py b/tempest/services/identity/v3/__init__.py
index c5ab6b3..3f5c3d5 100644
--- a/tempest/services/identity/v3/__init__.py
+++ b/tempest/services/identity/v3/__init__.py
@@ -12,24 +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.lib.services.identity.v3.trusts_client import TrustsClient
 from tempest.lib.services.identity.v3.users_client import UsersClient
-from tempest.services.identity.v3.json.credentials_client import \
-    CredentialsClient
 from tempest.services.identity.v3.json.domains_client import DomainsClient
-from tempest.services.identity.v3.json.roles_client import RolesClient
-from tempest.services.identity.v3.json.trusts_client import TrustsClient
 
-
-__all__ = ['EndPointsClient', 'GroupsClient', 'IdentityClient',
-           'PoliciesClient', 'ProjectsClient', 'RegionsClient',
-           'ServicesClient', 'V3TokenClient', 'UsersClient',
-           'CredentialsClient', 'DomainsClient', 'RolesClient',
-           'TrustsClient', ]
+__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 3f165fa..0000000
--- a/tempest/services/identity/v3/json/roles_client.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright 2016 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.lib.common import rest_client
-
-
-class RolesClient(rest_client.RestClient):
-    api_version = "v3"
-
-    def create_role(self, **kwargs):
-        """Create a Role.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createRole
-        """
-        post_body = json.dumps({'role': kwargs})
-        resp, body = self.post('roles', post_body)
-        self.expected_success(201, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_role(self, role_id):
-        """GET a Role."""
-        resp, body = self.get('roles/%s' % role_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_roles(self, **params):
-        """Get the list of Roles."""
-
-        url = 'roles'
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-        resp, body = self.get(url)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def update_role(self, role_id, **kwargs):
-        """Update a Role.
-
-        Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#updateRole
-        """
-        post_body = json.dumps({'role': kwargs})
-        resp, body = self.patch('roles/%s' % role_id, post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role(self, role_id):
-        """Delete a role."""
-        resp, body = self.delete('roles/%s' % role_id)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_user_role_on_project(self, project_id, user_id, role_id):
-        """Add roles to a user on a project."""
-        resp, body = self.put('projects/%s/users/%s/roles/%s' %
-                              (project_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_user_role_on_domain(self, domain_id, user_id, role_id):
-        """Add roles to a user on a domain."""
-        resp, body = self.put('domains/%s/users/%s/roles/%s' %
-                              (domain_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_user_roles_on_project(self, project_id, user_id):
-        """list roles of a user on a project."""
-        resp, body = self.get('projects/%s/users/%s/roles' %
-                              (project_id, user_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_user_roles_on_domain(self, domain_id, user_id):
-        """list roles of a user on a domain."""
-        resp, body = self.get('domains/%s/users/%s/roles' %
-                              (domain_id, user_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role_from_user_on_project(self, project_id, user_id, role_id):
-        """Delete role of a user on a project."""
-        resp, body = self.delete('projects/%s/users/%s/roles/%s' %
-                                 (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role_from_user_on_domain(self, domain_id, user_id, role_id):
-        """Delete role of a user on a domain."""
-        resp, body = self.delete('domains/%s/users/%s/roles/%s' %
-                                 (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_user_role_existence_on_project(self, project_id,
-                                             user_id, role_id):
-        """Check role of a user on a project."""
-        resp, body = self.head('projects/%s/users/%s/roles/%s' %
-                               (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def check_user_role_existence_on_domain(self, domain_id,
-                                            user_id, role_id):
-        """Check role of a user on a domain."""
-        resp, body = self.head('domains/%s/users/%s/roles/%s' %
-                               (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def create_group_role_on_project(self, project_id, group_id, role_id):
-        """Add roles to a group on a project."""
-        resp, body = self.put('projects/%s/groups/%s/roles/%s' %
-                              (project_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_group_role_on_domain(self, domain_id, group_id, role_id):
-        """Add roles to a group on a domain."""
-        resp, body = self.put('domains/%s/groups/%s/roles/%s' %
-                              (domain_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_group_roles_on_project(self, project_id, group_id):
-        """list roles of a group on a project."""
-        resp, body = self.get('projects/%s/groups/%s/roles' %
-                              (project_id, group_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_group_roles_on_domain(self, domain_id, group_id):
-        """list roles of a group on a domain."""
-        resp, body = self.get('domains/%s/groups/%s/roles' %
-                              (domain_id, group_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role_from_group_on_project(self, project_id, group_id, role_id):
-        """Delete role of a group on a project."""
-        resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
-                                 (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_role_from_group_on_domain(self, domain_id, group_id, role_id):
-        """Delete role of a group on a domain."""
-        resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
-                                 (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_role_from_group_on_project_existence(self, project_id,
-                                                   group_id, role_id):
-        """Check role of a group on a project."""
-        resp, body = self.head('projects/%s/groups/%s/roles/%s' %
-                               (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def check_role_from_group_on_domain_existence(self, domain_id,
-                                                  group_id, role_id):
-        """Check role of a group on a domain."""
-        resp, body = self.head('domains/%s/groups/%s/roles/%s' %
-                               (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def assign_inherited_role_on_domains_user(
-            self, domain_id, user_id, role_id):
-        """Assigns a role to a user on projects owned by a domain."""
-        resp, body = self.put(
-            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
-            % (domain_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def revoke_inherited_role_from_user_on_domain(
-            self, domain_id, user_id, role_id):
-        """Revokes an inherited project role from a user on a domain."""
-        resp, body = self.delete(
-            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
-            % (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_inherited_project_role_for_user_on_domain(
-            self, domain_id, user_id):
-        """Lists the inherited project roles on a domain for a user."""
-        resp, body = self.get(
-            "OS-INHERIT/domains/%s/users/%s/roles/inherited_to_projects"
-            % (domain_id, user_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_user_inherited_project_role_on_domain(
-            self, domain_id, user_id, role_id):
-        """Checks whether a user has an inherited project role on a domain."""
-        resp, body = self.head(
-            "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
-            % (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def assign_inherited_role_on_domains_group(
-            self, domain_id, group_id, role_id):
-        """Assigns a role to a group on projects owned by a domain."""
-        resp, body = self.put(
-            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (domain_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def revoke_inherited_role_from_group_on_domain(
-            self, domain_id, group_id, role_id):
-        """Revokes an inherited project role from a group on a domain."""
-        resp, body = self.delete(
-            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_inherited_project_role_for_group_on_domain(
-            self, domain_id, group_id):
-        """Lists the inherited project roles on a domain for a group."""
-        resp, body = self.get(
-            "OS-INHERIT/domains/%s/groups/%s/roles/inherited_to_projects"
-            % (domain_id, group_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_group_inherited_project_role_on_domain(
-            self, domain_id, group_id, role_id):
-        """Checks whether a group has an inherited project role on a domain."""
-        resp, body = self.head(
-            "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def assign_inherited_role_on_projects_user(
-            self, project_id, user_id, role_id):
-        """Assigns a role to a user on projects in a subtree."""
-        resp, body = self.put(
-            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
-            % (project_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def revoke_inherited_role_from_user_on_project(
-            self, project_id, user_id, role_id):
-        """Revokes an inherited role from a user on a project."""
-        resp, body = self.delete(
-            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
-            % (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_user_has_flag_on_inherited_to_project(
-            self, project_id, user_id, role_id):
-        """Checks whether a user has a role assignment"""
-        """with the inherited_to_projects flag on a project."""
-        resp, body = self.head(
-            "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
-            % (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
-
-    def assign_inherited_role_on_projects_group(
-            self, project_id, group_id, role_id):
-        """Assigns a role to a group on projects in a subtree."""
-        resp, body = self.put(
-            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (project_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def revoke_inherited_role_from_group_on_project(
-            self, project_id, group_id, role_id):
-        """Revokes an inherited role from a group on a project."""
-        resp, body = self.delete(
-            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def check_group_has_flag_on_inherited_to_project(
-            self, project_id, group_id, role_id):
-        """Checks whether a group has a role assignment"""
-        """with the inherited_to_projects flag on a project."""
-        resp, body = self.head(
-            "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
-            % (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return rest_client.ResponseBody(resp)
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index a7db30e..ec36fb7 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -195,7 +195,6 @@
 
         # Read the 100 status prior to sending the data
         response = conn.response_class(conn.sock,
-                                       strict=conn.strict,
                                        method=conn._method)
         _, status, _ = response._read_status()
 
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 925d765..1e33e88 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -20,8 +20,6 @@
 from oslo_log import log as logging
 from oslo_utils import importutils
 import six
-from six import moves
-
 
 from tempest import clients
 from tempest.common import cred_client
@@ -142,7 +140,7 @@
             manager = admin_manager
         else:
             raise NotImplemented('Non admin tests are not supported')
-        for p_number in moves.xrange(test.get('threads', default_thread_num)):
+        for p_number in range(test.get('threads', default_thread_num)):
             if test.get('use_isolated_tenants', False):
                 username = data_utils.rand_name("stress_user")
                 tenant_name = data_utils.rand_name("stress_tenant")
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index 613bc63..0033d4e 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -31,12 +31,12 @@
 from tempest.lib.services.identity.v3 import identity_client as v3_iden_client
 from tempest.lib.services.identity.v3 import projects_client as \
     v3_projects_client
+from tempest.lib.services.identity.v3 import roles_client as v3_roles_client
 from tempest.lib.services.identity.v3 import token_client as v3_token_client
 from tempest.lib.services.identity.v3 import users_client as \
     v3_users_client
 from tempest.lib.services.network import routers_client
 from tempest.services.identity.v3.json import domains_client
-from tempest.services.identity.v3.json import roles_client as v3_roles_client
 from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests.lib import fake_http
diff --git a/tempest/tests/fake_auth_provider.py b/tempest/tests/fake_auth_provider.py
deleted file mode 100644
index 769f6a6..0000000
--- a/tempest/tests/fake_auth_provider.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2014 Hewlett-Packard Development Company, L.P.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-
-class FakeAuthProvider(object):
-
-    def auth_request(self, method, url, headers=None, body=None, filters=None):
-        return url, headers, body
-
-    def get_token(self):
-        return "faketoken"
-
-    def base_url(self, filters, auth_data=None):
-        return "https://example.com"
diff --git a/tempest/tests/lib/common/utils/test_data_utils.py b/tempest/tests/lib/common/utils/test_data_utils.py
index 94a4847..4446e5c 100644
--- a/tempest/tests/lib/common/utils/test_data_utils.py
+++ b/tempest/tests/lib/common/utils/test_data_utils.py
@@ -125,13 +125,13 @@
 
     def test_random_bytes(self):
         actual = data_utils.random_bytes()  # default size=1024
-        self.assertIsInstance(actual, str)
-        self.assertRegex(actual, "^[\x00-\xFF]{1024}")
+        self.assertIsInstance(actual, bytes)
+        self.assertEqual(1024, len(actual))
         actual2 = data_utils.random_bytes()
         self.assertNotEqual(actual, actual2)
 
         actual = data_utils.random_bytes(size=2048)
-        self.assertRegex(actual, "^[\x00-\xFF]{2048}")
+        self.assertEqual(2048, len(actual))
 
     def test_get_ipv6_addr_by_EUI64(self):
         actual = data_utils.get_ipv6_addr_by_EUI64('2001:db8::',
diff --git a/tempest/tests/lib/fake_auth_provider.py b/tempest/tests/lib/fake_auth_provider.py
index fa8ab47..e4582f8 100644
--- a/tempest/tests/lib/fake_auth_provider.py
+++ b/tempest/tests/lib/fake_auth_provider.py
@@ -27,6 +27,9 @@
     def base_url(self, filters, auth_data=None):
         return self.fake_base_url or "https://example.com"
 
+    def get_token(self):
+        return "faketoken"
+
 
 class FakeCredentials(object):
 
diff --git a/tempest/tests/lib/services/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/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_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/services/object_storage/test_object_client.py b/tempest/tests/services/object_storage/test_object_client.py
index cd8c8f1..cc1dc1a 100644
--- a/tempest/tests/services/object_storage/test_object_client.py
+++ b/tempest/tests/services/object_storage/test_object_client.py
@@ -20,7 +20,7 @@
 from tempest.lib import exceptions
 from tempest.services.object_storage import object_client
 from tempest.tests import base
-from tempest.tests import fake_auth_provider
+from tempest.tests.lib import fake_auth_provider
 
 
 class TestObjectClient(base.TestCase):
diff --git a/tempest/tests/test_negative_rest_client.py b/tempest/tests/test_negative_rest_client.py
index 9d9c20f..05f9f3e 100644
--- a/tempest/tests/test_negative_rest_client.py
+++ b/tempest/tests/test_negative_rest_client.py
@@ -21,8 +21,8 @@
 from tempest.common import negative_rest_client
 from tempest import config
 from tempest.tests import base
-from tempest.tests import fake_auth_provider
 from tempest.tests import fake_config
+from tempest.tests.lib import fake_auth_provider
 
 
 class TestNegativeRestClient(base.TestCase):