Merge "Make image_client use **kwargs"
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index d5af4b4..82e4ec8 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -25,7 +25,7 @@
         name = data_utils.rand_name('Group')
         description = data_utils.rand_name('Description')
         group = self.groups_client.create_group(
-            name, description=description)['group']
+            name=name, description=description)['group']
         self.addCleanup(self.groups_client.delete_group, group['id'])
         self.assertEqual(group['name'], name)
         self.assertEqual(group['description'], description)
@@ -37,7 +37,7 @@
         self.assertEqual(updated_group['name'], new_name)
         self.assertEqual(updated_group['description'], new_desc)
 
-        new_group = self.groups_client.get_group(group['id'])['group']
+        new_group = self.groups_client.show_group(group['id'])['group']
         self.assertEqual(group['id'], new_group['id'])
         self.assertEqual(new_name, new_group['name'])
         self.assertEqual(new_desc, new_group['description'])
@@ -46,7 +46,7 @@
     @test.idempotent_id('1598521a-2f36-4606-8df9-30772bd51339')
     def test_group_users_add_list_delete(self):
         name = data_utils.rand_name('Group')
-        group = self.groups_client.create_group(name)['group']
+        group = self.groups_client.create_group(name=name)['group']
         self.addCleanup(self.groups_client.delete_group, group['id'])
         # add user into group
         users = []
@@ -77,7 +77,7 @@
         groups = []
         for i in range(2):
             name = data_utils.rand_name('Group')
-            group = self.groups_client.create_group(name)['group']
+            group = self.groups_client.create_group(name=name)['group']
             groups.append(group)
             self.addCleanup(self.groups_client.delete_group, group['id'])
             self.groups_client.add_group_user(group['id'], user['id'])
