Merge "Migrate scenario tests ssh-auth-strategy"
diff --git a/requirements.txt b/requirements.txt
index ffe6f26..17d063d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,7 +2,7 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 pbr>=1.6
-cliff>=1.14.0 # Apache-2.0
+cliff>=1.15.0 # Apache-2.0
 anyjson>=0.3.3
 httplib2>=0.7.5
 jsonschema!=2.5.0,<3.0.0,>=2.0.0
diff --git a/run_tempest.sh b/run_tempest.sh
index 0f32045..a704684 100755
--- a/run_tempest.sh
+++ b/run_tempest.sh
@@ -104,9 +104,9 @@
   fi
 
   if [ $serial -eq 1 ]; then
-      ${wrapper} testr run --subunit $testrargs | ${wrapper} subunit-2to1 | ${wrapper} tools/colorizer.py
+      ${wrapper} testr run --subunit $testrargs | ${wrapper} subunit-trace -n -f
   else
-      ${wrapper} testr run --parallel --subunit $testrargs | ${wrapper} subunit-2to1 | ${wrapper} tools/colorizer.py
+      ${wrapper} testr run --parallel --subunit $testrargs | ${wrapper} subunit-trace -n -f
   fi
 }
 
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index d5af4b4..260ea54 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,16 +37,31 @@
         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'])
 
+    @test.idempotent_id('b66eb441-b08a-4a6d-81ab-fef71baeb26c')
+    def test_group_update_with_few_fields(self):
+        name = data_utils.rand_name('Group')
+        old_description = data_utils.rand_name('Description')
+        group = self.groups_client.create_group(
+            name=name, description=old_description)['group']
+        self.addCleanup(self.groups_client.delete_group, group['id'])
+
+        new_name = data_utils.rand_name('UpdateGroup')
+        updated_group = self.groups_client.update_group(
+            group['id'], name=new_name)['group']
+        self.assertEqual(new_name, updated_group['name'])
+        # Verify that 'description' is not being updated or deleted.
+        self.assertEqual(old_description, updated_group['description'])
+
     @test.attr(type='smoke')
     @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 +92,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 +110,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/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index d68ceff..98ff64b 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -20,14 +20,14 @@
     def test_image_share_accept(self):
         image_id = self._create_image()
         member = self.os_img_client.add_image_member(image_id,
-                                                     self.alt_tenant_id)
+                                                     member=self.alt_tenant_id)
         self.assertEqual(member['member_id'], self.alt_tenant_id)
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'pending')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
         self.alt_img_client.update_image_member(image_id,
                                                 self.alt_tenant_id,
-                                                {'status': 'accepted'})
+                                                status='accepted')
         self.assertIn(image_id, self._list_image_ids_as_alt())
         body = self.os_img_client.list_image_members(image_id)
         members = body['members']
@@ -41,24 +41,24 @@
     def test_image_share_reject(self):
         image_id = self._create_image()
         member = self.os_img_client.add_image_member(image_id,
-                                                     self.alt_tenant_id)
+                                                     member=self.alt_tenant_id)
         self.assertEqual(member['member_id'], self.alt_tenant_id)
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'pending')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
         self.alt_img_client.update_image_member(image_id,
                                                 self.alt_tenant_id,
-                                                {'status': 'rejected'})
+                                                status='rejected')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
 
     @test.idempotent_id('a6ee18b9-4378-465e-9ad9-9a6de58a3287')
     def test_get_image_member(self):
         image_id = self._create_image()
         self.os_img_client.add_image_member(image_id,
-                                            self.alt_tenant_id)
+                                            member=self.alt_tenant_id)
         self.alt_img_client.update_image_member(image_id,
                                                 self.alt_tenant_id,
-                                                {'status': 'accepted'})
+                                                status='accepted')
 
         self.assertIn(image_id, self._list_image_ids_as_alt())
         member = self.os_img_client.show_image_member(image_id,
@@ -71,10 +71,10 @@
     def test_remove_image_member(self):
         image_id = self._create_image()
         self.os_img_client.add_image_member(image_id,
-                                            self.alt_tenant_id)
+                                            member=self.alt_tenant_id)
         self.alt_img_client.update_image_member(image_id,
                                                 self.alt_tenant_id,
-                                                {'status': 'accepted'})
+                                                status='accepted')
 
         self.assertIn(image_id, self._list_image_ids_as_alt())
         self.os_img_client.delete_image_member(image_id, self.alt_tenant_id)
@@ -94,14 +94,14 @@
     def test_get_private_image(self):
         image_id = self._create_image()
         member = self.os_img_client.add_image_member(image_id,
-                                                     self.alt_tenant_id)
+                                                     member=self.alt_tenant_id)
         self.assertEqual(member['member_id'], self.alt_tenant_id)
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'pending')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
         self.alt_img_client.update_image_member(image_id,
                                                 self.alt_tenant_id,
-                                                {'status': 'accepted'})
+                                                status='accepted')
         self.assertIn(image_id, self._list_image_ids_as_alt())
         self.os_img_client.delete_image_member(image_id, self.alt_tenant_id)
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
diff --git a/tempest/api/image/v2/test_images_member_negative.py b/tempest/api/image/v2/test_images_member_negative.py
index ae8913c..d5ea291 100644
--- a/tempest/api/image/v2/test_images_member_negative.py
+++ b/tempest/api/image/v2/test_images_member_negative.py
@@ -23,22 +23,22 @@
     def test_image_share_invalid_status(self):
         image_id = self._create_image()
         member = self.os_img_client.add_image_member(image_id,
-                                                     self.alt_tenant_id)
+                                                     member=self.alt_tenant_id)
         self.assertEqual(member['status'], 'pending')
         self.assertRaises(lib_exc.BadRequest,
                           self.alt_img_client.update_image_member,
                           image_id, self.alt_tenant_id,
-                          {'status': 'notavalidstatus'})
+                          status='notavalidstatus')
 
     @test.attr(type=['negative'])
     @test.idempotent_id('27002f74-109e-4a37-acd0-f91cd4597967')
     def test_image_share_owner_cannot_accept(self):
         image_id = self._create_image()
         member = self.os_img_client.add_image_member(image_id,
-                                                     self.alt_tenant_id)
+                                                     member=self.alt_tenant_id)
         self.assertEqual(member['status'], 'pending')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
         self.assertRaises(lib_exc.Forbidden,
                           self.os_img_client.update_image_member,
-                          image_id, self.alt_tenant_id, {'status': 'accepted'})
+                          image_id, self.alt_tenant_id, status='accepted')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
diff --git a/tempest/api/image/v2/test_images_metadefs_namespaces.py b/tempest/api/image/v2/test_images_metadefs_namespaces.py
index d089c84..efb7b8b 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespaces.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespaces.py
@@ -29,42 +29,42 @@
         resource_name = body['resource_types'][0]['name']
         name = [{'name': resource_name}]
         namespace_name = data_utils.rand_name('namespace')
-        # create the metadef namespaces
-        body = self.client.create_namespaces(namespace=namespace_name,
-                                             visibility='public',
-                                             description='Tempest',
-                                             display_name=namespace_name,
-                                             resource_type_associations=name,
-                                             protected=True)
+        # create the metadef namespace
+        body = self.client.create_namespace(namespace=namespace_name,
+                                            visibility='public',
+                                            description='Tempest',
+                                            display_name=namespace_name,
+                                            resource_type_associations=name,
+                                            protected=True)
         self.addCleanup(self._cleanup_namespace, namespace_name)
-        # get namespaces details
-        body = self.client.show_namespaces(namespace_name)
+        # get namespace details
+        body = self.client.show_namespace(namespace_name)
         self.assertEqual(namespace_name, body['namespace'])
         self.assertEqual('public', body['visibility'])
         # unable to delete protected namespace
