Merge "Update Available para link of network 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 b8a8491..d1635e3 100644
--- a/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
+++ b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
@@ -6,3 +6,6 @@
     any maintenance changes.
 
       * identity_client(v2)
+      * groups_client(v3)
+      * users_client(v3)
+      * identity_client(v3)
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index b1f0755..7d97ce2 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -117,8 +117,6 @@
                                                password=password,
                                                project=project,
                                                email=email)
-        if 'user' in user:
-            user = user['user']
         user_id = user['id']
         self.addCleanup(self.identity_utils.delete_user, user_id)
 
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 80d2c78..7c13ef0 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -119,7 +119,8 @@
                 servers_client=self.servers_client)
 
             partitions = linux_client.get_partitions()
-            self.assertIn(self.device, partitions)
+            device_name_to_match = ' ' + self.device + '\n'
+            self.assertIn(device_name_to_match, partitions)
 
         self._detach(server['id'], self.volume['id'])
         self.attachment = None
@@ -141,7 +142,7 @@
                 servers_client=self.servers_client)
 
             partitions = linux_client.get_partitions()
-            self.assertNotIn(self.device, partitions)
+            self.assertNotIn(device_name_to_match, partitions)
 
     @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
     def test_list_get_volume_attachments(self):
diff --git a/tempest/api/identity/admin/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index 3616e77..59ffc19 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -69,7 +69,7 @@
         admin_role_id = admin_role['id']
 
         # grant the admin role to the user on his project