@@ -95,7 +95,7 @@
             name = data_utils.rand_name('Group')
             description = data_utils.rand_name('Description')
             group = self.groups_client.create_group(
-                name, description=description)['group']
+                name=name, description=description)['group']
             self.addCleanup(self.groups_client.delete_group, group['id'])
             group_ids.append(group['id'])
         # List and Verify Groups
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index d5350a1..3be2643 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -40,7 +40,7 @@
             description=data_utils.rand_name('project-desc'),
             domain_id=cls.domain['id'])['project']
         cls.group_body = cls.groups_client.create_group(
-            data_utils.rand_name('Group'), project_id=cls.project['id'],
+            name=data_utils.rand_name('Group'), project_id=cls.project['id'],
             domain_id=cls.domain['id'])['group']
         cls.user_body = cls.client.create_user(
             u_name, description=u_desc, password=cls.u_password,
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 4337922..6d2aaea 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -11,7 +11,7 @@
 #    under the License.
 
 from oslo_log import log as logging
-
+import six
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import config
@@ -34,9 +34,14 @@
     @classmethod
     def resource_setup(cls):
         super(VolumeMultiBackendV2Test, cls).resource_setup()
-
-        cls.backend1_name = CONF.volume.backend1_name
-        cls.backend2_name = CONF.volume.backend2_name
+        # support 2 backends names, deprecated_for_removal.
+        # keep support 2 backend names, in case they are not empty
+        if CONF.volume.backend1_name and CONF.volume.backend2_name:
+            cls.backend_names = {CONF.volume.backend1_name,
+                                 CONF.volume.backend2_name}
+        else:
+            # read backend name from a list .
+            cls.backend_names = set(CONF.volume.backend_names)
 
         cls.name_field = cls.special_fields['name_field']
         cls.volume_type_id_list = []
@@ -44,15 +49,15 @@
         cls.volume_id_list_without_prefix = []
 
         # Volume/Type creation (uses volume_backend_name)
-        cls._create_type_and_volume(cls.backend1_name, False)
-        # Volume/Type creation (uses capabilities:volume_backend_name)
-        cls._create_type_and_volume(cls.backend1_name, True)
-
-        if cls.backend1_name != cls.backend2_name:
-            # Volume/Type creation (uses backend2_name)
-            cls._create_type_and_volume(cls.backend2_name, False)
+        # It is not allowed to create the same backend name twice
+        if len(cls.backend_names) < 2:
+            raise cls.skipException("Requires at least two different "
+                                    "backend names")
+        for backend_name in cls.backend_names:
+            # Volume/Type creation (uses backend_name)
+            cls._create_type_and_volume(backend_name, False)
             # Volume/Type creation (uses capabilities:volume_backend_name)
-            cls._create_type_and_volume(cls.backend2_name, True)
+            cls._create_type_and_volume(backend_name, True)
 
     @classmethod
     def _create_type_and_volume(self, backend_name_key, with_prefix):
@@ -104,32 +109,28 @@
     @test.idempotent_id('c1a41f3f-9dad-493e-9f09-3ff197d477cc')
     def test_backend_name_reporting(self):
         # get volume id which created by type without prefix
-        volume_id = self.volume_id_list_without_prefix[0]
-        self._test_backend_name_reporting_by_volume_id(volume_id)
+        for volume_id in self.volume_id_list_without_prefix:
+            self._test_backend_name_reporting_by_volume_id(volume_id)
 
     @test.idempotent_id('f38e647f-ab42-4a31-a2e7-ca86a6485215')
     def test_backend_name_reporting_with_prefix(self):
         # get volume id which created by type with prefix
-        volume_id = self.volume_id_list_with_prefix[0]
-        self._test_backend_name_reporting_by_volume_id(volume_id)
+        for volume_id in self.volume_id_list_with_prefix:
+            self._test_backend_name_reporting_by_volume_id(volume_id)
 
     @test.idempotent_id('46435ab1-a0af-4401-8373-f14e66b0dd58')
     def test_backend_name_distinction(self):
-        if self.backend1_name == self.backend2_name:
-            raise self.skipException("backends configured with same name")
-        # get volume id which created by type without prefix
-        volume1_id = self.volume_id_list_without_prefix[0]
-        volume2_id = self.volume_id_list_without_prefix[1]
-        self._test_backend_name_distinction(volume1_id, volume2_id)
+        # get volume ids which created by type without prefix
+        self._test_backend_name_distinction(self.volume_id_list_without_prefix)
 
     @test.idempotent_id('4236305b-b65a-4bfc-a9d2-69cb5b2bf2ed')
     def test_backend_name_distinction_with_prefix(self):
-        if self.backend1_name == self.backend2_name:
-            raise self.skipException("backends configured with same name")
-        # get volume id which created by type without prefix
-        volume1_id = self.volume_id_list_with_prefix[0]
-        volume2_id = self.volume_id_list_with_prefix[1]
-        self._test_backend_name_distinction(volume1_id, volume2_id)
+        # get volume ids which created by type without prefix
+        self._test_backend_name_distinction(self.volume_id_list_with_prefix)
+
+    def _get_volume_host(self, volume_id):
+        return self.admin_volume_client.show_volume(
+            volume_id)['volume']['os-vol-host-attr:host']
 
     def _test_backend_name_reporting_by_volume_id(self, volume_id):
         # this test checks if os-vol-attr:host is populated correctly after
@@ -143,19 +144,16 @@
                volume_id)
         self.assertTrue(len(volume1_host.split("@")) > 1, msg)
 
-    def _test_backend_name_distinction(self, volume1_id, volume2_id):
-        # this test checks that the two volumes created at setUp don't
+    def _test_backend_name_distinction(self, volume_id_list):
+        # this test checks that the volumes created at setUp don't
         # belong to the same backend (if they are, than the
         # volume backend distinction is not working properly)
-        volume = self.admin_volume_client.show_volume(volume1_id)['volume']
-        volume1_host = volume['os-vol-host-attr:host']
-
-        volume = self.admin_volume_client.show_volume(volume2_id)['volume']
-        volume2_host = volume['os-vol-host-attr:host']
-
-        msg = ("volumes %s and %s were created in the same backend" %
-               (volume1_id, volume2_id))
-        self.assertNotEqual(volume1_host, volume2_host, msg)
+        volume_hosts = [self._get_volume_host(volume) for volume in
+                        volume_id_list]
+        # assert that volumes are each created on separate hosts:
+        msg = ("volumes %s were created in the same backend" % ", "
+               .join(volume_hosts))
+        six.assertCountEqual(self, volume_hosts, set(volume_hosts), msg)
 
 
 class VolumeMultiBackendV1Test(VolumeMultiBackendV2Test):