-        self.assertRaises(lib_exc.Forbidden, self.client.delete_namespaces,
+        self.assertRaises(lib_exc.Forbidden, self.client.delete_namespace,
                           namespace_name)
         # update the visibility to private and protected to False
-        body = self.client.update_namespaces(namespace=namespace_name,
-                                             description='Tempest',
-                                             visibility='private',
-                                             display_name=namespace_name,
-                                             protected=False)
+        body = self.client.update_namespace(namespace=namespace_name,
+                                            description='Tempest',
+                                            visibility='private',
+                                            display_name=namespace_name,
+                                            protected=False)
         self.assertEqual('private', body['visibility'])
         self.assertEqual(False, body['protected'])
         # now able to delete the non-protected namespace
-        self.client.delete_namespaces(namespace_name)
+        self.client.delete_namespace(namespace_name)
 
     def _cleanup_namespace(self, namespace_name):
         # this is used to cleanup the resources
         try:
-            body = self.client.show_namespaces(namespace_name)
+            body = self.client.show_namespace(namespace_name)
             self.assertEqual(namespace_name, body['namespace'])
-            body = self.client.update_namespaces(namespace=namespace_name,
-                                                 description='Tempest',
-                                                 visibility='private',
-                                                 display_name=namespace_name,
-                                                 protected=False)
-            self.client.delete_namespaces(namespace_name)
+            body = self.client.update_namespace(namespace=namespace_name,
+                                                description='Tempest',
+                                                visibility='private',
+                                                display_name=namespace_name,
+                                                protected=False)
+            self.client.delete_namespace(namespace_name)
         except lib_exc.NotFound:
             pass
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/api_schema/response/compute/v2_1/tenant_networks.py b/tempest/api_schema/response/compute/v2_1/tenant_networks.py
deleted file mode 100644
index ddfab96..0000000
--- a/tempest/api_schema/response/compute/v2_1/tenant_networks.py
+++ /dev/null
@@ -1,53 +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.
-
-param_network = {
-    'type': 'object',
-    'properties': {
-        'id': {'type': 'string'},
-        'cidr': {'type': ['string', 'null']},
-        'label': {'type': 'string'}
-    },
-    'additionalProperties': False,
-    'required': ['id', 'cidr', 'label']
-}
-
-
-list_tenant_networks = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'networks': {
-                'type': 'array',
-                'items': param_network
-            }
-        },
-        'additionalProperties': False,
-        'required': ['networks']
-    }
-}
-
-
-get_tenant_network = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'network': param_network
-        },
-        'additionalProperties': False,
-        'required': ['network']
-    }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/tenant_usages.py b/tempest/api_schema/response/compute/v2_1/tenant_usages.py
deleted file mode 100644
index d51ef12..0000000
--- a/tempest/api_schema/response/compute/v2_1/tenant_usages.py
+++ /dev/null
@@ -1,92 +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.
-
-import copy
-
-_server_usages = {
-    'type': 'array',
-    'items': {
-        'type': 'object',
-        'properties': {
-            'ended_at': {
-                'oneOf': [
-                    {'type': 'string'},
-                    {'type': 'null'}
-                ]
-            },
-            'flavor': {'type': 'string'},
-            'hours': {'type': 'number'},
-            'instance_id': {'type': 'string'},
-            'local_gb': {'type': 'integer'},
-            'memory_mb': {'type': 'integer'},
-            'name': {'type': 'string'},
-            'started_at': {'type': 'string'},
-            'state': {'type': 'string'},
-            'tenant_id': {'type': 'string'},
-            'uptime': {'type': 'integer'},
-            'vcpus': {'type': 'integer'},
-        },
-        'required': ['ended_at', 'flavor', 'hours', 'instance_id', 'local_gb',
-                     'memory_mb', 'name', 'started_at', 'state', 'tenant_id',
-                     'uptime', 'vcpus']
-    }
-}
-
-_tenant_usage_list = {
-    'type': 'object',
-    'properties': {
-        'server_usages': _server_usages,
-        'start': {'type': 'string'},
-        'stop': {'type': 'string'},
-        'tenant_id': {'type': 'string'},
-        'total_hours': {'type': 'number'},
-        'total_local_gb_usage': {'type': 'number'},
-        'total_memory_mb_usage': {'type': 'number'},
-        'total_vcpus_usage': {'type': 'number'},
-    },
-    'required': ['start', 'stop', 'tenant_id',
-                 'total_hours', 'total_local_gb_usage',
-                 'total_memory_mb_usage', 'total_vcpus_usage']
-}
-
-# 'required' of get_tenant is different from list_tenant's.
-_tenant_usage_get = copy.deepcopy(_tenant_usage_list)
-_tenant_usage_get['required'] = ['server_usages', 'start', 'stop', 'tenant_id',
-                                 'total_hours', 'total_local_gb_usage',
-                                 'total_memory_mb_usage', 'total_vcpus_usage']
-
-list_tenant_usage = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'tenant_usages': {
-                'type': 'array',
-                'items': _tenant_usage_list
-            }
-        },
-        'required': ['tenant_usages']
-    }
-}
-
-get_tenant_usage = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'tenant_usage': _tenant_usage_get
-        },
-        'required': ['tenant_usage']
-    }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/versions.py b/tempest/api_schema/response/compute/v2_1/versions.py
deleted file mode 100644
index 08a9fab..0000000
--- a/tempest/api_schema/response/compute/v2_1/versions.py
+++ /dev/null
@@ -1,110 +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
-
-
-_version = {
-    'type': 'object',
-    'properties': {
-        'id': {'type': 'string'},
-        'links': {
-            'type': 'array',
-            'items': {
-                'type': 'object',
-                'properties': {
-                    'href': {'type': 'string', 'format': 'uri'},
-                    'rel': {'type': 'string'},
-                    'type': {'type': 'string'},
-                },
-                'required': ['href', 'rel'],
-                'additionalProperties': False
-            }
-        },
-        'status': {'type': 'string'},
-        'updated': {'type': 'string', 'format': 'date-time'},
-        'version': {'type': 'string'},
-        'min_version': {'type': 'string'},
-        'media-types': {
-            'type': 'array',
-            'properties': {
-                'base': {'type': 'string'},
-                'type': {'type': 'string'},
-            }
-        },
-    },
-    # NOTE: version and min_version have been added since Kilo,
-    # so they should not be required.
-    # NOTE(sdague): media-types only shows up in single version requests.
-    'required': ['id', 'links', 'status', 'updated'],
-    'additionalProperties': False
-}
-
-list_versions = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'versions': {
-                'type': 'array',
-                'items': _version
-            }
-        },
-        'required': ['versions'],
-        'additionalProperties': False
-    }
-}
-
-
-_detail_get_version = copy.deepcopy(_version)
-_detail_get_version['properties'].pop('min_version')
-_detail_get_version['properties'].pop('version')
-_detail_get_version['properties'].pop('updated')
-_detail_get_version['properties']['media-types'] = {
-    'type': 'array',
-    'items': {
-        'type': 'object',
-        'properties': {
-            'base': {'type': 'string'},
-            'type': {'type': 'string'}
-        }
-    }
-}
-_detail_get_version['required'] = ['id', 'links', 'status', 'media-types']
-
-get_version = {
-    'status_code': [300],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'choices': {
-                'type': 'array',
-                'items': _detail_get_version
-            }
-        },
-        'required': ['choices'],
-        'additionalProperties': False
-    }
-}
-
-get_one_version = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'version': _version
-        },
-        'additionalProperties': False
-    }
-}
diff --git a/tempest/clients.py b/tempest/clients.py
index 59009ac..2566d79 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -49,6 +49,14 @@
     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.compute.tenant_networks_client import \
+    TenantNetworksClient
+from tempest_lib.services.compute.tenant_usages_client import \
+    TenantUsagesClient
+from tempest_lib.services.compute.versions_client import VersionsClient
 from tempest_lib.services.identity.v2.token_client import TokenClient
 from tempest_lib.services.identity.v3.token_client import V3TokenClient
 
@@ -69,14 +77,6 @@
 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 \
-    TenantUsagesClient
-from tempest.services.compute.json.versions_client import VersionsClient
 from tempest.services.compute.json.volumes_client import \
     VolumesClient as ComputeVolumesClient
 from tempest.services.data_processing.v1_1.data_processing_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 \
@@ -117,22 +119,22 @@
 from tempest.services.telemetry.json.alarming_client import AlarmingClient
 from tempest.services.telemetry.json.telemetry_client import \
     TelemetryClient
-from tempest.services.volume.json.admin.volume_hosts_client import \
+from tempest.services.volume.v1.json.admin.volume_hosts_client import \
     VolumeHostsClient
-from tempest.services.volume.json.admin.volume_quotas_client import \
+from tempest.services.volume.v1.json.admin.volume_quotas_client import \
     VolumeQuotasClient
-from tempest.services.volume.json.admin.volume_services_client import \
+from tempest.services.volume.v1.json.admin.volume_services_client import \
     VolumesServicesClient
-from tempest.services.volume.json.admin.volume_types_client import \
+from tempest.services.volume.v1.json.admin.volume_types_client import \
     VolumeTypesClient
-from tempest.services.volume.json.availability_zone_client import \
+from tempest.services.volume.v1.json.availability_zone_client import \
     VolumeAvailabilityZoneClient
-from tempest.services.volume.json.backups_client import BackupsClient
-from tempest.services.volume.json.extensions_client import \
+from tempest.services.volume.v1.json.backups_client import BackupsClient
+from tempest.services.volume.v1.json.extensions_client import \
     ExtensionsClient as VolumeExtensionClient
-from tempest.services.volume.json.qos_client import QosSpecsClient
-from tempest.services.volume.json.snapshots_client import SnapshotsClient
-from tempest.services.volume.json.volumes_client import VolumesClient
+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
 from tempest.services.volume.v2.json.admin.volume_hosts_client import \
     VolumeHostsV2Client
 from tempest.services.volume.v2.json.admin.volume_quotas_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 184bb9a..b126ef6 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -135,7 +135,7 @@
 from tempest.services.object_storage import object_client
 from tempest.services.telemetry.json import alarming_client
 from tempest.services.telemetry.json import telemetry_client