-        self.roles_client.assign_user_role_on_project(proj_id, user_id,
+        self.roles_client.create_user_role_on_project(proj_id, user_id,
                                                       admin_role_id)
 
         # create a new client with user's credentials (NOTE: unscoped token!)
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 4ecf0a5..f5bf923 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -94,7 +94,7 @@
 
     @test.idempotent_id('c6b80012-fe4a-498b-9ce8-eb391c05169f')
     def test_grant_list_revoke_role_to_user_on_project(self):
-        self.roles_client.assign_user_role_on_project(self.project['id'],
+        self.roles_client.create_user_role_on_project(self.project['id'],
                                                       self.user_body['id'],
                                                       self.role['id'])
 
@@ -115,7 +115,7 @@
 
     @test.idempotent_id('6c9a2940-3625-43a3-ac02-5dcec62ef3bd')
     def test_grant_list_revoke_role_to_user_on_domain(self):
-        self.roles_client.assign_user_role_on_domain(
+        self.roles_client.create_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
         roles = self.roles_client.list_user_roles_on_domain(
@@ -136,7 +136,7 @@
     @test.idempotent_id('cbf11737-1904-4690-9613-97bcbb3df1c4')
     def test_grant_list_revoke_role_to_group_on_project(self):
         # Grant role to group on project
-        self.roles_client.assign_group_role_on_project(
+        self.roles_client.create_group_role_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
         # List group roles on project
         roles = self.roles_client.list_group_roles_on_project(
@@ -170,7 +170,7 @@
 
     @test.idempotent_id('4bf8a70b-e785-413a-ad53-9f91ce02faa7')
     def test_grant_list_revoke_role_to_group_on_domain(self):
-        self.roles_client.assign_group_role_on_domain(
+        self.roles_client.create_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
         roles = self.roles_client.list_group_roles_on_domain(
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index fcf4772..8706cf7 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -83,11 +83,11 @@
         self.addCleanup(self.roles_client.delete_role, role['id'])
 
         # Grant the user the role on both projects.
-        self.roles_client.assign_user_role_on_project(project1['id'],
+        self.roles_client.create_user_role_on_project(project1['id'],
                                                       user['id'],
                                                       role['id'])
 
-        self.roles_client.assign_user_role_on_project(project2['id'],
+        self.roles_client.create_user_role_on_project(project2['id'],
                                                       user['id'],
                                                       role['id'])
 
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 58e2ab8..4e69de8 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -77,11 +77,11 @@
         self.not_delegated_role_id = role['id']
 
         # Assign roles to trustor
-        self.roles_client.assign_user_role_on_project(
+        self.roles_client.create_user_role_on_project(
             self.trustor_project_id,
             self.trustor_user_id,
             self.delegated_role_id)
-        self.roles_client.assign_user_role_on_project(
+        self.roles_client.create_user_role_on_project(
             self.trustor_project_id,
             self.trustor_user_id,
             self.not_delegated_role_id)
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 1bcec62..fd2683e 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -130,7 +130,7 @@
             self.addCleanup(
                 self.projects_client.delete_project, project_body['id'])
             # Assigning roles to user on project
-            self.roles_client.assign_user_role_on_project(project['id'],
+            self.roles_client.create_user_role_on_project(project['id'],
                                                           user['id'],
                                                           role['id'])
             assigned_project_ids.append(project['id'])
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 6c926fb..9e40c42 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -23,6 +23,12 @@
 class BaseIdentityTest(tempest.test.BaseTestCase):
 
     @classmethod
+    def setup_credentials(cls):
+        # Create no network resources for these test.
+        cls.set_network_resources()
+        super(BaseIdentityTest, cls).setup_credentials()
+
+    @classmethod
     def disable_user(cls, user_name):
         user = cls.get_user_by_name(user_name)
         cls.users_client.update_user_enabled(user['id'], enabled=False)
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 723b870..9e9f08b 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -78,7 +78,16 @@
         # container request, the response does not contain 'accept-ranges'
         # header. This is a special case, therefore the existence of response
         # headers is checked without custom matcher.
-        self.assertIn('content-length', resp)
+        #
+        # As the expected response is 204 No Content, Content-Length presence
+        # is not checked here intensionally. According to RFC 7230 a server
+        # MUST NOT send the header in such responses. Thus, clients should not
+        # depend on this header. However, the standard does not require them
+        # to validate the server's behavior. We leverage that to not refuse
+        # any implementation violating it like Swift [1] or some versions of
+        # Ceph RadosGW [2].
+        # [1] https://bugs.launchpad.net/swift/+bug/1537811
+        # [2] http://tracker.ceph.com/issues/13582
         self.assertIn('x-timestamp', resp)
         self.assertIn('x-account-bytes-used', resp)
         self.assertIn('x-account-container-count', resp)
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 00da5be..646bc68 100755
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -128,7 +128,7 @@
         body = self.create_volume_type(name=name)
         # Create encryption type
         encryption_type = \
-            self.admin_volume_types_client.create_encryption_type(
+            self.admin_encryption_types_client.create_encryption_type(
                 body['id'], provider=provider,
                 control_location=control_location)['encryption']
         self.assertIn('volume_type_id', encryption_type)
@@ -141,7 +141,7 @@
 
         # Get encryption type
         fetched_encryption_type = (
-            self.admin_volume_types_client.show_encryption_type(
+            self.admin_encryption_types_client.show_encryption_type(
                 encryption_type['volume_type_id']))
         self.assertEqual(provider,
                          fetched_encryption_type['provider'],
@@ -153,14 +153,11 @@
                          'different from the created encryption_type')
 
         # Delete encryption type
-        self.admin_volume_types_client.delete_encryption_type(
-            encryption_type['volume_type_id'])
-        resource = {"id": encryption_type['volume_type_id'],
-                    "type": "encryption-type"}
-        self.admin_volume_types_client.wait_for_resource_deletion(resource)
+        type_id = encryption_type['volume_type_id']
+        self.admin_encryption_types_client.delete_encryption_type(type_id)
+        self.admin_encryption_types_client.wait_for_resource_deletion(type_id)
         deleted_encryption_type = (
-            self.admin_volume_types_client.show_encryption_type(
-                encryption_type['volume_type_id']))
+            self.admin_encryption_types_client.show_encryption_type(type_id))
         self.assertEmpty(deleted_encryption_type)
 
     @test.idempotent_id('cf9f07c6-db9e-4462-a243-5933ad65e9c8')
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 4f37c82..183452c 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -204,6 +204,8 @@
             cls.admin_hosts_client = cls.os_adm.volume_hosts_client
             cls.admin_snapshots_client = cls.os_adm.snapshots_client
             cls.admin_backups_client = cls.os_adm.backups_client
+            cls.admin_encryption_types_client = \
+                cls.os_adm.encryption_types_client
             cls.admin_quotas_client = cls.os_adm.volume_quotas_client
         elif cls._api_version == 2:
             cls.admin_volume_qos_client = cls.os_adm.volume_qos_v2_client
@@ -214,6 +216,8 @@
             cls.admin_hosts_client = cls.os_adm.volume_hosts_v2_client
             cls.admin_snapshots_client = cls.os_adm.snapshots_v2_client
             cls.admin_backups_client = cls.os_adm.backups_v2_client
+            cls.admin_encryption_types_client = \
+                cls.os_adm.encryption_types_v2_client
             cls.admin_quotas_client = cls.os_adm.volume_quotas_v2_client
 
     @classmethod
@@ -265,12 +269,9 @@
                 cls.admin_volume_types_client.delete_volume_type, vol_type)
 
         for vol_type in cls.volume_types:
-            # Resource dictionary uses for is_resource_deleted method,
-            # to distinguish between volume-type to encryption-type.
-            resource = {'id': vol_type, 'type': 'volume-type'}
             test_utils.call_and_ignore_notfound_exc(
                 cls.admin_volume_types_client.wait_for_resource_deletion,
-                resource)
+                vol_type)
 
     def wait_for_qos_operations(self, qos_id, operation, args=None):
         """Waits for a qos operations to be completed.
diff --git a/tempest/clients.py b/tempest/clients.py
index 5406d73..f8c276a 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -293,6 +293,10 @@
                                                       **params)
         self.backups_v2_client = volume.v2.BackupsClient(self.auth_provider,
                                                          **params)
+        self.encryption_types_client = volume.v1.EncryptionTypesClient(
+            self.auth_provider, **params)
+        self.encryption_types_v2_client = volume.v2.EncryptionTypesClient(
+            self.auth_provider, **params)
         self.snapshots_client = volume.v1.SnapshotsClient(self.auth_provider,
                                                           **params)
         self.snapshots_v2_client = volume.v2.SnapshotsClient(
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index d8b808b..ad968f1 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -74,7 +74,9 @@
             msg = 'No "%s" role found' % role_name
             raise lib_exc.NotFound(msg)
         try:
-            self._assign_user_role(project, user, role)
+            self.roles_client.create_user_role_on_project(project['id'],
+                                                          user['id'],
+                                                          role['id'])
         except lib_exc.Conflict:
             LOG.debug("Role %s already assigned on project %s for user %s" % (
                 role['id'], project['id'], user['id']))
@@ -124,11 +126,6 @@
             tenant_name=project['name'], tenant_id=project['id'],
             password=password)
 
-    def _assign_user_role(self, project, user, role):
-        self.roles_client.create_user_role_on_project(project['id'],
-                                                      user['id'],
-                                                      role['id'])
-
 
 class V3CredsClient(CredsClient):
     project_id_param = 'project_id'
@@ -176,11 +173,6 @@
             domain_id=self.creds_domain['id'],
             domain_name=self.creds_domain['name'])
 
-    def _assign_user_role(self, project, user, role):
-        self.roles_client.assign_user_role_on_project(project['id'],
-                                                      user['id'],
-                                                      role['id'])
-
     def assign_user_role_on_domain(self, user, role_name, domain=None):
         """Assign the specified role on a domain
 
@@ -198,7 +190,7 @@
             msg = 'No "%s" role found' % role_name
             raise lib_exc.NotFound(msg)
         try:
-            self.roles_client.assign_user_role_on_domain(
+            self.roles_client.create_user_role_on_domain(
                 domain['id'], user['id'], role['id'])
         except lib_exc.Conflict:
             LOG.debug("Role %s already assigned on domain %s for user %s",
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index 8ba33ed..998612b 100644
--- a/tempest/common/custom_matchers.py
+++ b/tempest/common/custom_matchers.py
@@ -37,13 +37,32 @@
         self.target = target
         self.method = method
 
+    def _content_length_required(self, resp):
+        # Verify whether given HTTP response must contain content-length.
+        # Take into account the exceptions defined in RFC 7230.
+        if resp.status in range(100, 200) or resp.status == 204:
+            return False
+
+        return True
+
     def match(self, actual):
         """Check headers
 
-        param: actual HTTP response headers
+        param: actual HTTP response object containing headers and status
         """
-        # Check common headers for all HTTP methods
-        if 'content-length' not in actual:
+        # Check common headers for all HTTP methods.
+        #
+        # Please note that for 1xx and 204 responses Content-Length presence
+        # is not checked intensionally. According to RFC 7230 a server MUST
+        # NOT send the header in such responses. Thus, clients should not
+        # depend on this header. However, the standard does not require them
+        # to validate the server's behavior. We leverage that to not refuse
+        # any implementation violating it like Swift [1] or some versions of
+        # Ceph RadosGW [2].
+        # [1] https://bugs.launchpad.net/swift/+bug/1537811
+        # [2] http://tracker.ceph.com/issues/13582
+        if ('content-length' not in actual and
+                self._content_length_required(actual)):
             return NonExistentHeader('content-length')
         if 'content-type' not in actual:
             return NonExistentHeader('content-type')
diff --git a/tempest/services/identity/v3/json/groups_client.py b/tempest/lib/services/identity/v3/groups_client.py
similarity index 100%
rename from tempest/services/identity/v3/json/groups_client.py
rename to tempest/lib/services/identity/v3/groups_client.py
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/lib/services/identity/v3/identity_client.py
similarity index 100%
rename from tempest/services/identity/v3/json/identity_client.py
rename to tempest/lib/services/identity/v3/identity_client.py
diff --git a/tempest/services/identity/v3/json/users_clients.py b/tempest/lib/services/identity/v3/users_client.py
similarity index 100%
rename from tempest/services/identity/v3/json/users_clients.py
rename to tempest/lib/services/identity/v3/users_client.py
diff --git a/tempest/lib/services/network/ports_client.py b/tempest/lib/services/network/ports_client.py
index 71f1103..85f5a1d 100755
--- a/tempest/lib/services/network/ports_client.py
+++ b/tempest/lib/services/network/ports_client.py
@@ -20,7 +20,7 @@
         """Creates a port on a network.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#createPort
+                              api-ref/networking/v2/index.html#create-port
         """
         uri = '/ports'
         post_data = {'port': kwargs}
@@ -30,7 +30,7 @@
         """Updates a port.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#updatePort
+                              api-ref/networking/v2/index.html#update-port
         """
         uri = '/ports/%s' % port_id
         post_data = {'port': kwargs}
@@ -40,7 +40,7 @@
         """Shows details for a port.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#showPort
+                              api-ref/networking/v2/index.html#show-port-details
         """
         uri = '/ports/%s' % port_id
         return self.show_resource(uri, **fields)
@@ -49,7 +49,7 @@
         """Deletes a port.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#removePort
+                              api-ref/networking/v2/index.html#delete-port
         """
         uri = '/ports/%s' % port_id
         return self.delete_resource(uri)
@@ -58,7 +58,7 @@
         """Lists ports to which the tenant has access.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#listPorts
+                              api-ref/networking/v2/index.html#list-ports
         """
         uri = '/ports'
         return self.list_resources(uri, **filters)
@@ -67,7 +67,7 @@
         """Create multiple ports in a single request.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#bulkCreatePorts
+                              api-ref/networking/v2/index.html?expanded=#bulk-create-ports
         """
         uri = '/ports'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/subnets_client.py b/tempest/lib/services/network/subnets_client.py
index 0fde3ee..203b360 100755
--- a/tempest/lib/services/network/subnets_client.py
+++ b/tempest/lib/services/network/subnets_client.py
@@ -19,7 +19,7 @@
         """Creates a subnet on a network.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#createSubnet
+                              api-ref/networking/v2/index.html#create-subnet
         """
         uri = '/subnets'
         post_data = {'subnet': kwargs}
@@ -29,7 +29,7 @@
         """Updates a subnet.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#updateSubnet
+                              api-ref/networking/v2/index.html#update-subnet
         """
         uri = '/subnets/%s' % subnet_id
         post_data = {'subnet': kwargs}
@@ -39,7 +39,7 @@
         """Shows details for a subnet.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#showSubnet
+                              api-ref/networking/v2/index.html#show-subnet-details
         """
         uri = '/subnets/%s' % subnet_id
         return self.show_resource(uri, **fields)
@@ -52,7 +52,7 @@
         """Lists subnets to which the tenant has access.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#listSubnets
+                              api-ref/networking/v2/index.html#list-subnets
         """
         uri = '/subnets'
         return self.list_resources(uri, **filters)
@@ -61,7 +61,7 @@
         """Create multiple subnets in a single request.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-networking-v2.html#bulkCreateSubnet
+                              api-ref/networking/v2/index.html#bulk-create-subnet
         """
         uri = '/subnets'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index a3f832a..233d747 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -1346,8 +1346,12 @@
         super(EncryptionScenarioTest, cls).setup_clients()
         if CONF.volume_feature_enabled.api_v1:
             cls.admin_volume_types_client = cls.os_adm.volume_types_client
+            cls.admin_encryption_types_client =\
+                cls.os_adm.encryption_types_client
         else:
             cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
+            cls.admin_encryption_types_client =\
+                cls.os_adm.encryption_types_v2_client
 
     def create_volume_type(self, client=None, name=None):
         if not client:
@@ -1366,7 +1370,7 @@
                                key_size=None, cipher=None,
                                control_location=None):
         if not client:
-            client = self.admin_volume_types_client
+            client = self.admin_encryption_types_client
         if not type_id:
             volume_type = self.create_volume_type()
             type_id = volume_type['id']
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index a89147a..8f27a5d 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -58,7 +58,7 @@
             security_groups = [{'name': security_group['name']}]
         network, subnet, router = self.create_networks()
         public_network_id = CONF.network.public_network_id
-        server_name = data_utils.rand_name('server')
+        server_name = data_utils.rand_name(self.__class__.__name__ + '-server')
         server = self.create_server(
             name=server_name,
             networks=[{'uuid': network['id']}],
diff --git a/tempest/services/identity/v3/__init__.py b/tempest/services/identity/v3/__init__.py
index c77c78d..c5ab6b3 100644
--- a/tempest/services/identity/v3/__init__.py
+++ b/tempest/services/identity/v3/__init__.py
@@ -13,21 +13,23 @@
 # the License.
 
 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.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.services_client import ServicesClient
 from tempest.lib.services.identity.v3.token_client import V3TokenClient
+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.groups_client import GroupsClient
-from tempest.services.identity.v3.json.identity_client import IdentityClient
 from tempest.services.identity.v3.json.roles_client import RolesClient
 from tempest.services.identity.v3.json.trusts_client import TrustsClient
-from tempest.services.identity.v3.json.users_clients import UsersClient
 
-__all__ = ['EndPointsClient', 'PoliciesClient', 'ProjectsClient',
-           'RegionsClient', 'ServicesClient', 'V3TokenClient',
-           'CredentialsClient', 'DomainsClient', 'GroupsClient',
-           'IdentityClient', 'RolesClient', 'TrustsClient', 'UsersClient', ]
+
+__all__ = ['EndPointsClient', 'GroupsClient', 'IdentityClient',
+           'PoliciesClient', 'ProjectsClient', 'RegionsClient',
+           'ServicesClient', 'V3TokenClient', 'UsersClient',
+           'CredentialsClient', 'DomainsClient', 'RolesClient',
+           'TrustsClient', ]
diff --git a/tempest/services/identity/v3/json/roles_client.py b/tempest/services/identity/v3/json/roles_client.py
index aab203f..3f165fa 100644
--- a/tempest/services/identity/v3/json/roles_client.py
+++ b/tempest/services/identity/v3/json/roles_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
 
@@ -39,9 +40,13 @@
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
-    def list_roles(self):
+    def list_roles(self, **params):
         """Get the list of Roles."""
-        resp, body = self.get("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)
@@ -64,14 +69,14 @@
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
-    def assign_user_role_on_project(self, project_id, user_id, role_id):
+    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 assign_user_role_on_domain(self, domain_id, user_id, role_id):
+    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)
@@ -124,22 +129,22 @@
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp)
 
-    def assign_group_role_on_project(self, project_id, group_id, role_id):
-        """Add roles to a user on a project."""
+    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 assign_group_role_on_domain(self, domain_id, group_id, role_id):
-        """Add roles to a user on a domain."""
+    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 user on a project."""
+        """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)
@@ -147,7 +152,7 @@
         return rest_client.ResponseBody(resp, body)
 
     def list_group_roles_on_domain(self, domain_id, group_id):
-        """list roles of a user on a domain."""
+        """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)
@@ -155,14 +160,14 @@
         return rest_client.ResponseBody(resp, body)
 
     def delete_role_from_group_on_project(self, project_id, group_id, role_id):
-        """Delete role of a user on a project."""
+        """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 user on a domain."""
+        """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)
@@ -170,7 +175,7 @@
 
     def check_role_from_group_on_project_existence(self, project_id,
                                                    group_id, role_id):
-        """Check role of a user on a project."""
+        """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)
@@ -178,7 +183,7 @@
 
     def check_role_from_group_on_domain_existence(self, domain_id,
                                                   group_id, role_id):
-        """Check role of a user on a domain."""
+        """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)
diff --git a/tempest/services/volume/base/admin/__init__.py b/tempest/services/volume/base/admin/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/volume/base/admin/__init__.py
+++ /dev/null
diff --git a/tempest/services/volume/base/admin/base_types_client.py b/tempest/services/volume/base/admin/base_types_client.py
deleted file mode 100755
index 83870ae..0000000
--- a/tempest/services/volume/base/admin/base_types_client.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.lib.common import rest_client
-from tempest.lib import exceptions as lib_exc
-
-
-class BaseTypesClient(rest_client.RestClient):
-    """Client class to send CRUD Volume Types API requests"""
-
-    def is_resource_deleted(self, resource):
-        # to use this method self.resource must be defined to respective value
-        # Resource is a dictionary containing resource id and type
-        # Resource : {"id" : resource_id
-        #             "type": resource_type}
-        try:
-            if resource['type'] == "volume-type":
-                self.show_volume_type(resource['id'])
-            elif resource['type'] == "encryption-type":
-                body = self.show_encryption_type(resource['id'])
-                if not body:
-                    return True
-            else:
-                msg = (" resource value is either not defined or incorrect.")
-                raise lib_exc.UnprocessableEntity(msg)
-        except lib_exc.NotFound:
-            return True
-        return False
-
-    @property
-    def resource_type(self):
-        """Returns the primary type of resource this client works with."""
-        return 'volume-type/encryption-type'
-
-    def list_volume_types(self, **params):
-        """List all the volume_types created.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#showVolumeTypes
-        """
-        url = 'types'
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_volume_type(self, volume_type_id):
-        """Returns the details of a single volume_type.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#showVolumeType
-        """
-        url = "types/%s" % volume_type_id
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_volume_type(self, **kwargs):
-        """Create volume type.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#createVolumeType
-        """
-        post_body = json.dumps({'volume_type': kwargs})
-        resp, body = self.post('types', post_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_volume_type(self, volume_type_id):
-        """Deletes the Specified Volume_type.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#deleteVolumeType
-        """
-        resp, body = self.delete("types/%s" % volume_type_id)
-        self.expected_success(202, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def list_volume_types_extra_specs(self, volume_type_id, **params):
-        """List all the volume_types extra specs created.
-
-        TODO: Current api-site doesn't contain this API description.
-        After fixing the api-site, we need to fix here also for putting
-        the link to api-site.
-        """
-        url = 'types/%s/extra_specs' % volume_type_id
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_volume_type_extra_specs(self, volume_type_id, extra_specs_name):
-        """Returns the details of a single volume_type extra spec."""
-        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_specs_name)
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_volume_type_extra_specs(self, volume_type_id, extra_specs):
-        """Creates a new Volume_type extra spec.
-
-        volume_type_id: Id of volume_type.
-        extra_specs: A dictionary of values to be used as extra_specs.
-        """
-        url = "types/%s/extra_specs" % volume_type_id
-        post_body = json.dumps({'extra_specs': extra_specs})
-        resp, body = self.post(url, post_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_volume_type_extra_specs(self, volume_type_id, extra_spec_name):
-        """Deletes the Specified Volume_type extra spec."""
-        resp, body = self.delete("types/%s/extra_specs/%s" % (
-            volume_type_id, extra_spec_name))
-        self.expected_success(202, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def update_volume_type(self, volume_type_id, **kwargs):
-        """Updates volume type name, description, and/or is_public.
-
-        Available params: see http://developer.openstack.org/
-        api-ref-blockstorage-v2.html#updateVolumeType
-        """
-        put_body = json.dumps({'volume_type': kwargs})
-        resp, body = self.put('types/%s' % volume_type_id, put_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def update_volume_type_extra_specs(self, volume_type_id, extra_spec_name,
-                                       extra_specs):
-        """Update a volume_type extra spec.
-
-        volume_type_id: Id of volume_type.
-        extra_spec_name: Name of the extra spec to be updated.
-        extra_spec: A dictionary of with key as extra_spec_name and the
-                     updated value.
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html#
-                              updateVolumeTypeExtraSpecs
-        """
-        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_spec_name)
-        put_body = json.dumps(extra_specs)
-        resp, body = self.put(url, put_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def show_encryption_type(self, volume_type_id):
-        """Get the volume encryption type for the specified volume type.
-
-        volume_type_id: Id of volume_type.
-        """
-        url = "/types/%s/encryption" % volume_type_id
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_encryption_type(self, volume_type_id, **kwargs):
-        """Create encryption type.
-
-        TODO: Current api-site doesn't contain this API description.
-        After fixing the api-site, we need to fix here also for putting
-        the link to api-site.
-        """
-        url = "/types/%s/encryption" % volume_type_id
-        post_body = json.dumps({'encryption': kwargs})
-        resp, body = self.post(url, post_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_encryption_type(self, volume_type_id):
-        """Delete the encryption type for the specified volume-type."""
-        resp, body = self.delete(
-            "/types/%s/encryption/provider" % volume_type_id)
-        self.expected_success(202, resp.status)
-        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/base/base_volumes_client.py b/tempest/services/volume/base/base_volumes_client.py
index 308f818..11b6e1a 100755
--- a/tempest/services/volume/base/base_volumes_client.py
+++ b/tempest/services/volume/base/base_volumes_client.py
@@ -52,21 +52,6 @@
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, body)
 
-    def show_pools(self, detail=False):
-        """List all the volumes pools (hosts).
-
-        Output params: see http://developer.openstack.org/
-                           api-ref-blockstorage-v2.html#listPools
-        """
-        url = 'scheduler-stats/get_pools'
-        if detail:
-            url += '?detail=True'
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
     def show_backend_capabilities(self, host):
         """Shows capabilities for a storage back end.
 
@@ -316,28 +301,6 @@
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, body)
 
-    def update_volume_image_metadata(self, volume_id, **kwargs):
-        """Update image metadata for the volume.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-blockstorage-v2.html
-                              #setVolumeimagemetadata
-        """
-        post_body = json.dumps({'os-set_image_metadata': {'metadata': kwargs}})
-        url = "volumes/%s/action" % (volume_id)
-        resp, body = self.post(url, post_body)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def delete_volume_image_metadata(self, volume_id, key_name):
-        """Delete image metadata item for the volume."""
-        post_body = json.dumps({'os-unset_image_metadata': {'key': key_name}})
-        url = "volumes/%s/action" % (volume_id)
-        resp, body = self.post(url, post_body)
-        self.expected_success(200, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
     def retype_volume(self, volume_id, **kwargs):
         """Updates volume with new volume type."""
         post_body = json.dumps({'os-retype': kwargs})
diff --git a/tempest/services/volume/v1/__init__.py b/tempest/services/volume/v1/__init__.py
index 945d2f2..72868bc 100644
--- a/tempest/services/volume/v1/__init__.py
+++ b/tempest/services/volume/v1/__init__.py
@@ -20,10 +20,13 @@
 from tempest.lib.services.volume.v1.services_client import ServicesClient
 from tempest.services.volume.v1.json.admin.types_client import TypesClient
 from tempest.services.volume.v1.json.backups_client import BackupsClient
+from tempest.services.volume.v1.json.encryption_types_client import \
+    EncryptionTypesClient
 from tempest.services.volume.v1.json.qos_client import QosSpecsClient
 from tempest.services.volume.v1.json.snapshots_client import SnapshotsClient
 from tempest.services.volume.v1.json.volumes_client import VolumesClient
 
 __all__ = ['HostsClient', 'QuotasClient', 'ServicesClient', 'TypesClient',
            'AvailabilityZoneClient', 'BackupsClient', 'ExtensionsClient',
-           'QosSpecsClient', 'SnapshotsClient', 'VolumesClient']
+           'QosSpecsClient', 'SnapshotsClient', 'VolumesClient',
+           'EncryptionTypesClient']
diff --git a/tempest/services/volume/v1/json/admin/types_client.py b/tempest/services/volume/v1/json/admin/types_client.py
index 0e84296..dce728d 100644
--- a/tempest/services/volume/v1/json/admin/types_client.py
+++ b/tempest/services/volume/v1/json/admin/types_client.py
@@ -13,8 +13,148 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.base.admin import base_types_client
+from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest.lib.common import rest_client
+from tempest.lib import exceptions as lib_exc
 
 
-class TypesClient(base_types_client.BaseTypesClient):
-    """Volume V1 Volume Types client"""
+class TypesClient(rest_client.RestClient):
+    """Client class to send CRUD Volume Types API requests"""
+
+    def is_resource_deleted(self, id):
+        try:
+            self.show_volume_type(id)
+        except lib_exc.NotFound:
+            return True
+        return False
+
+    @property
+    def resource_type(self):
+        """Returns the primary type of resource this client works with."""
+        return 'volume-type'
+
+    def list_volume_types(self, **params):
+        """List all the volume_types created.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#listVolumeTypes
+        """
+        url = 'types'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_volume_type(self, volume_type_id):
+        """Returns the details of a single volume_type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#showVolumeType
+        """
+        url = "types/%s" % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_volume_type(self, **kwargs):
+        """Create volume type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#createVolumeType
+        """
+        post_body = json.dumps({'volume_type': kwargs})
+        resp, body = self.post('types', post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_volume_type(self, volume_type_id):
+        """Deletes the Specified Volume_type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v1.html#deleteVolumeType
+        """
+        resp, body = self.delete("types/%s" % volume_type_id)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_volume_types_extra_specs(self, volume_type_id, **params):
+        """List all the volume_types extra specs created.
+
+        TODO: Current api-site doesn't contain this API description.
+        After fixing the api-site, we need to fix here also for putting
+        the link to api-site.
+        """
+        url = 'types/%s/extra_specs' % volume_type_id
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_volume_type_extra_specs(self, volume_type_id, extra_specs_name):
+        """Returns the details of a single volume_type extra spec."""
+        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_specs_name)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_volume_type_extra_specs(self, volume_type_id, extra_specs):
+        """Creates a new Volume_type extra spec.
+
+        volume_type_id: Id of volume_type.
+        extra_specs: A dictionary of values to be used as extra_specs.
+        """
+        url = "types/%s/extra_specs" % volume_type_id
+        post_body = json.dumps({'extra_specs': extra_specs})
+        resp, body = self.post(url, post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_volume_type_extra_specs(self, volume_type_id, extra_spec_name):
+        """Deletes the Specified Volume_type extra spec."""
+        resp, body = self.delete("types/%s/extra_specs/%s" % (
+            volume_type_id, extra_spec_name))
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_volume_type(self, volume_type_id, **kwargs):
+        """Updates volume type name, description, and/or is_public.
+
+        Available params: see http://developer.openstack.org/
+        api-ref-blockstorage-v2.html#updateVolumeType
+        """
+        put_body = json.dumps({'volume_type': kwargs})
+        resp, body = self.put('types/%s' % volume_type_id, put_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_volume_type_extra_specs(self, volume_type_id, extra_spec_name,
+                                       extra_specs):
+        """Update a volume_type extra spec.
+
+        volume_type_id: Id of volume_type.
+        extra_spec_name: Name of the extra spec to be updated.
+        extra_spec: A dictionary of with key as extra_spec_name and the
+                     updated value.
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#
+                              updateVolumeTypeExtraSpecs
+        """
+        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_spec_name)
+        put_body = json.dumps(extra_specs)
+        resp, body = self.put(url, put_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/v1/json/encryption_types_client.py b/tempest/services/volume/v1/json/encryption_types_client.py
new file mode 100755
index 0000000..067b4e8
--- /dev/null
+++ b/tempest/services/volume/v1/json/encryption_types_client.py
@@ -0,0 +1,68 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
+from tempest.lib import exceptions as lib_exc
+
+
+class EncryptionTypesClient(rest_client.RestClient):
+
+    def is_resource_deleted(self, id):
+        try:
+            body = self.show_encryption_type(id)
+            if not body:
+                return True
+        except lib_exc.NotFound:
+            return True
+        return False
+
+    @property
+    def resource_type(self):
+        """Returns the primary type of resource this client works with."""
+        return 'encryption-type'
+
+    def show_encryption_type(self, volume_type_id):
+        """Get the volume encryption type for the specified volume type.
+
+        volume_type_id: Id of volume_type.
+        """
+        url = "/types/%s/encryption" % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_encryption_type(self, volume_type_id, **kwargs):
+        """Create encryption type.
+
+        TODO: Current api-site doesn't contain this API description.
+        After fixing the api-site, we need to fix here also for putting
+        the link to api-site.
+        """
+        url = "/types/%s/encryption" % volume_type_id
+        post_body = json.dumps({'encryption': kwargs})
+        resp, body = self.post(url, post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_encryption_type(self, volume_type_id):
+        """Delete the encryption type for the specified volume-type."""
+        resp, body = self.delete(
+            "/types/%s/encryption/provider" % volume_type_id)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/v2/__init__.py b/tempest/services/volume/v2/__init__.py
index 80f7a94..4afcc29 100644
--- a/tempest/services/volume/v2/__init__.py
+++ b/tempest/services/volume/v2/__init__.py
@@ -20,10 +20,13 @@
 from tempest.lib.services.volume.v2.services_client import ServicesClient
 from tempest.services.volume.v2.json.admin.types_client import TypesClient
 from tempest.services.volume.v2.json.backups_client import BackupsClient
+from tempest.services.volume.v2.json.encryption_types_client import \
+    EncryptionTypesClient
 from tempest.services.volume.v2.json.qos_client import QosSpecsClient
 from tempest.services.volume.v2.json.snapshots_client import SnapshotsClient
 from tempest.services.volume.v2.json.volumes_client import VolumesClient
 
 __all__ = ['HostsClient', 'QuotasClient', 'ServicesClient', 'TypesClient',
            'AvailabilityZoneClient', 'BackupsClient', 'ExtensionsClient',
-           'QosSpecsClient', 'SnapshotsClient', 'VolumesClient']
+           'QosSpecsClient', 'SnapshotsClient', 'VolumesClient',
+           'EncryptionTypesClient']
diff --git a/tempest/services/volume/v2/json/admin/types_client.py b/tempest/services/volume/v2/json/admin/types_client.py
index f76e8dc..d399e99 100644
--- a/tempest/services/volume/v2/json/admin/types_client.py
+++ b/tempest/services/volume/v2/json/admin/types_client.py
@@ -14,15 +14,152 @@
 #    under the License.
 
 from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
 
 from tempest.lib.common import rest_client
-from tempest.services.volume.base.admin import base_types_client
+from tempest.lib import exceptions as lib_exc
 
 
-class TypesClient(base_types_client.BaseTypesClient):
+class TypesClient(rest_client.RestClient):
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
 
+    def is_resource_deleted(self, id):
+        try:
+            self.show_volume_type(id)
+        except lib_exc.NotFound:
+            return True
+        return False
+
+    @property
+    def resource_type(self):
+        """Returns the primary type of resource this client works with."""
+        return 'volume-type'
+
+    def list_volume_types(self, **params):
+        """List all the volume_types created.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#showVolumeTypes
+        """
+        url = 'types'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_volume_type(self, volume_type_id):
+        """Returns the details of a single volume_type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#showVolumeType
+        """
+        url = "types/%s" % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_volume_type(self, **kwargs):
+        """Create volume type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#createVolumeType
+        """
+        post_body = json.dumps({'volume_type': kwargs})
+        resp, body = self.post('types', post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_volume_type(self, volume_type_id):
+        """Deletes the Specified Volume_type.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#deleteVolumeType
+        """
+        resp, body = self.delete("types/%s" % volume_type_id)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_volume_types_extra_specs(self, volume_type_id, **params):
+        """List all the volume_types extra specs created.
+
+        TODO: Current api-site doesn't contain this API description.
+        After fixing the api-site, we need to fix here also for putting
+        the link to api-site.
+        """
+        url = 'types/%s/extra_specs' % volume_type_id
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_volume_type_extra_specs(self, volume_type_id, extra_specs_name):
+        """Returns the details of a single volume_type extra spec."""
+        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_specs_name)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_volume_type_extra_specs(self, volume_type_id, extra_specs):
+        """Creates a new Volume_type extra spec.
+
+        volume_type_id: Id of volume_type.
+        extra_specs: A dictionary of values to be used as extra_specs.
+        """
+        url = "types/%s/extra_specs" % volume_type_id
+        post_body = json.dumps({'extra_specs': extra_specs})
+        resp, body = self.post(url, post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_volume_type_extra_specs(self, volume_type_id, extra_spec_name):
+        """Deletes the Specified Volume_type extra spec."""
+        resp, body = self.delete("types/%s/extra_specs/%s" % (
+            volume_type_id, extra_spec_name))
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_volume_type(self, volume_type_id, **kwargs):
+        """Updates volume type name, description, and/or is_public.
+
+        Available params: see http://developer.openstack.org/
+        api-ref-blockstorage-v2.html#updateVolumeType
+        """
+        put_body = json.dumps({'volume_type': kwargs})
+        resp, body = self.put('types/%s' % volume_type_id, put_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_volume_type_extra_specs(self, volume_type_id, extra_spec_name,
+                                       extra_specs):
+        """Update a volume_type extra spec.
+
+        volume_type_id: Id of volume_type.
+        extra_spec_name: Name of the extra spec to be updated.
+        extra_spec: A dictionary of with key as extra_spec_name and the
+                     updated value.
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html#
+                              updateVolumeTypeExtraSpecs
+        """
+        url = "types/%s/extra_specs/%s" % (volume_type_id, extra_spec_name)
+        put_body = json.dumps(extra_specs)
+        resp, body = self.put(url, put_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
     def add_type_access(self, volume_type_id, **kwargs):
         """Adds volume type access for the given project.
 
diff --git a/tempest/services/volume/v2/json/encryption_types_client.py b/tempest/services/volume/v2/json/encryption_types_client.py
new file mode 100755
index 0000000..8b01f11
--- /dev/null
+++ b/tempest/services/volume/v2/json/encryption_types_client.py
@@ -0,0 +1,69 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
+from tempest.lib import exceptions as lib_exc
+
+
+class EncryptionTypesClient(rest_client.RestClient):
+    api_version = "v2"
+
+    def is_resource_deleted(self, id):
+        try:
+            body = self.show_encryption_type(id)
+            if not body:
+                return True
+        except lib_exc.NotFound:
+            return True
+        return False
+
+    @property
+    def resource_type(self):
+        """Returns the primary type of resource this client works with."""
+        return 'encryption-type'
+
+    def show_encryption_type(self, volume_type_id):
+        """Get the volume encryption type for the specified volume type.
+
+        volume_type_id: Id of volume_type.
+        """
+        url = "/types/%s/encryption" % volume_type_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_encryption_type(self, volume_type_id, **kwargs):
+        """Create encryption type.
+
+        TODO: Current api-site doesn't contain this API description.
+        After fixing the api-site, we need to fix here also for putting
+        the link to api-site.
+        """
+        url = "/types/%s/encryption" % volume_type_id
+        post_body = json.dumps({'encryption': kwargs})
+        resp, body = self.post(url, post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_encryption_type(self, volume_type_id):
+        """Delete the encryption type for the specified volume-type."""
+        resp, body = self.delete(
+            "/types/%s/encryption/provider" % volume_type_id)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/v2/json/volumes_client.py b/tempest/services/volume/v2/json/volumes_client.py
index b7d9dfb..2a435e7 100644
--- a/tempest/services/volume/v2/json/volumes_client.py
+++ b/tempest/services/volume/v2/json/volumes_client.py
@@ -13,6 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
 from tempest.services.volume.base import base_volumes_client
 
 
@@ -20,3 +23,36 @@
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
     create_resp = 202
+
+    def update_volume_image_metadata(self, volume_id, **kwargs):
+        """Update image metadata for the volume.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html
+                              #setVolumeimagemetadata
+        """
+        post_body = json.dumps({'os-set_image_metadata': {'metadata': kwargs}})
+        url = "volumes/%s/action" % (volume_id)
+        resp, body = self.post(url, post_body)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_volume_image_metadata(self, volume_id, key_name):
+        """Delete image metadata item for the volume."""
+        post_body = json.dumps({'os-unset_image_metadata': {'key': key_name}})
+        url = "volumes/%s/action" % (volume_id)
+        resp, body = self.post(url, post_body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_pools(self, detail=False):
+        # List all the volumes pools (hosts)
+        url = 'scheduler-stats/get_pools'
+        if detail:
+            url += '?detail=True'
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/stress/actions/server_create_destroy.py b/tempest/stress/actions/server_create_destroy.py
index 44b6f62..183bc6c 100644
--- a/tempest/stress/actions/server_create_destroy.py
+++ b/tempest/stress/actions/server_create_destroy.py
@@ -27,7 +27,7 @@
         self.flavor = CONF.compute.flavor_ref
 
     def run(self):
-        name = data_utils.rand_name("instance")
+        name = data_utils.rand_name(self.__class__.__name__ + "-instance")
         self.logger.info("creating %s" % name)
         server = self.manager.servers_client.create_server(
             name=name, imageRef=self.image, flavorRef=self.flavor)['server']
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index c9a4d38..845b4a7 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -70,7 +70,8 @@
                          self.server_id, self.floating['ip'])
 
     def _create_vm(self):
-        self.name = name = data_utils.rand_name("instance")
+        self.name = name = data_utils.rand_name(
+            self.__class__.__name__ + "-instance")
         servers_client = self.manager.servers_client
         self.logger.info("creating %s" % name)
         vm_args = self.vm_extra_args.copy()
@@ -92,7 +93,7 @@
 
     def _create_sec_group(self):
         sec_grp_cli = self.manager.compute_security_groups_client
-        s_name = data_utils.rand_name('sec_grp')
+        s_name = data_utils.rand_name(self.__class__.__name__ + '-sec_grp')
         s_description = data_utils.rand_name('desc')
         self.sec_grp = sec_grp_cli.create_security_group(
             name=s_name, description=s_description)['security_group']
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index e06c364..5fc006e 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -27,7 +27,7 @@
 
     def run(self):
         # Step 1: create volume
-        name = data_utils.rand_name("volume")
+        name = data_utils.rand_name(self.__class__.__name__ + "-volume")
         self.logger.info("creating volume: %s" % name)
         volume = self.manager.volumes_client.create_volume(
             display_name=name, size=CONF.volume.volume_size)['volume']
@@ -36,7 +36,7 @@
         self.logger.info("created volume: %s" % volume['id'])
 
         # Step 2: create vm instance
-        vm_name = data_utils.rand_name("instance")
+        vm_name = data_utils.rand_name(self.__class__.__name__ + "-instance")
         self.logger.info("creating vm: %s" % vm_name)
         server = self.manager.servers_client.create_server(
             name=vm_name, imageRef=self.image, flavorRef=self.flavor)['server']
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index 743cb11..4fbb851 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -33,7 +33,8 @@
         self.manager.keypairs_client.delete_keypair(self.key['name'])
 
     def _create_vm(self):
-        self.name = name = data_utils.rand_name("instance")
+        self.name = name = data_utils.rand_name(
+            self.__class__.__name__ + "-instance")
         servers_client = self.manager.servers_client
         self.logger.info("creating %s" % name)
         vm_args = self.vm_extra_args.copy()
@@ -55,7 +56,7 @@
 
     def _create_sec_group(self):
         sec_grp_cli = self.manager.compute_security_groups_client
-        s_name = data_utils.rand_name('sec_grp')
+        s_name = data_utils.rand_name(self.__class__.__name__ + '-sec_grp')
         s_description = data_utils.rand_name('desc')
         self.sec_grp = sec_grp_cli.create_security_group(
             name=s_name, description=s_description)['security_group']
@@ -81,7 +82,7 @@
         self.logger.info("Deleted Floating IP %s", str(self.floating['ip']))
 
     def _create_volume(self):
-        name = data_utils.rand_name("volume")
+        name = data_utils.rand_name(self.__class__.__name__ + "-volume")
         self.logger.info("creating volume: %s" % name)
         volumes_client = self.manager.volumes_client
         self.volume = volumes_client.create_volume(
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index 8c74d9c..613bc63 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -28,14 +28,15 @@
     v2_tenants_client
 from tempest.lib.services.identity.v2 import token_client as v2_token_client
 from tempest.lib.services.identity.v2 import users_client as v2_users_client
+from tempest.lib.services.identity.v3 import identity_client as v3_iden_client
 from tempest.lib.services.identity.v3 import projects_client as \
     v3_projects_client
 from tempest.lib.services.identity.v3 import token_client as v3_token_client
+from tempest.lib.services.identity.v3 import users_client as \
+    v3_users_client
 from tempest.lib.services.network import routers_client
 from tempest.services.identity.v3.json import domains_client
-from tempest.services.identity.v3.json import identity_client as v3_iden_client
 from tempest.services.identity.v3.json import roles_client as v3_roles_client
-from tempest.services.identity.v3.json import users_clients as v3_users_client
 from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests.lib import fake_http
@@ -55,7 +56,6 @@
     users_client = v2_users_client
     token_client_class = token_client.TokenClient
     fake_response = fake_identity._fake_v2_response
-    assign_role_on_project = 'create_user_role_on_project'
     tenants_client_class = tenants_client.TenantsClient
     delete_tenant = 'delete_tenant'
 
@@ -125,7 +125,7 @@
     def _mock_assign_user_role(self):
         tenant_fix = self.useFixture(mockpatch.PatchObject(
             self.roles_client.RolesClient,
-            self.assign_role_on_project,
+            'create_user_role_on_project',
             return_value=(rest_client.ResponseBody
                           (200, {}))))
         return tenant_fix
@@ -198,11 +198,11 @@
         self._mock_tenant_create('1234', 'fake_admin_tenant')
 
         user_mock = mock.patch.object(self.roles_client.RolesClient,
-                                      self.assign_role_on_project)
+                                      'create_user_role_on_project')
         user_mock.start()
         self.addCleanup(user_mock.stop)
         with mock.patch.object(self.roles_client.RolesClient,
-                               self.assign_role_on_project) as user_mock:
+                               'create_user_role_on_project') as user_mock:
             admin_creds = creds.get_admin_creds()
         user_mock.assert_has_calls([
             mock.call('1234', '1234', '1234')])
@@ -221,11 +221,11 @@
         self._mock_tenant_create('1234', 'fake_role_tenant')
 
         user_mock = mock.patch.object(self.roles_client.RolesClient,
-                                      self.assign_role_on_project)
+                                      'create_user_role_on_project')
         user_mock.start()
         self.addCleanup(user_mock.stop)
         with mock.patch.object(self.roles_client.RolesClient,
-                               self.assign_role_on_project) as user_mock:
+                               'create_user_role_on_project') as user_mock:
             role_creds = creds.get_creds_by_roles(
                 roles=['role1', 'role2'])
         calls = user_mock.mock_calls
@@ -612,7 +612,6 @@
     users_client = v3_users_client
     token_client_class = token_client.V3TokenClient
     fake_response = fake_identity._fake_v3_response
-    assign_role_on_project = 'assign_user_role_on_project'
     tenants_client_class = tenants_client.ProjectsClient
     delete_tenant = 'delete_project'
 
@@ -624,7 +623,7 @@
             return_value=dict(domains=[dict(id='default',
                                             name='Default')])))
         self.patchobject(self.roles_client.RolesClient,
-                         'assign_user_role_on_domain')
+                         'create_user_role_on_domain')
 
     def _mock_list_ec2_credentials(self, user_id, tenant_id):
         pass
diff --git a/tempest/tests/lib/services/identity/v3/test_groups_client.py b/tempest/tests/lib/services/identity/v3/test_groups_client.py
new file mode 100644
index 0000000..38cf3ae
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_groups_client.py
@@ -0,0 +1,213 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from tempest.lib.services.identity.v3 import groups_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestGroupsClient(base.BaseServiceTest):
+    FAKE_CREATE_GROUP = {
+        'group': {
+            'description': 'Tempest Group Description',
+            'domain_id': 'TempestDomain',
+            'name': 'Tempest Group',
+        }
+    }
+
+    FAKE_GROUP_INFO = {
+        'group': {
+            'description': 'Tempest Group Description',
+            'domain_id': 'TempestDomain',
+            'id': '6e13e2068cf9466e98950595baf6bb35',
+            'links': {
+                'self': 'http://example.com/identity/v3/groups/' +
+                        '6e13e2068cf9466e98950595baf6bb35'
+            },
+            'name': 'Tempest Group',
+        }
+    }
+
+    FAKE_GROUP_LIST = {
+        'links': {
+            'self': 'http://example.com/identity/v3/groups',
+            'previous': None,
+            'next': None,
+        },
+        'groups': [
+            {
+                'description': 'Tempest Group One Description',
+                'domain_id': 'TempestDomain',
+                'id': '1c92f3453ed34291a074b87493455b8f',
+                'links': {
+                    'self': 'http://example.com/identity/v3/groups/' +
+                            '1c92f3453ed34291a074b87493455b8f'
+                },
+                'name': 'Tempest Group One',
+            },
+            {
+                'description': 'Tempest Group Two Description',
+                'domain_id': 'TempestDomain',
+                'id': 'ce9e7dafed3b4877a7d4466ed730a9ee',
+                'links': {
+                    'self': 'http://example.com/identity/v3/groups/' +
+                            'ce9e7dafed3b4877a7d4466ed730a9ee'
+                },
+                'name': 'Tempest Group Two',
+            },
+        ]
+    }
+
+    FAKE_USER_LIST = {
+        'links': {
+            'self': 'http://example.com/identity/v3/groups/' +
+                    '6e13e2068cf9466e98950595baf6bb35/users',
+            'previous': None,
+            'next': None,
+        },
+        'users': [
+            {
+                'domain_id': 'TempestDomain',
+                'description': 'Tempest Test User One Description',
+                'enabled': True,
+                'id': '642688fa65a84217b86cef3c063de2b9',
+                'name': 'TempestUserOne',
+                'links': {
+                    'self': 'http://example.com/identity/v3/users/' +
+                            '642688fa65a84217b86cef3c063de2b9'
+                }
+            },
+            {
+                'domain_id': 'TempestDomain',
+                'description': 'Tempest Test User Two Description',
+                'enabled': True,
+                'id': '1048ead6f8ef4a859b44ffbce3ac0b52',
+                'name': 'TempestUserTwo',
+                'links': {
+                    'self': 'http://example.com/identity/v3/users/' +
+                            '1048ead6f8ef4a859b44ffbce3ac0b52'
+                }
+            },
+        ]
+    }
+
+    def setUp(self):
+        super(TestGroupsClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = groups_client.GroupsClient(fake_auth, 'identity',
+                                                 'regionOne')
+
+    def _test_create_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_group,
+            'tempest.lib.common.rest_client.RestClient.post',
+            self.FAKE_CREATE_GROUP,
+            bytes_body,
+            status=201,
+        )
+
+    def _test_show_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_group,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_GROUP_INFO,
+            bytes_body,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+        )
+
+    def _test_list_groups(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_groups,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_GROUP_LIST,
+            bytes_body,
+        )
+
+    def _test_update_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.update_group,
+            'tempest.lib.common.rest_client.RestClient.patch',
+            self.FAKE_GROUP_INFO,
+            bytes_body,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+            name='NewName',
+        )
+
+    def _test_list_users_in_group(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_group_users,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_USER_LIST,
+            bytes_body,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+        )
+
+    def test_create_group_with_string_body(self):
+        self._test_create_group()
+
+    def test_create_group_with_bytes_body(self):
+        self._test_create_group(bytes_body=True)
+
+    def test_show_group_with_string_body(self):
+        self._test_show_group()
+
+    def test_show_group_with_bytes_body(self):
+        self._test_show_group(bytes_body=True)
+
+    def test_list_groups_with_string_body(self):
+        self._test_list_groups()
+
+    def test_list_groups_with_bytes_body(self):
+        self._test_list_groups(bytes_body=True)
+
+    def test_update_group_with_string_body(self):
+        self._test_update_group()
+
+    def test_update_group_with_bytes_body(self):
+        self._test_update_group(bytes_body=True)
+
+    def test_list_users_in_group_with_string_body(self):
+        self._test_list_users_in_group()
+
+    def test_list_users_in_group_with_bytes_body(self):
+        self._test_list_users_in_group(bytes_body=True)
+
+    def test_delete_group(self):
+        self.check_service_client_function(
+            self.client.delete_group,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+            status=204,
+        )
+
+    def test_add_user_to_group(self):
+        self.check_service_client_function(
+            self.client.add_group_user,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            status=204,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+            user_id='642688fa65a84217b86cef3c063de2b9',
+        )
+
+    def test_check_user_in_group(self):
+        self.check_service_client_function(
+            self.client.check_group_user_existence,
+            'tempest.lib.common.rest_client.RestClient.head',
+            {},
+            status=204,
+            group_id='6e13e2068cf9466e98950595baf6bb35',
+            user_id='642688fa65a84217b86cef3c063de2b9',
+        )
diff --git a/tempest/tests/lib/services/identity/v3/test_identity_client.py b/tempest/tests/lib/services/identity/v3/test_identity_client.py
new file mode 100644
index 0000000..9eaaaaf
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_identity_client.py
@@ -0,0 +1,75 @@
+# Copyright 2016 NEC Corporation.  All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.lib.services.identity.v3 import identity_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestIdentityClient(base.BaseServiceTest):
+    FAKE_TOKEN = {
+        "tokens": {
+            "id": "cbc36478b0bd8e67e89",
+            "name": "FakeToken",
+            "type": "token",
+        }
+    }
+
+    FAKE_API_INFO = {
+        "name": "API_info",
+        "type": "API",
+        "description": "test_description"
+    }
+
+    def setUp(self):
+        super(TestIdentityClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = identity_client.IdentityClient(fake_auth,
+                                                     'identity',
+                                                     'regionOne')
+
+    def _test_show_api_description(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_api_description,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_API_INFO,
+            bytes_body)
+
+    def _test_show_token(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_token,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_TOKEN,
+            bytes_body,
+            resp_token="cbc36478b0bd8e67e89")
+
+    def test_show_api_description_with_str_body(self):
+        self._test_show_api_description()
+
+    def test_show_api_description_with_bytes_body(self):
+        self._test_show_api_description(bytes_body=True)
+
+    def test_show_token_with_str_body(self):
+        self._test_show_token()
+
+    def test_show_token_with_bytes_body(self):
+        self._test_show_token(bytes_body=True)
+
+    def test_delete_token(self):
+        self.check_service_client_function(
+            self.client.delete_token,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            resp_token="cbc36478b0bd8e67e89",
+            status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_users_client.py b/tempest/tests/lib/services/identity/v3/test_users_client.py
new file mode 100644
index 0000000..5b572f5
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_users_client.py
@@ -0,0 +1,205 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from tempest.lib.services.identity.v3 import users_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestUsersClient(base.BaseServiceTest):
+    FAKE_CREATE_USER = {
+        'user': {
+            'default_project_id': '95f8c3f8e7b54409a418fc30717f9ae0',
+            'domain_id': '8347b31afc3545c4b311cb4cce788a08',
+            'enabled': True,
+            'name': 'Tempest User',
+            'password': 'TempestPassword',
+        }
+    }
+
+    FAKE_USER_INFO = {
+        'user': {
+            'default_project_id': '95f8c3f8e7b54409a418fc30717f9ae0',
+            'domain_id': '8347b31afc3545c4b311cb4cce788a08',
+            'enabled': True,
+            'id': '817fb3c23fd7465ba6d7fe1b1320121d',
+            'links': {
+                'self': 'http://example.com/identity',
+            },
+            'name': 'Tempest User',
+            'password_expires_at': '2016-11-06T15:32:17.000000',
+        }
+    }
+
+    FAKE_USER_LIST = {
+        'links': {
+            'next': None,
+            'previous': None,
+            'self': 'http://example.com/identity/v3/users',
+        },
+        'users': [
+            {
+                'domain_id': 'TempestDomain',
+                'enabled': True,
+                'id': '817fb3c23fd7465ba6d7fe1b1320121d',
+                'links': {
+                    'self': 'http://example.com/identity/v3/users/' +
+                            '817fb3c23fd7465ba6d7fe1b1320121d',
+                },
+                'name': 'Tempest User',
+                'password_expires_at': '2016-11-06T15:32:17.000000',
+            },
+            {
+                'domain_id': 'TempestDomain',
+                'enabled': True,
+                'id': 'bdbfb1e2f1344be197e90a778379cca1',
+                'links': {
+                    'self': 'http://example.com/identity/v3/users/' +
+                            'bdbfb1e2f1344be197e90a778379cca1',
+                },
+                'name': 'Tempest User',
+                'password_expires_at': None,
+            },
+        ]
+    }
+
+    FAKE_GROUP_LIST = {
+        'links': {
+            'self': 'http://example.com/identity/v3/groups',
+            'previous': None,
+            'next': None,
+        },
+        'groups': [
+            {
+                'description': 'Tempest Group One Description',
+                'domain_id': 'TempestDomain',
+                'id': '1c92f3453ed34291a074b87493455b8f',
+                'links': {
+                    'self': 'http://example.com/identity/v3/groups/' +
+                            '1c92f3453ed34291a074b87493455b8f'
+                },
+                'name': 'Tempest Group One',
+            },
+            {
+                'description': 'Tempest Group Two Description',
+                'domain_id': 'TempestDomain',
+                'id': 'ce9e7dafed3b4877a7d4466ed730a9ee',
+                'links': {
+                    'self': 'http://example.com/identity/v3/groups/' +
+                            'ce9e7dafed3b4877a7d4466ed730a9ee'
+                },
+                'name': 'Tempest Group Two',
+            },
+        ]
+    }
+
+    def setUp(self):
+        super(TestUsersClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = users_client.UsersClient(fake_auth, 'identity',
+                                               'regionOne')
+
+    def _test_create_user(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_user,
+            'tempest.lib.common.rest_client.RestClient.post',
+            self.FAKE_CREATE_USER,
+            bytes_body,
+            status=201,
+        )
+
+    def _test_show_user(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_user,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_USER_INFO,
+            bytes_body,
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+        )
+
+    def _test_list_users(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_users,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_USER_LIST,
+            bytes_body,
+        )
+
+    def _test_update_user(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.update_user,
+            'tempest.lib.common.rest_client.RestClient.patch',
+            self.FAKE_USER_INFO,
+            bytes_body,
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+            name='NewName',
+        )
+
+    def _test_list_user_groups(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_user_groups,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_GROUP_LIST,
+            bytes_body,
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+        )
+
+    def test_create_user_with_string_body(self):
+        self._test_create_user()
+
+    def test_create_user_with_bytes_body(self):
+        self._test_create_user(bytes_body=True)
+
+    def test_show_user_with_string_body(self):
+        self._test_show_user()
+
+    def test_show_user_with_bytes_body(self):
+        self._test_show_user(bytes_body=True)
+
+    def test_list_users_with_string_body(self):
+        self._test_list_users()
+
+    def test_list_users_with_bytes_body(self):
+        self._test_list_users(bytes_body=True)
+
+    def test_update_user_with_string_body(self):
+        self._test_update_user()
+
+    def test_update_user_with_bytes_body(self):
+        self._test_update_user(bytes_body=True)
+
+    def test_list_user_groups_with_string_body(self):
+        self._test_list_user_groups()
+
+    def test_list_user_groups_with_bytes_body(self):
+        self._test_list_user_groups(bytes_body=True)
+
+    def test_delete_user(self):
+        self.check_service_client_function(
+            self.client.delete_user,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+            status=204,
+        )
+
+    def test_change_user_password(self):
+        self.check_service_client_function(
+            self.client.update_user_password,
+            'tempest.lib.common.rest_client.RestClient.post',
+            {},
+            status=204,
+            user_id='817fb3c23fd7465ba6d7fe1b1320121d',
+            password='NewTempestPassword',
+            original_password='OldTempestPassword')