diff --git a/tempest/api_schema/response/compute/v2_1/services.py b/tempest/api_schema/response/compute/v2_1/services.py
deleted file mode 100644
index ddef7b2..0000000
--- a/tempest/api_schema/response/compute/v2_1/services.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2014 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-list_services = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'services': {
-                'type': 'array',
-                'items': {
-                    'type': 'object',
-                    'properties': {
-                        'id': {'type': ['integer', 'string'],
-                               'pattern': '^[a-zA-Z!]*@[0-9]+$'},
-                        'zone': {'type': 'string'},
-                        'host': {'type': 'string'},
-                        'state': {'type': 'string'},
-                        'binary': {'type': 'string'},
-                        'status': {'type': 'string'},
-                        'updated_at': {'type': ['string', 'null']},
-                        'disabled_reason': {'type': ['string', 'null']}
-                    },
-                    'additionalProperties': False,
-                    'required': ['id', 'zone', 'host', 'state', 'binary',
-                                 'status', 'updated_at', 'disabled_reason']
-                }
-            }
-        },
-        'additionalProperties': False,
-        'required': ['services']
-    }
-}
-
-enable_disable_service = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'service': {
-                'type': 'object',
-                'properties': {
-                    'status': {'type': 'string'},
-                    'binary': {'type': 'string'},
-                    'host': {'type': 'string'}
-                },
-                'additionalProperties': False,
-                'required': ['status', 'binary', 'host']
-            }
-        },
-        'additionalProperties': False,
-        'required': ['service']
-    }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/snapshots.py b/tempest/api_schema/response/compute/v2_1/snapshots.py
deleted file mode 100644
index 01a524b..0000000
--- a/tempest/api_schema/response/compute/v2_1/snapshots.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2015 Fujitsu(fnst) 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.
-
-common_snapshot_info = {
-    'type': 'object',
-    'properties': {
-        'id': {'type': 'string'},
-        'volumeId': {'type': 'string'},
-        'status': {'type': 'string'},
-        'size': {'type': 'integer'},
-        'createdAt': {'type': 'string'},
-        'displayName': {'type': ['string', 'null']},
-        'displayDescription': {'type': ['string', 'null']}
-    },
-    'additionalProperties': False,
-    'required': ['id', 'volumeId', 'status', 'size',
-                 'createdAt', 'displayName', 'displayDescription']
-}
-
-create_get_snapshot = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'snapshot': common_snapshot_info
-        },
-        'additionalProperties': False,
-        'required': ['snapshot']
-    }
-}
-
-list_snapshots = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'snapshots': {
-                'type': 'array',
-                'items': common_snapshot_info
-            }
-        },
-        'additionalProperties': False,
-        'required': ['snapshots']
-    }
-}
-
-delete_snapshot = {
-    'status_code': [202]
-}
diff --git a/tempest/clients.py b/tempest/clients.py
index b6f2545..ded94b2 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -47,6 +47,11 @@
 from tempest_lib.services.compute.quotas_client import QuotasClient
 from tempest_lib.services.compute.security_group_default_rules_client import \
     SecurityGroupDefaultRulesClient
+from tempest_lib.services.compute.security_groups_client import \
+    SecurityGroupsClient
+from tempest_lib.services.compute.services_client import ServicesClient
+from tempest_lib.services.compute.snapshots_client import \
+    SnapshotsClient as ComputeSnapshotsClient
 from tempest_lib.services.identity.v2.token_client import TokenClient
 from tempest_lib.services.identity.v3.token_client import V3TokenClient
 
@@ -64,14 +69,9 @@
 from tempest.services.compute.json.keypairs_client import KeyPairsClient
 from tempest.services.compute.json.security_group_rules_client import \
     SecurityGroupRulesClient
-from tempest.services.compute.json.security_groups_client import \
-    SecurityGroupsClient
 from tempest.services.compute.json.server_groups_client import \
     ServerGroupsClient
 from tempest.services.compute.json.servers_client import ServersClient
-from tempest.services.compute.json.services_client import ServicesClient
-from tempest.services.compute.json.snapshots_client import \
-    SnapshotsClient as ComputeSnapshotsClient
 from tempest.services.compute.json.tenant_networks_client import \
     TenantNetworksClient
 from tempest.services.compute.json.tenant_usages_client import \
@@ -90,16 +90,18 @@
 from tempest.services.identity.v2.json.identity_client import \
     IdentityClient
 from tempest.services.identity.v3.json.credentials_client import \
-    CredentialsClient
+    CredentialsClient as CredentialsV3Client
 from tempest.services.identity.v3.json.endpoints_client import \