-from tempest.services.volume.json import volumes_client
+from tempest.services.volume.v1.json import volumes_client
 
 CONF = config.CONF
 OPTS = {}
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 6fc3843..5a14fbe 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -43,7 +43,7 @@
     :param wait_until: Server status to wait for the server to reach after
     its creation.
     :param volume_backed: Whether the instance is volume backed or not.
-    :returns a tuple
+    :returns: a tuple
     """
 
     # TODO(jlanoux) add support of wait_until PINGABLE/SSHABLE
diff --git a/tempest/common/fixed_network.py b/tempest/common/fixed_network.py
index 1928a22..56cd331 100644
--- a/tempest/common/fixed_network.py
+++ b/tempest/common/fixed_network.py
@@ -83,7 +83,7 @@
            is the network to be used, and it's not visible to the tenant
     :param shared_network_name: name of the shared network to be used if no
            tenant network is available in the creds provider
-    :return a dict with 'id' and 'name' of the network
+    :returns: a dict with 'id' and 'name' of the network
     """
     caller = misc_utils.find_test_caller()
     net_creds = creds_provider.get_primary_creds()
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 10654ff..025b79f 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -95,15 +95,24 @@
         return self.exec_command(cmd)
 
     def ping_host(self, host, count=CONF.compute.ping_count,
-                  size=CONF.compute.ping_size):
+                  size=CONF.compute.ping_size, nic=None):
         addr = netaddr.IPAddress(host)
         cmd = 'ping6' if addr.version == 6 else 'ping'
+        if nic:
+            cmd = 'sudo {cmd} -I {nic}'.format(cmd=cmd, nic=nic)
         cmd += ' -c{0} -w{0} -s{1} {2}'.format(count, size, host)
         return self.exec_command(cmd)
 
-    def get_mac_address(self):
-        cmd = "ip addr | awk '/ether/ {print $2}'"
-        return self.exec_command(cmd)
+    def set_mac_address(self, nic, address):
+        self.set_nic_state(nic=nic, state="down")
+        cmd = "sudo ip link set dev {0} address {1}".format(nic, address)
+        self.exec_command(cmd)
+        self.set_nic_state(nic=nic, state="up")
+
+    def get_mac_address(self, nic=""):
+        show_nic = "show {nic} ".format(nic=nic) if nic else ""
+        cmd = "ip addr %s| awk '/ether/ {print $2}'" % show_nic
+        return self.exec_command(cmd).strip().lower()
 
     def get_nic_name(self, address):
         cmd = "ip -o addr | awk '/%s/ {print $2}'" % address
@@ -121,8 +130,8 @@
         )
         return self.exec_command(cmd)
 
-    def turn_nic_on(self, nic):
-        cmd = "sudo ip link set {nic} up".format(nic=nic)
+    def set_nic_state(self, nic, state="up"):
+        cmd = "sudo ip link set {nic} {state}".format(nic=nic, state=state)
         return self.exec_command(cmd)
 
     def get_pids(self, pr_name):
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..211a7d6 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
@@ -8,6 +7,6 @@
 ./tempest/services/object_storage/object_client.py
 ./tempest/services/telemetry/json/alarming_client.py
 ./tempest/services/telemetry/json/telemetry_client.py
-./tempest/services/volume/json/qos_client.py
-./tempest/services/volume/json/backups_client.py
+./tempest/services/volume/base/base_qos_client.py
+./tempest/services/volume/base/base_backups_client.py
 ./tempest/services/baremetal/base.py
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index c52ea15..64f9e31 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -744,8 +744,8 @@
         def cidr_in_use(cidr, tenant_id):
             """Check cidr existence
 
-            :return True if subnet with cidr already exist in tenant
-                False else
+            :returns: True if subnet with cidr already exist in tenant
+                  False else
             """
             cidr_in_use = self._list_subnets(tenant_id=tenant_id, cidr=cidr)
             return len(cidr_in_use) != 0
@@ -913,18 +913,20 @@
             self._log_net_info(e)
             raise
 
-    def _check_remote_connectivity(self, source, dest, should_succeed=True):
+    def _check_remote_connectivity(self, source, dest, should_succeed=True,
+                                   nic=None):
         """check ping server via source ssh connection
 
         :param source: RemoteClient: an ssh connection from which to ping
         :param dest: and IP to ping against
         :param should_succeed: boolean should ping succeed or not
+        :param nic: specific network interface to ping from
         :returns: boolean -- should_succeed == ping
         :returns: ping is false if ping failed
         """
         def ping_remote():
             try:
-                source.ping_host(dest)
+                source.ping_host(dest, nic=nic)
             except lib_exc.SSHExecCommandFailed:
                 LOG.warn('Failed to ping IP: %s via a ssh connection from: %s.'
                          % (dest, source.ssh_client.host))
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 57010f7..41d13fe 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -287,7 +287,7 @@
         num, new_nic = self.diff_list[0]
         ssh_client.assign_static_ip(nic=new_nic,
                                     addr=new_port.fixed_ips[0]['ip_address'])
-        ssh_client.turn_nic_on(nic=new_nic)
+        ssh_client.set_nic_state(nic=new_nic)
 
     def _get_server_nics(self, ssh_client):
         reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+):')
@@ -737,3 +737,49 @@
         self.check_public_network_connectivity(
             should_connect=True,
             msg='After router rescheduling')
+
+    @test.requires_ext(service='network', extension='port-security')
+    @test.idempotent_id('7c0bb1a2-d053-49a4-98f9-ca1a1d849f63')
+    @test.services('compute', 'network')
+    def test_port_security_macspoofing_port(self):
+        """Tests port_security extension enforces mac spoofing
+
+        1. create a new network
+        2. connect VM to new network
+        4. check VM can ping new network DHCP port
+        5. spoof mac on new new network interface
+        6. check Neutron enforces mac spoofing and blocks pings via spoofed
+            interface
+        7. disable port-security on the spoofed port
+        8. check Neutron allows pings via spoofed interface
+        """
+        spoof_mac = "00:00:00:00:00:01"
+
+        # Create server
+        self._setup_network_and_servers()
+        self.check_public_network_connectivity(should_connect=False)
+        self._create_new_network()
+        self._hotplug_server()
+        fip, server = self.floating_ip_tuple
+        new_ports = self._list_ports(device_id=server["id"],
+                                     network_id=self.new_net["id"])
+        spoof_port = new_ports[0]
+        private_key = self._get_server_key(server)
+        ssh_client = self.get_remote_client(fip.floating_ip_address,
+                                            private_key=private_key)
+        spoof_nic = ssh_client.get_nic_name(spoof_port["mac_address"])
+        dhcp_ports = self._list_ports(device_owner="network:dhcp",
+                                      network_id=self.new_net["id"])
+        new_net_dhcp = dhcp_ports[0]["fixed_ips"][0]["ip_address"]
+        self._check_remote_connectivity(ssh_client, dest=new_net_dhcp,
+                                        nic=spoof_nic, should_succeed=True)
+        ssh_client.set_mac_address(spoof_nic, spoof_mac)
+        new_mac = ssh_client.get_mac_address(nic=spoof_nic)
+        self.assertEqual(spoof_mac, new_mac)
+        self._check_remote_connectivity(ssh_client, dest=new_net_dhcp,
+                                        nic=spoof_nic, should_succeed=False)
+        self.ports_client.update_port(spoof_port["id"],
+                                      port_security_enabled=False,
+                                      security_groups=[])
+        self._check_remote_connectivity(ssh_client, dest=new_net_dhcp,
+                                        nic=spoof_nic, should_succeed=True)
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 3806943..d6ad46a 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -147,7 +147,7 @@
                                   "ports: %s")
                          % (self.network_v6, ports))
         mac6 = ports[0]
-        ssh.turn_nic_on(ssh.get_nic_name(mac6))
+        ssh.set_nic_state(ssh.get_nic_name(mac6))
 
     def _prepare_and_test(self, address6_mode, n_subnets6=1, dualnet=False):
         net_list = self.prepare_network(address6_mode=address6_mode,
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/compute/json/tenant_networks_client.py b/tempest/services/compute/json/tenant_networks_client.py
deleted file mode 100644
index 33166c0..0000000
--- a/tempest/services/compute/json/tenant_networks_client.py
+++ /dev/null
@@ -1,33 +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 oslo_serialization import jsonutils as json
-
-from tempest.api_schema.response.compute.v2_1 import tenant_networks as schema
-from tempest.common import service_client
-
-
-class TenantNetworksClient(service_client.ServiceClient):
-
-    def list_tenant_networks(self):
-        resp, body = self.get("os-tenant-networks")
-        body = json.loads(body)
-        self.validate_response(schema.list_tenant_networks, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def show_tenant_network(self, network_id):
-        resp, body = self.get("os-tenant-networks/%s" % network_id)
-        body = json.loads(body)
-        self.validate_response(schema.get_tenant_network, resp, body)
-        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
deleted file mode 100644
index 73b4706..0000000
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2013 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 oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.api_schema.response.compute.v2_1 import tenant_usages as schema
-from tempest.common import service_client
-
-
-class TenantUsagesClient(service_client.ServiceClient):
-
-    def list_tenant_usages(self, **params):
-        url = 'os-simple-tenant-usage'
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.validate_response(schema.list_tenant_usage, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def show_tenant_usage(self, tenant_id, **params):
-        url = 'os-simple-tenant-usage/%s' % tenant_id
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.validate_response(schema.get_tenant_usage, resp, body)
-        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/versions_client.py b/tempest/services/compute/json/versions_client.py
deleted file mode 100644
index 48c0e8d..0000000
--- a/tempest/services/compute/json/versions_client.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo_serialization import jsonutils as json
-from six.moves import urllib
-
-from tempest.api_schema.response.compute.v2_1 import versions as schema
-from tempest.common import service_client
-
-
-class VersionsClient(service_client.ServiceClient):
-
-    def _get_base_version_url(self):
-        # NOTE: The URL which is gotten from keystone's catalog contains
-        # API version and project-id like "v2/{project-id}", but we need
-        # to access the URL which doesn't contain them for getting API
-        # versions. For that, here should use raw_request() instead of
-        # get().
-        endpoint = self.base_url
-        url = urllib.parse.urlparse(endpoint)
-        return '%s://%s/' % (url.scheme, url.netloc)
-
-    def list_versions(self):
-        version_url = self._get_base_version_url()
-        resp, body = self.raw_request(version_url, 'GET')
-        body = json.loads(body)
-        self.validate_response(schema.list_versions, resp, body)
-        return service_client.ResponseBody(resp, body)
-
-    def get_version_by_url(self, version_url):
-        """Get the version document by url.
-
-        This gets the version document for a url, useful in testing
-        the contents of things like /v2/ or /v2.1/ in Nova. That
-        controller needs authenticated access, so we have to get
-        ourselves a token before making the request.
-
-        """
-        # we need a token for this request
-        resp, body = self.raw_request(version_url, 'GET',
-                                      {'X-Auth-Token': self.token})
-        body = json.loads(body)
-        self.validate_response(schema.get_one_version, resp, body)
-        return service_client.ResponseBody(resp, body)
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/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 492c7df..a7e0f04 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -178,17 +178,17 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def add_image_member(self, image_id, member_id):
+    def add_image_member(self, image_id, **kwargs):
         url = 'v2/images/%s/members' % image_id
-        data = json.dumps({'member': member_id})
+        data = json.dumps(kwargs)
         resp, body = self.post(url, data)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def update_image_member(self, image_id, member_id, body):
+    def update_image_member(self, image_id, member_id, **kwargs):
         url = 'v2/images/%s/members/%s' % (image_id, member_id)
-        data = json.dumps(body)
+        data = json.dumps(kwargs)
         resp, body = self.put(url, data)
         self.expected_success(200, resp.status)
         body = json.loads(body)
@@ -220,19 +220,13 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def create_namespaces(self, namespace, **kwargs):
-        params = {
-            "namespace": namespace,
-        }
+    def create_namespace(self, **kwargs):
+        """Create a namespace.
 
-        for option in kwargs:
-            value = kwargs.get(option)
-            if isinstance(value, dict) or isinstance(value, tuple):
-                params.update(value)
-            else:
-                params[option] = value
-
-        data = json.dumps(params)
+        Available params: see http://developer.openstack.org/
+                              api-ref-image-v2.html#createNamespace-v2
+        """
+        data = json.dumps(kwargs)
         self._validate_schema(data)
 
         resp, body = self.post('/v2/metadefs/namespaces', data)
@@ -240,25 +234,23 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def show_namespaces(self, namespace):
+    def show_namespace(self, namespace):
         url = '/v2/metadefs/namespaces/%s' % namespace
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def update_namespaces(self, namespace, visibility, **kwargs):
-        params = {
-            "namespace": namespace,
-            "visibility": visibility
-        }
-        for option in kwargs:
-            value = kwargs.get(option)
-            if isinstance(value, dict) or isinstance(value, tuple):
-                params.update(value)
-            else:
-                params[option] = value
+    def update_namespace(self, namespace, **kwargs):
+        """Update a namespace.
 
+        Available params: see http://developer.openstack.org/
+                              api-ref-image-v2.html#updateNamespace-v2
+        """
+        # NOTE: On Glance API, we need to pass namespace on both URI
+        # and a request body.
+        params = {'namespace': namespace}
+        params.update(kwargs)
         data = json.dumps(params)
         self._validate_schema(data)
         url = '/v2/metadefs/namespaces/%s' % namespace
@@ -267,7 +259,7 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def delete_namespaces(self, namespace):
+    def delete_namespace(self, namespace):
         url = '/v2/metadefs/namespaces/%s' % namespace
         resp, _ = self.delete(url)
         self.expected_success(204, resp.status)
diff --git a/tempest/services/volume/json/__init__.py b/tempest/services/volume/base/__init__.py
similarity index 100%
copy from tempest/services/volume/json/__init__.py
copy to tempest/services/volume/base/__init__.py
diff --git a/tempest/services/volume/json/admin/__init__.py b/tempest/services/volume/base/admin/__init__.py
similarity index 100%
copy from tempest/services/volume/json/admin/__init__.py
copy to tempest/services/volume/base/admin/__init__.py
diff --git a/tempest/services/volume/json/admin/volume_hosts_client.py b/tempest/services/volume/base/admin/base_volume_hosts_client.py
similarity index 88%
rename from tempest/services/volume/json/admin/volume_hosts_client.py
rename to tempest/services/volume/base/admin/base_volume_hosts_client.py
index 939db59..97bb007 100644
--- a/tempest/services/volume/json/admin/volume_hosts_client.py
+++ b/tempest/services/volume/base/admin/base_volume_hosts_client.py
@@ -22,7 +22,7 @@
 class BaseVolumeHostsClient(service_client.ServiceClient):
     """Client class to send CRUD Volume Hosts API requests"""
 
-    def list_hosts(self, params=None):
+    def list_hosts(self, **params):
         """Lists all hosts."""
 
         url = 'os-hosts'
@@ -33,7 +33,3 @@
         body = json.loads(body)
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, body)
-
-
-class VolumeHostsClient(BaseVolumeHostsClient):
-    """Client class to send CRUD Volume Host API V1 requests"""
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/base/admin/base_volume_quotas_client.py
similarity index 95%
rename from tempest/services/volume/json/admin/volume_quotas_client.py
rename to tempest/services/volume/base/admin/base_volume_quotas_client.py
index f6d4a14..d7909ff 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/base/admin/base_volume_quotas_client.py
@@ -74,7 +74,3 @@
         resp, body = self.delete('os-quota-sets/%s' % tenant_id)
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, body)
-
-
-class VolumeQuotasClient(BaseVolumeQuotasClient):
-    """Client class to send CRUD Volume Type API V1 requests"""
diff --git a/tempest/services/volume/json/admin/volume_services_client.py b/tempest/services/volume/base/admin/base_volume_services_client.py
similarity index 91%
rename from tempest/services/volume/json/admin/volume_services_client.py
rename to tempest/services/volume/base/admin/base_volume_services_client.py
index 798a642..1790421 100644
--- a/tempest/services/volume/json/admin/volume_services_client.py
+++ b/tempest/services/volume/base/admin/base_volume_services_client.py
@@ -30,7 +30,3 @@
         body = json.loads(body)
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, body)
-
-
-class VolumesServicesClient(BaseVolumesServicesClient):
-    """Volume V1 volume services client"""
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/base/admin/base_volume_types_client.py
similarity index 98%
rename from tempest/services/volume/json/admin/volume_types_client.py
rename to tempest/services/volume/base/admin/base_volume_types_client.py
index f2da8a5..8fcf57c 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/base/admin/base_volume_types_client.py
@@ -182,7 +182,3 @@
             "/types/%s/encryption/provider" % str(vol_type_id))
         self.expected_success(202, resp.status)
         return service_client.ResponseBody(resp, body)