-    EndPointClient
-from tempest.services.identity.v3.json.groups_client import GroupsClient
-from tempest.services.identity.v3.json.identity_client import \
-    IdentityV3Client
-from tempest.services.identity.v3.json.policy_client import PolicyClient
-from tempest.services.identity.v3.json.region_client import RegionClient
+    EndPointClient as EndPointV3Client
+from tempest.services.identity.v3.json.groups_client import \
+    GroupsClient as GroupsV3Client
+from tempest.services.identity.v3.json.identity_client import IdentityV3Client
+from tempest.services.identity.v3.json.policy_client import \
+    PolicyClient as PolicyV3Client
+from tempest.services.identity.v3.json.region_client import \
+    RegionClient as RegionV3Client
 from tempest.services.identity.v3.json.service_client import \
-    ServiceClient
+    ServiceClient as ServiceV3Client
 from tempest.services.image.v1.json.image_client import ImageClient
 from tempest.services.image.v2.json.image_client import ImageClientV2
 from tempest.services.messaging.json.messaging_client import \
@@ -406,17 +408,17 @@
                                                      **params_v2_public)
         params_v3 = params.copy()
         params_v3['endpoint_type'] = CONF.identity.v3_endpoint_type
-        # Client uses the endpoint type of Keystone API v3
+        # Clients below use the endpoint type of Keystone API v3
         self.identity_v3_client = IdentityV3Client(self.auth_provider,
                                                    **params_v3)
-        self.endpoints_client = EndPointClient(self.auth_provider,
-                                               **params)
-        self.service_client = ServiceClient(self.auth_provider, **params)
-        self.policy_client = PolicyClient(self.auth_provider, **params)
-        self.region_client = RegionClient(self.auth_provider, **params)
-        self.credentials_client = CredentialsClient(self.auth_provider,
-                                                    **params)
-        self.groups_client = GroupsClient(self.auth_provider, **params_v3)
+        self.endpoints_client = EndPointV3Client(self.auth_provider,
+                                                 **params_v3)
+        self.service_client = ServiceV3Client(self.auth_provider, **params_v3)
+        self.policy_client = PolicyV3Client(self.auth_provider, **params_v3)
+        self.region_client = RegionV3Client(self.auth_provider, **params_v3)
+        self.credentials_client = CredentialsV3Client(self.auth_provider,
+                                                      **params_v3)
+        self.groups_client = GroupsV3Client(self.auth_provider, **params_v3)
         # Token clients do not use the catalog. They only need default_params.
         # They read auth_url, so they should only be set if the corresponding
         # API version is marked as enabled
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 3df19fc..184bb9a 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -118,6 +118,7 @@
 from tempest_lib import auth
 from tempest_lib import exceptions as lib_exc
 from tempest_lib.services.compute import flavors_client
+from tempest_lib.services.compute import security_groups_client
 import yaml
 
 from tempest.common import identity
@@ -125,7 +126,6 @@
 from tempest import config
 from tempest.services.compute.json import floating_ips_client
 from tempest.services.compute.json import security_group_rules_client
-from tempest.services.compute.json import security_groups_client
 from tempest.services.compute.json import servers_client
 from tempest.services.identity.v2.json import identity_client
 from tempest.services.image.v2.json import image_client
diff --git a/tempest/config.py b/tempest/config.py
index c9fe38d..8c3656f 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -722,11 +722,21 @@
                         'publicURL', 'adminURL', 'internalURL'],
                help="The endpoint type to use for the volume service."),
     cfg.StrOpt('backend1_name',
-               default='BACKEND_1',
-               help="Name of the backend1 (must be declared in cinder.conf)"),
+               default='',
+               help='Name of the backend1 (must be declared in cinder.conf)',
+               deprecated_for_removal=True),
     cfg.StrOpt('backend2_name',
-               default='BACKEND_2',
-               help="Name of the backend2 (must be declared in cinder.conf)"),
+               default='',
+               help='Name of the backend2 (must be declared in cinder.conf)',
+               deprecated_for_removal=True),
+    cfg.ListOpt('backend_names',
+                default=['BACKEND_1', 'BACKEND_2'],
+                help='A list of backend names seperated by comma .'
+                     'The backend name must be declared in cinder.conf',
+                deprecated_opts=[cfg.DeprecatedOpt('BACKEND_1',
+                                                   group='volume'),
+                                 cfg.DeprecatedOpt('BACKEND_2',
+                                                   group='volume')]),
     cfg.StrOpt('storage_protocol',
                default='iSCSI',
                help='Backend protocol to target when creating volume types'),
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
index 7c5a55d..f1655d0 100644
--- a/tempest/hacking/ignored_list_T110.txt
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -1,6 +1,5 @@
 ./tempest/services/database/json/flavors_client.py
 ./tempest/services/identity/v3/json/credentials_client.py