-
-
-class VolumeTypesClient(BaseVolumeTypesClient):
-    """Volume V1 Volume Types client"""
diff --git a/tempest/services/volume/json/availability_zone_client.py b/tempest/services/volume/base/base_availability_zone_client.py
similarity index 89%
rename from tempest/services/volume/json/availability_zone_client.py
rename to tempest/services/volume/base/base_availability_zone_client.py
index 36f95d6..d5a2fda 100644
--- a/tempest/services/volume/json/availability_zone_client.py
+++ b/tempest/services/volume/base/base_availability_zone_client.py
@@ -25,7 +25,3 @@
         body = json.loads(body)
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, body)
-
-
-class VolumeAvailabilityZoneClient(BaseVolumeAvailabilityZoneClient):
-    """Volume V1 availability zone client."""
diff --git a/tempest/services/volume/json/backups_client.py b/tempest/services/volume/base/base_backups_client.py
similarity index 98%
rename from tempest/services/volume/json/backups_client.py
rename to tempest/services/volume/base/base_backups_client.py
index 3045992..be926e6 100644
--- a/tempest/services/volume/json/backups_client.py
+++ b/tempest/services/volume/base/base_backups_client.py
@@ -16,7 +16,6 @@
 import time
 
 from oslo_serialization import jsonutils as json
-
 from tempest_lib import exceptions as lib_exc
 
 from tempest.common import service_client
@@ -124,7 +123,3 @@
             if int(time.time()) - start_time >= self.build_timeout:
                 raise exceptions.TimeoutException
             time.sleep(self.build_interval)
-
-
-class BackupsClient(BaseBackupsClient):
-    """Volume V1 Backups client"""
diff --git a/tempest/services/volume/json/extensions_client.py b/tempest/services/volume/base/base_extensions_client.py
similarity index 91%
rename from tempest/services/volume/json/extensions_client.py
rename to tempest/services/volume/base/base_extensions_client.py
index d7d3197..afc3f6b 100644
--- a/tempest/services/volume/json/extensions_client.py
+++ b/tempest/services/volume/base/base_extensions_client.py
@@ -26,7 +26,3 @@
         body = json.loads(body)
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, body)
-
-
-class ExtensionsClient(BaseExtensionsClient):
-    """Volume V1 extensions client."""
diff --git a/tempest/services/volume/json/qos_client.py b/tempest/services/volume/base/base_qos_client.py
similarity index 98%
rename from tempest/services/volume/json/qos_client.py
rename to tempest/services/volume/base/base_qos_client.py
index c79168c..c7f6c6e 100644
--- a/tempest/services/volume/json/qos_client.py
+++ b/tempest/services/volume/base/base_qos_client.py
@@ -155,7 +155,3 @@
         resp, body = self.get(url)
         self.expected_success(202, resp.status)
         return service_client.ResponseBody(resp, body)
-
-
-class QosSpecsClient(BaseQosSpecsClient):
-    """Volume V1 QoS client."""
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/base/base_snapshots_client.py
similarity index 98%
rename from tempest/services/volume/json/snapshots_client.py
rename to tempest/services/volume/base/base_snapshots_client.py
index 77c9dd1..fac90e4 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/base/base_snapshots_client.py
@@ -196,7 +196,3 @@
         resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body)
         self.expected_success(202, resp.status)
         return service_client.ResponseBody(resp, body)
-
-
-class SnapshotsClient(BaseSnapshotsClient):
-    """Client class to send CRUD Volume V1 API requests."""
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/base/base_volumes_client.py
similarity index 98%
rename from tempest/services/volume/json/volumes_client.py
rename to tempest/services/volume/base/base_volumes_client.py
index c2a76f0..c7302e8 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/base/base_volumes_client.py
@@ -334,7 +334,3 @@
         post_body = json.dumps({'os-retype': post_body})
         resp, body = self.post('volumes/%s/action' % volume_id, post_body)
         self.expected_success(202, resp.status)
-
-
-class VolumesClient(BaseVolumesClient):
-    """Client class to send CRUD Volume V1 API requests"""
diff --git a/tempest/services/volume/json/__init__.py b/tempest/services/volume/v1/__init__.py
similarity index 100%
copy from tempest/services/volume/json/__init__.py
copy to tempest/services/volume/v1/__init__.py
diff --git a/tempest/services/volume/json/__init__.py b/tempest/services/volume/v1/json/__init__.py
similarity index 100%
rename from tempest/services/volume/json/__init__.py
rename to tempest/services/volume/v1/json/__init__.py
diff --git a/tempest/services/volume/json/admin/__init__.py b/tempest/services/volume/v1/json/admin/__init__.py
similarity index 100%
rename from tempest/services/volume/json/admin/__init__.py
rename to tempest/services/volume/v1/json/admin/__init__.py
diff --git a/tempest/services/volume/v1/json/admin/volume_hosts_client.py b/tempest/services/volume/v1/json/admin/volume_hosts_client.py
new file mode 100644
index 0000000..e564469
--- /dev/null
+++ b/tempest/services/volume/v1/json/admin/volume_hosts_client.py
@@ -0,0 +1,20 @@
+# Copyright 2013 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.services.volume.base.admin import base_volume_hosts_client
+
+
+class VolumeHostsClient(base_volume_hosts_client.BaseVolumeHostsClient):
+    """Client class to send CRUD Volume Host API V1 requests"""
diff --git a/tempest/services/volume/v1/json/admin/volume_quotas_client.py b/tempest/services/volume/v1/json/admin/volume_quotas_client.py
new file mode 100644
index 0000000..b0dde19
--- /dev/null
+++ b/tempest/services/volume/v1/json/admin/volume_quotas_client.py
@@ -0,0 +1,19 @@
+# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.services.volume.base.admin import base_volume_quotas_client
+
+
+class VolumeQuotasClient(base_volume_quotas_client.BaseVolumeQuotasClient):
+    """Client class to send CRUD Volume Type API V1 requests"""
diff --git a/tempest/services/volume/v1/json/admin/volume_services_client.py b/tempest/services/volume/v1/json/admin/volume_services_client.py
new file mode 100644
index 0000000..00810ed
--- /dev/null
+++ b/tempest/services/volume/v1/json/admin/volume_services_client.py
@@ -0,0 +1,21 @@
+# 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.
+
+from tempest.services.volume.base.admin import base_volume_services_client
+
+
+class VolumesServicesClient(
+        base_volume_services_client.BaseVolumesServicesClient):
+    """Volume V1 volume services client"""
diff --git a/tempest/services/volume/v1/json/admin/volume_types_client.py b/tempest/services/volume/v1/json/admin/volume_types_client.py
new file mode 100644
index 0000000..28524d1
--- /dev/null
+++ b/tempest/services/volume/v1/json/admin/volume_types_client.py
@@ -0,0 +1,20 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.services.volume.base.admin import base_volume_types_client
+
+
+class VolumeTypesClient(base_volume_types_client.BaseVolumeTypesClient):
+    """Volume V1 Volume Types client"""
diff --git a/tempest/services/volume/v1/json/availability_zone_client.py b/tempest/services/volume/v1/json/availability_zone_client.py
new file mode 100644
index 0000000..d8180fa
--- /dev/null
+++ b/tempest/services/volume/v1/json/availability_zone_client.py
@@ -0,0 +1,21 @@
+# 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.
+
+from tempest.services.volume.base import base_availability_zone_client
+
+
+class VolumeAvailabilityZoneClient(
+        base_availability_zone_client.BaseVolumeAvailabilityZoneClient):
+    """Volume V1 availability zone client."""
diff --git a/tempest/services/volume/v1/json/backups_client.py b/tempest/services/volume/v1/json/backups_client.py
new file mode 100644
index 0000000..ac6db6a
--- /dev/null
+++ b/tempest/services/volume/v1/json/backups_client.py
@@ -0,0 +1,20 @@
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.services.volume.base import base_backups_client
+
+
+class BackupsClient(base_backups_client.BaseBackupsClient):
+    """Volume V1 Backups client"""
diff --git a/tempest/services/volume/json/extensions_client.py b/tempest/services/volume/v1/json/extensions_client.py
similarity index 61%
copy from tempest/services/volume/json/extensions_client.py
copy to tempest/services/volume/v1/json/extensions_client.py
index d7d3197..f99d0f5 100644
--- a/tempest/services/volume/json/extensions_client.py
+++ b/tempest/services/volume/v1/json/extensions_client.py
@@ -13,20 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_serialization import jsonutils as json
-
-from tempest.common import service_client
+from tempest.services.volume.base import base_extensions_client
 
 
-class BaseExtensionsClient(service_client.ServiceClient):
-
-    def list_extensions(self):
-        url = 'extensions'
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-
-class ExtensionsClient(BaseExtensionsClient):
+class ExtensionsClient(base_extensions_client.BaseExtensionsClient):
     """Volume V1 extensions client."""
diff --git a/tempest/services/volume/v1/json/qos_client.py b/tempest/services/volume/v1/json/qos_client.py
new file mode 100644
index 0000000..b2b2195
--- /dev/null
+++ b/tempest/services/volume/v1/json/qos_client.py
@@ -0,0 +1,19 @@
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.services.volume.base import base_qos_client
+
+
+class QosSpecsClient(base_qos_client.BaseQosSpecsClient):
+    """Volume V1 QoS client."""
diff --git a/tempest/services/volume/v1/json/snapshots_client.py b/tempest/services/volume/v1/json/snapshots_client.py
new file mode 100644
index 0000000..b039c2b
--- /dev/null
+++ b/tempest/services/volume/v1/json/snapshots_client.py
@@ -0,0 +1,17 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.services.volume.base import base_snapshots_client
+
+
+class SnapshotsClient(base_snapshots_client.BaseSnapshotsClient):
+    """Client class to send CRUD Volume V1 API requests."""
diff --git a/tempest/services/volume/v1/json/volumes_client.py b/tempest/services/volume/v1/json/volumes_client.py
new file mode 100644
index 0000000..7782043
--- /dev/null
+++ b/tempest/services/volume/v1/json/volumes_client.py
@@ -0,0 +1,20 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.services.volume.base import base_volumes_client
+
+
+class VolumesClient(base_volumes_client.BaseVolumesClient):
+    """Client class to send CRUD Volume V1 API requests"""
diff --git a/tempest/services/volume/v2/json/admin/volume_hosts_client.py b/tempest/services/volume/v2/json/admin/volume_hosts_client.py
index 649c9ec..a1d8b61 100644
--- a/tempest/services/volume/v2/json/admin/volume_hosts_client.py
+++ b/tempest/services/volume/v2/json/admin/volume_hosts_client.py
@@ -13,10 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-
-from tempest.services.volume.json.admin import volume_hosts_client
+from tempest.services.volume.base.admin import base_volume_hosts_client
 
 
-class VolumeHostsV2Client(volume_hosts_client.BaseVolumeHostsClient):
+class VolumeHostsV2Client(base_volume_hosts_client.BaseVolumeHostsClient):
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
diff --git a/tempest/services/volume/v2/json/admin/volume_quotas_client.py b/tempest/services/volume/v2/json/admin/volume_quotas_client.py
index 80fffc7..a89ba2f 100644
--- a/tempest/services/volume/v2/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/v2/json/admin/volume_quotas_client.py
@@ -13,9 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.json.admin import volume_quotas_client
+from tempest.services.volume.base.admin import base_volume_quotas_client
 
 
-class VolumeQuotasV2Client(volume_quotas_client.BaseVolumeQuotasClient):
+class VolumeQuotasV2Client(base_volume_quotas_client.BaseVolumeQuotasClient):
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
diff --git a/tempest/services/volume/v2/json/admin/volume_services_client.py b/tempest/services/volume/v2/json/admin/volume_services_client.py
index 88eb82f..da7a4ea 100644
--- a/tempest/services/volume/v2/json/admin/volume_services_client.py
+++ b/tempest/services/volume/v2/json/admin/volume_services_client.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.json.admin import volume_services_client as vs_cli
+from tempest.services.volume.base.admin import base_volume_services_client
 
 
-class VolumesServicesV2Client(vs_cli.BaseVolumesServicesClient):
+class VolumesServicesV2Client(
+        base_volume_services_client.BaseVolumesServicesClient):
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
diff --git a/tempest/services/volume/v2/json/admin/volume_types_client.py b/tempest/services/volume/v2/json/admin/volume_types_client.py
index 78fe8e5..d63acf5 100644
--- a/tempest/services/volume/v2/json/admin/volume_types_client.py
+++ b/tempest/services/volume/v2/json/admin/volume_types_client.py
@@ -13,10 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-
-from tempest.services.volume.json.admin import volume_types_client
+from tempest.services.volume.base.admin import base_volume_types_client
 
 
-class VolumeTypesV2Client(volume_types_client.BaseVolumeTypesClient):
+class VolumeTypesV2Client(base_volume_types_client.BaseVolumeTypesClient):
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
diff --git a/tempest/services/volume/v2/json/availability_zone_client.py b/tempest/services/volume/v2/json/availability_zone_client.py
index 2e1ab20..a4fc9fe 100644
--- a/tempest/services/volume/v2/json/availability_zone_client.py
+++ b/tempest/services/volume/v2/json/availability_zone_client.py
@@ -13,9 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.json import availability_zone_client
+from tempest.services.volume.base import base_availability_zone_client
 
 
 class VolumeV2AvailabilityZoneClient(
-        availability_zone_client.BaseVolumeAvailabilityZoneClient):
+        base_availability_zone_client.BaseVolumeAvailabilityZoneClient):
     api_version = "v2"
diff --git a/tempest/services/volume/v2/json/backups_client.py b/tempest/services/volume/v2/json/backups_client.py
index 8e87505..15d363b 100644
--- a/tempest/services/volume/v2/json/backups_client.py
+++ b/tempest/services/volume/v2/json/backups_client.py
@@ -13,9 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.json import backups_client
+from tempest.services.volume.base import base_backups_client
 
 
-class BackupsClientV2(backups_client.BaseBackupsClient):
+class BackupsClientV2(base_backups_client.BaseBackupsClient):
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
diff --git a/tempest/services/volume/v2/json/extensions_client.py b/tempest/services/volume/v2/json/extensions_client.py
index 3e32c0c..004b232 100644
--- a/tempest/services/volume/v2/json/extensions_client.py
+++ b/tempest/services/volume/v2/json/extensions_client.py
@@ -13,8 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.json import extensions_client
+from tempest.services.volume.base import base_extensions_client
 
 
-class ExtensionsV2Client(extensions_client.BaseExtensionsClient):
+class ExtensionsV2Client(base_extensions_client.BaseExtensionsClient):
     api_version = "v2"
diff --git a/tempest/services/volume/v2/json/qos_client.py b/tempest/services/volume/v2/json/qos_client.py
index 42bd1c9..e8b680a 100644
--- a/tempest/services/volume/v2/json/qos_client.py
+++ b/tempest/services/volume/v2/json/qos_client.py
@@ -12,8 +12,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.json import qos_client
+from tempest.services.volume.base import base_qos_client
 
 
-class QosSpecsV2Client(qos_client.BaseQosSpecsClient):
+class QosSpecsV2Client(base_qos_client.BaseQosSpecsClient):
     api_version = "v2"
diff --git a/tempest/services/volume/v2/json/snapshots_client.py b/tempest/services/volume/v2/json/snapshots_client.py
index a94f9cd..28a9e98 100644
--- a/tempest/services/volume/v2/json/snapshots_client.py
+++ b/tempest/services/volume/v2/json/snapshots_client.py
@@ -10,10 +10,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.json import snapshots_client
+from tempest.services.volume.base import base_snapshots_client
 
 
-class SnapshotsV2Client(snapshots_client.BaseSnapshotsClient):
+class SnapshotsV2Client(base_snapshots_client.BaseSnapshotsClient):
     """Client class to send CRUD Volume V2 API requests."""
     api_version = "v2"
     create_resp = 202
diff --git a/tempest/services/volume/v2/json/volumes_client.py b/tempest/services/volume/v2/json/volumes_client.py
index a56a7be..51daa94 100644
--- a/tempest/services/volume/v2/json/volumes_client.py
+++ b/tempest/services/volume/v2/json/volumes_client.py
@@ -13,10 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.services.volume.json import volumes_client
+from tempest.services.volume.base import base_volumes_client
 
 
-class VolumesV2Client(volumes_client.BaseVolumesClient):
+class VolumesV2Client(base_volumes_client.BaseVolumesClient):
     """Client class to send CRUD Volume V2 API requests"""
     api_version = "v2"
     create_resp = 202
diff --git a/tempest/test.py b/tempest/test.py
index a9c8ba7..435d10a 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -495,7 +495,7 @@
         :param credential_type: string - primary, alt or admin
         :param roles: list of roles
 