-./tempest/services/identity/v3/json/groups_client.py
 ./tempest/services/identity/v3/json/identity_client.py
 ./tempest/services/identity/v3/json/policy_client.py
 ./tempest/services/identity/v3/json/region_client.py
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
deleted file mode 100644
index c996079..0000000
--- a/tempest/services/compute/json/security_groups_client.py
+++ /dev/null
@@ -1,89 +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 import exceptions as lib_exc
-
-from tempest.api_schema.response.compute.v2_1 import security_groups as schema
-from tempest.common import service_client
-
-
-class SecurityGroupsClient(service_client.ServiceClient):
-
-    def list_security_groups(self, **params):
-        """List all security groups for a user."""
-
-        url = 'os-security-groups'
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.validate_response(schema.list_security_groups, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def show_security_group(self, security_group_id):
-        """Get the details of a Security Group."""
-        url = "os-security-groups/%s" % security_group_id
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.validate_response(schema.get_security_group, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def create_security_group(self, **kwargs):
-        """Creates a new security group.
-
-        name (Required): Name of security group.
-        description (Required): Description of security group.
-        """
-        post_body = json.dumps({'security_group': kwargs})
-        resp, body = self.post('os-security-groups', post_body)
-        body = json.loads(body)
-        self.validate_response(schema.get_security_group, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def update_security_group(self, security_group_id, **kwargs):
-        """Update a security group.
-
-        security_group_id: a security_group to update
-        name: new name of security group
-        description: new description of security group
-        """
-        post_body = json.dumps({'security_group': kwargs})
-        resp, body = self.put('os-security-groups/%s' % security_group_id,
-                              post_body)
-        body = json.loads(body)
-        self.validate_response(schema.update_security_group, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_security_group(self, security_group_id):
-        """Deletes the provided Security Group."""
-        resp, body = self.delete(
-            'os-security-groups/%s' % security_group_id)
-        self.validate_response(schema.delete_security_group, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def is_resource_deleted(self, id):
-        try:
-            self.show_security_group(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 'security_group'
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
deleted file mode 100644
index 57d0434..0000000
--- a/tempest/services/compute/json/services_client.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2013 NEC Corporation
-# Copyright 2013 IBM Corp.
-# 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.api_schema.response.compute.v2_1 import services as schema
-from tempest.common import service_client
-
-
-class ServicesClient(service_client.ServiceClient):
-
-    def list_services(self, **params):
-        url = 'os-services'
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.validate_response(schema.list_services, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def enable_service(self, **kwargs):
-        """Enable service on a host
-
-        host_name: Name of host
-        binary: Service binary
-        """
-        post_body = json.dumps(kwargs)
-        resp, body = self.put('os-services/enable', post_body)
-        body = json.loads(body)
-        self.validate_response(schema.enable_disable_service, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def disable_service(self, **kwargs):
-        """Disable service on a host
-
-        host_name: Name of host
-        binary: Service binary
-        """
-        post_body = json.dumps(kwargs)
-        resp, body = self.put('os-services/disable', post_body)
-        body = json.loads(body)
-        self.validate_response(schema.enable_disable_service, resp, body)
-        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/snapshots_client.py b/tempest/services/compute/json/snapshots_client.py
deleted file mode 100644
index e3f92db..0000000
--- a/tempest/services/compute/json/snapshots_client.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2015 Fujitsu(fnst) 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 oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-from tempest_lib import exceptions as lib_exc
-
-from tempest.api_schema.response.compute.v2_1 import snapshots as schema
-from tempest.common import service_client
-
-
-class SnapshotsClient(service_client.ServiceClient):
-
-    def create_snapshot(self, volume_id, **kwargs):
-        post_body = {
-            'volume_id': volume_id
-        }
-        post_body.update(kwargs)
-        post_body = json.dumps({'snapshot': post_body})
-        resp, body = self.post('os-snapshots', post_body)
-        body = json.loads(body)
-        self.validate_response(schema.create_get_snapshot, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def show_snapshot(self, snapshot_id):
-        url = "os-snapshots/%s" % snapshot_id
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.validate_response(schema.create_get_snapshot, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_snapshots(self, detail=False, params=None):
-        url = 'os-snapshots'
-
-        if detail:
-            url += '/detail'
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.validate_response(schema.list_snapshots, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_snapshot(self, snapshot_id):
-        resp, body = self.delete("os-snapshots/%s" % snapshot_id)
-        self.validate_response(schema.delete_snapshot, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def is_resource_deleted(self, id):
-        try:
-            self.show_snapshot(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 'snapshot'
diff --git a/tempest/services/identity/v3/json/groups_client.py b/tempest/services/identity/v3/json/groups_client.py
index 5bd610d..70edd23 100644
--- a/tempest/services/identity/v3/json/groups_client.py
+++ b/tempest/services/identity/v3/json/groups_client.py
@@ -13,6 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+"""
+http://developer.openstack.org/api-ref-identity-v3.html#groups-v3
+"""
+
 from oslo_serialization import jsonutils as json
 
 from tempest.common import service_client
@@ -21,24 +25,19 @@
 class GroupsClient(service_client.ServiceClient):
     api_version = "v3"
 
-    def create_group(self, name, **kwargs):
-        """Creates a group."""
-        description = kwargs.get('description', None)
-        domain_id = kwargs.get('domain_id', 'default')
-        project_id = kwargs.get('project_id', None)
-        post_body = {
-            'description': description,
-            'domain_id': domain_id,
-            'project_id': project_id,
-            'name': name
-        }
-        post_body = json.dumps({'group': post_body})
+    def create_group(self, **kwargs):
+        """Creates a group.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#createGroup
+        """
+        post_body = json.dumps({'group': kwargs})
         resp, body = self.post('groups', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def get_group(self, group_id):
+    def show_group(self, group_id):
         """Get group details."""
         resp, body = self.get('groups/%s' % group_id)
         self.expected_success(200, resp.status)
@@ -53,15 +52,12 @@
         return service_client.ResponseBody(resp, body)
 
     def update_group(self, group_id, **kwargs):
-        """Updates a group."""
-        body = self.get_group(group_id)['group']
-        name = kwargs.get('name', body['name'])
-        description = kwargs.get('description', body['description'])
-        post_body = {
-            'name': name,
-            'description': description
-        }
-        post_body = json.dumps({'group': post_body})
+        """Updates a group.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#updateGroup
+        """
+        post_body = json.dumps({'group': kwargs})
         resp, body = self.patch('groups/%s' % group_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index cf33fb2..b0706f2 100644
--- a/tempest/tests/common/test_service_clients.py
+++ b/tempest/tests/common/test_service_clients.py
@@ -22,7 +22,6 @@
 from tempest.services.compute.json import security_group_rules_client
 from tempest.services.compute.json import server_groups_client
 from tempest.services.compute.json import servers_client
-from tempest.services.compute.json import services_client
 from tempest.services.compute.json import volumes_client \
     as compute_volumes_client
 from tempest.services.data_processing.v1_1 import data_processing_client
@@ -92,7 +91,6 @@
             security_group_rules_client.SecurityGroupRulesClient,
             server_groups_client.ServerGroupsClient,
             servers_client.ServersClient,
-            services_client.ServicesClient,
             compute_volumes_client.VolumesClient,
             data_processing_client.DataProcessingClient,
             db_flavor_client.DatabaseFlavorsClient,
diff --git a/tempest/tests/services/compute/test_security_groups_client.py b/tempest/tests/services/compute/test_security_groups_client.py
deleted file mode 100644
index 9e40b96..0000000
--- a/tempest/tests/services/compute/test_security_groups_client.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright 2015 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from oslotest import mockpatch
-from tempest_lib import exceptions as lib_exc
-from tempest_lib.tests import fake_auth_provider
-
-from tempest.services.compute.json import security_groups_client
-from tempest.tests.services.compute import base
-
-
-class TestSecurityGroupsClient(base.BaseComputeServiceTest):
-
-    FAKE_SECURITY_GROUP_INFO = [{
-        "description": "default",
-        "id": "3fb26eb3-581b-4420-9963-b0879a026506",
-        "name": "default",
-        "rules": [],
-        "tenant_id": "openstack"
-    }]
-
-    def setUp(self):
-        super(TestSecurityGroupsClient, self).setUp()
-        fake_auth = fake_auth_provider.FakeAuthProvider()
-        self.client = security_groups_client.SecurityGroupsClient(
-            fake_auth, 'compute', 'regionOne')
-
-    def _test_list_security_groups(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.list_security_groups,
-            'tempest.common.service_client.ServiceClient.get',
-            {"security_groups": self.FAKE_SECURITY_GROUP_INFO},
-            to_utf=bytes_body)
-
-    def test_list_security_groups_with_str_body(self):
-        self._test_list_security_groups()
-
-    def test_list_security_groups_with_bytes_body(self):
-        self._test_list_security_groups(bytes_body=True)
-
-    def _test_show_security_group(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.show_security_group,
-            'tempest.common.service_client.ServiceClient.get',
-            {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
-            to_utf=bytes_body,
-            security_group_id='fake-id')
-
-    def test_show_security_group_with_str_body(self):
-        self._test_show_security_group()
-
-    def test_show_security_group_with_bytes_body(self):
-        self._test_show_security_group(bytes_body=True)
-
-    def _test_create_security_group(self, bytes_body=False):
-        post_body = {"name": "test", "description": "test_group"}
-        self.check_service_client_function(
-            self.client.create_security_group,
-            'tempest.common.service_client.ServiceClient.post',
-            {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
-            to_utf=bytes_body,
-            kwargs=post_body)
-
-    def test_create_security_group_with_str_body(self):
-        self._test_create_security_group()
-
-    def test_create_security_group_with_bytes_body(self):
-        self._test_create_security_group(bytes_body=True)
-
-    def _test_update_security_group(self, bytes_body=False):
-        req_body = {"name": "test", "description": "test_group"}
-        self.check_service_client_function(
-            self.client.update_security_group,
-            'tempest.common.service_client.ServiceClient.put',
-            {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
-            to_utf=bytes_body,
-            security_group_id='fake-id',
-            kwargs=req_body)
-
-    def test_update_security_group_with_str_body(self):
-        self._test_update_security_group()
-
-    def test_update_security_group_with_bytes_body(self):
-        self._test_update_security_group(bytes_body=True)
-
-    def test_delete_security_group(self):
-        self.check_service_client_function(
-            self.client.delete_security_group,
-            'tempest.common.service_client.ServiceClient.delete',
-            {}, status=202, security_group_id='fake-id')
-
-    def test_is_resource_deleted_true(self):
-        mod = ('tempest.services.compute.json.security_groups_client.'
-               'SecurityGroupsClient.show_security_group')
-        self.useFixture(mockpatch.Patch(mod, side_effect=lib_exc.NotFound))
-        self.assertTrue(self.client.is_resource_deleted('fake-id'))
-
-    def test_is_resource_deleted_false(self):
-        mod = ('tempest.services.compute.json.security_groups_client.'
-               'SecurityGroupsClient.show_security_group')
-        self.useFixture(mockpatch.Patch(mod, return_value='success'))
-        self.assertFalse(self.client.is_resource_deleted('fake-id'))
diff --git a/tempest/tests/services/compute/test_services_client.py b/tempest/tests/services/compute/test_services_client.py
deleted file mode 100644
index fce28e8..0000000
--- a/tempest/tests/services/compute/test_services_client.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2015 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import copy
-
-from tempest_lib.tests import fake_auth_provider
-
-from tempest.services.compute.json import services_client
-from tempest.tests.services.compute import base
-
-
-class TestServicesClient(base.BaseComputeServiceTest):
-
-    FAKE_SERVICES = {
-        "services":
-        [{
-            "status": "enabled",
-            "binary": "nova-conductor",
-            "zone": "internal",
-            "state": "up",
-            "updated_at": "2015-08-19T06:50:55.000000",
-            "host": "controller",
-            "disabled_reason": None,
-            "id": 1
-        }]
-    }
-
-    FAKE_SERVICE = {
-        "service":
-        {
-            "status": "enabled",
-            "binary": "nova-conductor",
-            "host": "controller"
-        }
-    }
-
-    def setUp(self):
-        super(TestServicesClient, self).setUp()
-        fake_auth = fake_auth_provider.FakeAuthProvider()
-        self.client = services_client.ServicesClient(
-            fake_auth, 'compute', 'regionOne')
-
-    def test_list_services_with_str_body(self):
-        self.check_service_client_function(
-            self.client.list_services,
-            'tempest.common.service_client.ServiceClient.get',
-            self.FAKE_SERVICES)
-
-    def test_list_services_with_bytes_body(self):
-        self.check_service_client_function(
-            self.client.list_services,
-            'tempest.common.service_client.ServiceClient.get',
-            self.FAKE_SERVICES, to_utf=True)
-
-    def _test_enable_service(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.enable_service,
-            'tempest.common.service_client.ServiceClient.put',
-            self.FAKE_SERVICE,
-            bytes_body,
-            host_name="nova-conductor", binary="controller")
-
-    def test_enable_service_with_str_body(self):
-        self._test_enable_service()
-
-    def test_enable_service_with_bytes_body(self):
-        self._test_enable_service(bytes_body=True)
-
-    def _test_disable_service(self, bytes_body=False):
-        fake_service = copy.deepcopy(self.FAKE_SERVICE)
-        fake_service["service"]["status"] = "disable"
-
-        self.check_service_client_function(
-            self.client.disable_service,
-            'tempest.common.service_client.ServiceClient.put',
-            fake_service,
-            bytes_body,
-            host_name="nova-conductor", binary="controller")
-
-    def test_disable_service_with_str_body(self):
-        self._test_disable_service()
-
-    def test_disable_service_with_bytes_body(self):
-        self._test_disable_service(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_snapshots_client.py b/tempest/tests/services/compute/test_snapshots_client.py
deleted file mode 100644
index c24c6ae..0000000
--- a/tempest/tests/services/compute/test_snapshots_client.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright 2015 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from oslotest import mockpatch
-from tempest_lib import exceptions as lib_exc
-
-from tempest.services.compute.json import snapshots_client
-from tempest.tests import fake_auth_provider
-from tempest.tests.services.compute import base
-
-
-class TestSnapshotsClient(base.BaseComputeServiceTest):
-
-    FAKE_SNAPSHOT = {
-        "createdAt": "2015-10-02T16:27:54.724209",
-        "displayDescription": u"Another \u1234.",
-        "displayName": u"v\u1234-001",
-        "id": "100",
-        "size": 100,
-        "status": "available",
-        "volumeId": "12"
-    }
-
-    FAKE_SNAPSHOTS = {"snapshots": [FAKE_SNAPSHOT]}
-
-    def setUp(self):
-        super(TestSnapshotsClient, self).setUp()
-        fake_auth = fake_auth_provider.FakeAuthProvider()
-        self.client = snapshots_client.SnapshotsClient(
-            fake_auth, 'compute', 'regionOne')
-
-    def _test_create_snapshot(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.create_snapshot,
-            'tempest.common.service_client.ServiceClient.post',
-            {"snapshot": self.FAKE_SNAPSHOT},
-            to_utf=bytes_body, status=200,
-            volume_id=self.FAKE_SNAPSHOT["volumeId"])
-
-    def test_create_snapshot_with_str_body(self):
-        self._test_create_snapshot()
-
-    def test_create_shapshot_with_bytes_body(self):
-        self._test_create_snapshot(bytes_body=True)
-
-    def _test_show_snapshot(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.show_snapshot,
-            'tempest.common.service_client.ServiceClient.get',
-            {"snapshot": self.FAKE_SNAPSHOT},
-            to_utf=bytes_body, snapshot_id=self.FAKE_SNAPSHOT["id"])
-
-    def test_show_snapshot_with_str_body(self):
-        self._test_show_snapshot()
-
-    def test_show_snapshot_with_bytes_body(self):
-        self._test_show_snapshot(bytes_body=True)
-
-    def _test_list_snapshots(self, bytes_body=False, **params):
-        self.check_service_client_function(
-            self.client.list_snapshots,
-            'tempest.common.service_client.ServiceClient.get',
-            self.FAKE_SNAPSHOTS, to_utf=bytes_body, **params)
-
-    def test_list_snapshots_with_str_body(self):
-        self._test_list_snapshots()
-
-    def test_list_snapshots_with_byte_body(self):
-        self._test_list_snapshots(bytes_body=True)
-
-    def test_list_snapshots_with_params(self):
-        self._test_list_snapshots('fake')
-
-    def test_delete_snapshot(self):
-        self.check_service_client_function(
-            self.client.delete_snapshot,
-            'tempest.common.service_client.ServiceClient.delete',
-            {}, status=202, snapshot_id=self.FAKE_SNAPSHOT['id'])
-
-    def test_is_resource_deleted_true(self):
-        module = ('tempest.services.compute.json.snapshots_client.'
-                  'SnapshotsClient.show_snapshot')
-        self.useFixture(mockpatch.Patch(
-            module, side_effect=lib_exc.NotFound))
-        self.assertTrue(self.client.is_resource_deleted('fake-id'))
-
-    def test_is_resource_deleted_false(self):
-        module = ('tempest.services.compute.json.snapshots_client.'
-                  'SnapshotsClient.show_snapshot')
-        self.useFixture(mockpatch.Patch(
-            module, return_value={}))
-        self.assertFalse(self.client.is_resource_deleted('fake-id'))