-        :returns the created client manager
+        :returns: the created client manager
         :raises skipException: if the requested credentials are not available
         """
         if all([roles, credential_type]):
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index cf33fb2..272eba4 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
@@ -47,18 +46,18 @@
 from tempest.services.orchestration.json import orchestration_client
 from tempest.services.telemetry.json import alarming_client
 from tempest.services.telemetry.json import telemetry_client
-from tempest.services.volume.json.admin import volume_hosts_client
-from tempest.services.volume.json.admin import volume_quotas_client
-from tempest.services.volume.json.admin import volume_services_client
-from tempest.services.volume.json.admin import volume_types_client
-from tempest.services.volume.json import availability_zone_client \
+from tempest.services.volume.v1.json.admin import volume_hosts_client
+from tempest.services.volume.v1.json.admin import volume_quotas_client
+from tempest.services.volume.v1.json.admin import volume_services_client
+from tempest.services.volume.v1.json.admin import volume_types_client
+from tempest.services.volume.v1.json import availability_zone_client \
     as volume_az_client
-from tempest.services.volume.json import backups_client
-from tempest.services.volume.json import extensions_client \
+from tempest.services.volume.v1.json import backups_client
+from tempest.services.volume.v1.json import extensions_client \
     as volume_extensions_client
-from tempest.services.volume.json import qos_client
-from tempest.services.volume.json import snapshots_client
-from tempest.services.volume.json import volumes_client
+from tempest.services.volume.v1.json import qos_client
+from tempest.services.volume.v1.json import snapshots_client
+from tempest.services.volume.v1.json import volumes_client
 from tempest.services.volume.v2.json.admin import volume_hosts_client \
     as volume_v2_hosts_client
 from tempest.services.volume.v2.json.admin import volume_quotas_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/common/test_waiters.py b/tempest/tests/common/test_waiters.py
index 68a8295..c7cc638 100644
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -18,7 +18,7 @@
 
 from tempest.common import waiters
 from tempest import exceptions
-from tempest.services.volume.json import volumes_client
+from tempest.services.volume.base import base_volumes_client
 from tempest.tests import base
 
 
@@ -53,7 +53,7 @@
     def test_wait_for_volume_status_error_restoring(self, mock_sleep):
         # Tests that the wait method raises VolumeRestoreErrorException if
         # the volume status is 'error_restoring'.
-        client = mock.Mock(spec=volumes_client.BaseVolumesClient,
+        client = mock.Mock(spec=base_volumes_client.BaseVolumesClient,
                            build_interval=1)
         volume1 = {'volume': {'status': 'restoring-backup'}}
         volume2 = {'volume': {'status': 'error_restoring'}}
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index 3ff8e0d..e596aab 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -146,8 +146,11 @@
         self._assert_exec_called_with(
             "sudo ip addr add %s/%s dev %s" % (ip, '28', nic))
 
-    def test_turn_nic_on(self):
+    def test_set_nic_state(self):
         nic = 'eth0'
-        self.conn.turn_nic_on(nic)
+        self.conn.set_nic_state(nic)
         self._assert_exec_called_with(
             'sudo ip link set %s up' % nic)
+        self.conn.set_nic_state(nic, "down")
+        self._assert_exec_called_with(
+            'sudo ip link set %s down' % nic)
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'))
diff --git a/tempest/tests/services/compute/test_tenant_networks_client.py b/tempest/tests/services/compute/test_tenant_networks_client.py
deleted file mode 100644
index 691792a..0000000
--- a/tempest/tests/services/compute/test_tenant_networks_client.py
+++ /dev/null
@@ -1,64 +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 tempest_lib.tests import fake_auth_provider
-
-from tempest.services.compute.json import tenant_networks_client
-from tempest.tests.services.compute import base
-
-
-class TestTenantNetworksClient(base.BaseComputeServiceTest):
-
-    FAKE_NETWORK = {
-        "cidr": "None",
-        "id": "c2329eb4-cc8e-4439-ac4c-932369309e36",
-        "label": u'\u30d7'
-        }
-
-    FAKE_NETWORKS = [FAKE_NETWORK]
-
-    NETWORK_ID = FAKE_NETWORK['id']
-
-    def setUp(self):
-        super(TestTenantNetworksClient, self).setUp()
-        fake_auth = fake_auth_provider.FakeAuthProvider()
-        self.client = tenant_networks_client.TenantNetworksClient(
-            fake_auth, 'compute', 'regionOne')
-
-    def _test_list_tenant_networks(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.list_tenant_networks,
-            'tempest.common.service_client.ServiceClient.get',
-            {"networks": self.FAKE_NETWORKS},
-            bytes_body)
-
-    def test_list_tenant_networks_with_str_body(self):
-        self._test_list_tenant_networks()
-
-    def test_list_tenant_networks_with_bytes_body(self):
-        self._test_list_tenant_networks(bytes_body=True)
-
-    def _test_show_tenant_network(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.show_tenant_network,
-            'tempest.common.service_client.ServiceClient.get',
-            {"network": self.FAKE_NETWORK},
-            bytes_body,
-            network_id=self.NETWORK_ID)
-
-    def test_show_tenant_network_with_str_body(self):
-        self._test_show_tenant_network()
-
-    def test_show_tenant_network_with_bytes_body(self):
-        self._test_show_tenant_network(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_tenant_usages_client.py b/tempest/tests/services/compute/test_tenant_usages_client.py
deleted file mode 100644
index 58e0b7a..0000000
--- a/tempest/tests/services/compute/test_tenant_usages_client.py
+++ /dev/null
@@ -1,80 +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 tempest_lib.tests import fake_auth_provider
-
-from tempest.services.compute.json import tenant_usages_client
-from tempest.tests.services.compute import base
-
-
-class TestTenantUsagesClient(base.BaseComputeServiceTest):
-
-    FAKE_SERVER_USAGES = [{
-        "ended_at": None,
-        "flavor": "m1.tiny",
-        "hours": 1.0,
-        "instance_id": "1f1deceb-17b5-4c04-84c7-e0d4499c8fe0",
-        "local_gb": 1,
-        "memory_mb": 512,
-        "name": "new-server-test",
-        "started_at": "2012-10-08T20:10:44.541277",
-        "state": "active",
-        "tenant_id": "openstack",
-        "uptime": 3600,
-        "vcpus": 1
-        }]
-
-    FAKE_TENANT_USAGES = [{
-        "server_usages": FAKE_SERVER_USAGES,
-        "start": "2012-10-08T21:10:44.587336",
-        "stop": "2012-10-08T22:10:44.587336",
-        "tenant_id": "openstack",
-        "total_hours": 1,
-        "total_local_gb_usage": 1,
-        "total_memory_mb_usage": 512,
-        "total_vcpus_usage": 1
-        }]
-
-    def setUp(self):
-        super(TestTenantUsagesClient, self).setUp()
-        fake_auth = fake_auth_provider.FakeAuthProvider()
-        self.client = tenant_usages_client.TenantUsagesClient(
-            fake_auth, 'compute', 'regionOne')
-
-    def _test_list_tenant_usages(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.list_tenant_usages,
-            'tempest.common.service_client.ServiceClient.get',
-            {"tenant_usages": self.FAKE_TENANT_USAGES},
-            to_utf=bytes_body)
-
-    def test_list_tenant_usages_with_str_body(self):
-        self._test_list_tenant_usages()
-
-    def test_list_tenant_usages_with_bytes_body(self):
-        self._test_list_tenant_usages(bytes_body=True)
-
-    def _test_show_tenant_usage(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.show_tenant_usage,
-            'tempest.common.service_client.ServiceClient.get',
-            {"tenant_usage": self.FAKE_TENANT_USAGES[0]},
-            to_utf=bytes_body,
-            tenant_id='openstack')
-
-    def test_show_tenant_usage_with_str_body(self):
-        self._test_show_tenant_usage()
-
-    def test_show_tenant_usage_with_bytes_body(self):
-        self._test_show_tenant_usage(bytes_body=True)
diff --git a/tools/colorizer.py b/tools/colorizer.py
deleted file mode 100755
index 3f68a51..0000000
--- a/tools/colorizer.py
+++ /dev/null
@@ -1,328 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2013, Nebula, Inc.
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# 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.
-#
-# Colorizer Code is borrowed from Twisted:
-# Copyright (c) 2001-2010 Twisted Matrix Laboratories.
-#
-#    Permission is hereby granted, free of charge, to any person obtaining
-#    a copy of this software and associated documentation files (the
-#    "Software"), to deal in the Software without restriction, including
-#    without limitation the rights to use, copy, modify, merge, publish,
-#    distribute, sublicense, and/or sell copies of the Software, and to
-#    permit persons to whom the Software is furnished to do so, subject to
-#    the following conditions:
-#
-#    The above copyright notice and this permission notice shall be
-#    included in all copies or substantial portions of the Software.
-#
-#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-#    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-#    LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-#    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-#    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-"""Display a subunit stream through a colorized unittest test runner."""
-
-import heapq
-import sys
-import unittest
-
-import subunit
-import testtools
-
-
-class _AnsiColorizer(object):
-    """A colorizer is an object that loosely wraps around a stream
-
-    allowing callers to write text to the stream in a particular color.
-
-    Colorizer classes must implement C{supported()} and C{write(text, color)}.
-    """
-    _colors = dict(black=30, red=31, green=32, yellow=33,
-                   blue=34, magenta=35, cyan=36, white=37)
-
-    def __init__(self, stream):
-        self.stream = stream
-
-    def supported(cls, stream=sys.stdout):
-        """Check the current platform supports coloring terminal output
-
-        A class method that returns True if the current platform supports
-        coloring terminal output using this method. Returns False otherwise.
-        """
-        if not stream.isatty():
-            return False  # auto color only on TTYs
-        try:
-            import curses
-        except ImportError:
-            return False
-        else:
-            try:
-                try:
-                    return curses.tigetnum("colors") > 2
-                except curses.error:
-                    curses.setupterm()
-                    return curses.tigetnum("colors") > 2
-            except Exception:
-                # guess false in case of error
-                return False
-    supported = classmethod(supported)
-
-    def write(self, text, color):
-        """Write the given text to the stream in the given color.
-
-        @param text: Text to be written to the stream.
-
-        @param color: A string label for a color. e.g. 'red', 'white'.
-        """
-        color = self._colors[color]
-        self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text))
-
-
-class _Win32Colorizer(object):
-    """See _AnsiColorizer docstring."""
-    def __init__(self, stream):
-        import win32console
-        red, green, blue, bold = (win32console.FOREGROUND_RED,
-                                  win32console.FOREGROUND_GREEN,
-                                  win32console.FOREGROUND_BLUE,
-                                  win32console.FOREGROUND_INTENSITY)
-        self.stream = stream
-        self.screenBuffer = win32console.GetStdHandle(
-            win32console.STD_OUT_HANDLE)
-        self._colors = {'normal': red | green | blue,
-                        'red': red | bold,
-                        'green': green | bold,
-                        'blue': blue | bold,
-                        'yellow': red | green | bold,
-                        'magenta': red | blue | bold,
-                        'cyan': green | blue | bold,
-                        'white': red | green | blue | bold}
-
-    def supported(cls, stream=sys.stdout):
-        try:
-            import win32console
-            screenBuffer = win32console.GetStdHandle(
-                win32console.STD_OUT_HANDLE)
-        except ImportError:
-            return False
-        import pywintypes
-        try:
-            screenBuffer.SetConsoleTextAttribute(
-                win32console.FOREGROUND_RED |
-                win32console.FOREGROUND_GREEN |
-                win32console.FOREGROUND_BLUE)
-        except pywintypes.error:
-            return False
-        else:
-            return True
-    supported = classmethod(supported)
-
-    def write(self, text, color):
-        color = self._colors[color]
-        self.screenBuffer.SetConsoleTextAttribute(color)
-        self.stream.write(text)
-        self.screenBuffer.SetConsoleTextAttribute(self._colors['normal'])
-
-
-class _NullColorizer(object):
-    """See _AnsiColorizer docstring."""
-    def __init__(self, stream):
-        self.stream = stream
-
-    def supported(cls, stream=sys.stdout):
-        return True
-    supported = classmethod(supported)
-
-    def write(self, text, color):
-        self.stream.write(text)
-
-
-def get_elapsed_time_color(elapsed_time):
-    if elapsed_time > 1.0:
-        return 'red'
-    elif elapsed_time > 0.25:
-        return 'yellow'
-    else:
-        return 'green'
-
-
-class NovaTestResult(testtools.TestResult):
-    def __init__(self, stream, descriptions, verbosity):
-        super(NovaTestResult, self).__init__()
-        self.stream = stream
-        self.showAll = verbosity > 1
-        self.num_slow_tests = 10
-        self.slow_tests = []  # this is a fixed-sized heap
-        self.colorizer = None
-        # NOTE(vish): reset stdout for the terminal check
-        stdout = sys.stdout
-        sys.stdout = sys.__stdout__
-        for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]:
-            if colorizer.supported():
-                self.colorizer = colorizer(self.stream)
-                break
-        sys.stdout = stdout
-        self.start_time = None
-        self.last_time = {}
-        self.results = {}
-        self.last_written = None
-
-    def _writeElapsedTime(self, elapsed):
-        color = get_elapsed_time_color(elapsed)
-        self.colorizer.write("  %.2f" % elapsed, color)
-
-    def _addResult(self, test, *args):
-        try:
-            name = test.id()
-        except AttributeError:
-            name = 'Unknown.unknown'
-        test_class, test_name = name.rsplit('.', 1)
-
-        elapsed = (self._now() - self.start_time).total_seconds()
-        item = (elapsed, test_class, test_name)
-        if len(self.slow_tests) >= self.num_slow_tests:
-            heapq.heappushpop(self.slow_tests, item)
-        else:
-            heapq.heappush(self.slow_tests, item)
-
-        self.results.setdefault(test_class, [])
-        self.results[test_class].append((test_name, elapsed) + args)
-        self.last_time[test_class] = self._now()
-        self.writeTests()
-
-    def _writeResult(self, test_name, elapsed, long_result, color,
-                     short_result, success):
-        if self.showAll:
-            self.stream.write('    %s' % str(test_name).ljust(66))
-            self.colorizer.write(long_result, color)
-            if success:
-                self._writeElapsedTime(elapsed)
-            self.stream.writeln()
-        else:
-            self.colorizer.write(short_result, color)
-
-    def addSuccess(self, test):
-        super(NovaTestResult, self).addSuccess(test)
-        self._addResult(test, 'OK', 'green', '.', True)
-
-    def addFailure(self, test, err):
-        if test.id() == 'process-returncode':
-            return
-        super(NovaTestResult, self).addFailure(test, err)
-        self._addResult(test, 'FAIL', 'red', 'F', False)
-
-    def addError(self, test, err):
-        super(NovaTestResult, self).addFailure(test, err)
-        self._addResult(test, 'ERROR', 'red', 'E', False)
-
-    def addSkip(self, test, reason=None, details=None):
-        super(NovaTestResult, self).addSkip(test, reason, details)
-        self._addResult(test, 'SKIP', 'blue', 'S', True)
-
-    def startTest(self, test):
-        self.start_time = self._now()
-        super(NovaTestResult, self).startTest(test)
-
-    def writeTestCase(self, cls):
-        if not self.results.get(cls):
-            return
-        if cls != self.last_written:
-            self.colorizer.write(cls, 'white')
-            self.stream.writeln()
-        for result in self.results[cls]:
-            self._writeResult(*result)
-        del self.results[cls]
-        self.stream.flush()
-        self.last_written = cls
-
-    def writeTests(self):
-        time = self.last_time.get(self.last_written, self._now())
-        if not self.last_written or (self._now() - time).total_seconds() > 2.0:
-            diff = 3.0
-            while diff > 2.0:
-                classes = self.results.keys()
-                oldest = min(classes, key=lambda x: self.last_time[x])
-                diff = (self._now() - self.last_time[oldest]).total_seconds()
-                self.writeTestCase(oldest)
-        else:
-            self.writeTestCase(self.last_written)
-
-    def done(self):
-        self.stopTestRun()
-
-    def stopTestRun(self):
-        for cls in list(self.results.iterkeys()):
-            self.writeTestCase(cls)
-        self.stream.writeln()
-        self.writeSlowTests()
-
-    def writeSlowTests(self):
-        # Pare out 'fast' tests
-        slow_tests = [item for item in self.slow_tests
-                      if get_elapsed_time_color(item[0]) != 'green']
-        if slow_tests:
-            slow_total_time = sum(item[0] for item in slow_tests)
-            slow = ("Slowest %i tests took %.2f secs:"
-                    % (len(slow_tests), slow_total_time))
-            self.colorizer.write(slow, 'yellow')
-            self.stream.writeln()
-            last_cls = None
-            # sort by name
-            for elapsed, cls, name in sorted(slow_tests,
-                                             key=lambda x: x[1] + x[2]):
-                if cls != last_cls:
-                    self.colorizer.write(cls, 'white')
-                    self.stream.writeln()
-                last_cls = cls
-                self.stream.write('    %s' % str(name).ljust(68))
-                self._writeElapsedTime(elapsed)
-                self.stream.writeln()
-
-    def printErrors(self):
-        if self.showAll:
-            self.stream.writeln()
-        self.printErrorList('ERROR', self.errors)
-        self.printErrorList('FAIL', self.failures)
-
-    def printErrorList(self, flavor, errors):
-        for test, err in errors:
-            self.colorizer.write("=" * 70, 'red')
-            self.stream.writeln()
-            self.colorizer.write(flavor, 'red')
-            self.stream.writeln(": %s" % test.id())
-            self.colorizer.write("-" * 70, 'red')
-            self.stream.writeln()
-            self.stream.writeln("%s" % err)
-
-
-test = subunit.ProtocolTestCase(sys.stdin, passthrough=None)
-
-if sys.version_info[0:2] <= (2, 6):
-    runner = unittest.TextTestRunner(verbosity=2)
-else:
-    runner = unittest.TextTestRunner(verbosity=2, resultclass=NovaTestResult)
-
-if runner.run(test).wasSuccessful():
-    exit_code = 0
-else:
-    exit_code = 1
-sys.exit(exit_code)
diff --git a/tox.ini b/tox.ini
index 892cfed..ecd4f24 100644
--- a/tox.ini
+++ b/tox.ini
@@ -55,7 +55,7 @@
 setenv = {[tempestenv]setenv}
 deps = {[tempestenv]deps}
 # The regex below is used to select which tests to run and exclude the slow tag:
-# See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
+# See the testrepository bug: https://bugs.launchpad.net/testrepository/+bug/1208610
 commands =
   find . -type f -name "*.pyc" -delete
   bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty)) {posargs}'
@@ -65,7 +65,7 @@
 setenv = {[tempestenv]setenv}
 deps = {[tempestenv]deps}
 # The regex below is used to select which tests to run and exclude the slow tag:
-# See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
+# See the testrepository bug: https://bugs.launchpad.net/testrepository/+bug/1208610
 commands =
   find . -type f -name "*.pyc" -delete
   bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty)) {posargs}'