Merge "Add unit tests for security_groups_client"
diff --git a/HACKING.rst b/HACKING.rst
index a918f4a..e15e213 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -15,6 +15,8 @@
 - [T106] vim configuration should not be kept in source files.
 - [T107] Check that a service tag isn't in the module path
 - [T108] Check no hyphen at the end of rand_name() argument
+- [T109] Cannot use testtools.skip decorator; instead use
+         decorators.skip_because from tempest-lib
 - [N322] Method's default argument shouldn't be mutable
 
 Test Data/Configuration
diff --git a/REVIEWING.rst b/REVIEWING.rst
index 12ccb75..f7334ad 100644
--- a/REVIEWING.rst
+++ b/REVIEWING.rst
@@ -51,6 +51,19 @@
 whether to skip or not.
 
 
+Configuration Options
+---------------------
+With the introduction of the tempest external test plugin interface we needed
+to provide a stable contract for tempest's configuration options. This means
+we can no longer simply remove a configuration option when it's no longer used.
+Patches proposed that remove options without a deprecation cycle should not
+be approved. Similarly when changing default values with configuration we need
+to similarly be careful that we don't break existing functionality. Also, when
+adding options, just as before, we need to weigh the benefit of adding an
+additional option against the complexity and maintenance overhead having it
+costs.
+
+
 Test Documentation
 ------------------
 When a new test is being added refer to the :ref:`TestDocumentation` section in
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index c8ca938..e979616 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -80,5 +80,6 @@
         self.assertNotEqual(0, len(ips_list))
         for ip in netaddr.IPNetwork(self.ip_range).iter_hosts():
             self.assertIn(str(ip), map(lambda x: x['address'], ips_list))
-        body = self.client.delete_floating_ips_bulk(self.ip_range)
-        self.assertEqual(self.ip_range, body.data)
+        body = (self.client.delete_floating_ips_bulk(self.ip_range)
+                ['floating_ips_bulk_delete'])
+        self.assertEqual(self.ip_range, body)
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index ef88231..410f7b7 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -81,7 +81,7 @@
             return server_id
 
     def _volume_clean_up(self, server_id, volume_id):
-        body = self.volumes_client.show_volume(volume_id)
+        body = self.volumes_client.show_volume(volume_id)['volume']
         if body['status'] == 'in-use':
             self.servers_client.detach_volume(server_id, volume_id)
             self.volumes_client.wait_for_volume_status(volume_id, 'available')
@@ -158,7 +158,8 @@
         actual_host = self._get_host_for_server(server_id)
         target_host = self._get_host_other_than(actual_host)
 
-        volume = self.volumes_client.create_volume(display_name='test')
+        volume = self.volumes_client.create_volume(
+            display_name='test')['volume']
 
         self.volumes_client.wait_for_volume_status(volume['id'],
                                                    'available')
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 2624fca..1f53f9a 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -75,7 +75,6 @@
         cls.networks_client = cls.os.networks_client
         cls.limits_client = cls.os.limits_client
         cls.volumes_extensions_client = cls.os.volumes_extensions_client
-        cls.volumes_client = cls.os.volumes_client
         cls.interfaces_client = cls.os.interfaces_client
         cls.fixed_ips_client = cls.os.fixed_ips_client
         cls.availability_zone_client = cls.os.availability_zone_client
@@ -91,6 +90,11 @@
             cls.os.security_group_default_rules_client)
         cls.versions_client = cls.os.compute_versions_client
 
+        if CONF.volume_feature_enabled.api_v1:
+            cls.volumes_client = cls.os.volumes_client
+        else:
+            cls.volumes_client = cls.os.volumes_v2_client
+
     @classmethod
     def resource_setup(cls):
         super(BaseComputeTest, cls).resource_setup()
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index abff422..ba34039 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -75,7 +75,7 @@
 
         # Create a volume and wait for it to become ready
         self.volume = self.volumes_client.create_volume(
-            CONF.volume.volume_size, display_name='test')
+            CONF.volume.volume_size, display_name='test')['volume']
         self.addCleanup(self._delete_volume)
         self.volumes_client.wait_for_volume_status(self.volume['id'],
                                                    'available')
diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py
index d8f117e..4ba38ad 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -34,7 +34,7 @@
 
     def _cinder_verify(self, volume_id, template):
         self.assertIsNotNone(volume_id)
-        volume = self.volumes_client.show_volume(volume_id)
+        volume = self.volumes_client.show_volume(volume_id)['volume']
         self.assertEqual('available', volume.get('status'))
         self.assertEqual(template['resources']['volume']['properties'][
             'size'], volume.get('size'))
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index 71a00c9..31eff9d 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -22,13 +22,6 @@
 
 class TelemetryNotificationAPITestJSON(base.BaseTelemetryTest):
 
-    @classmethod
-    def skip_checks(cls):
-        super(TelemetryNotificationAPITestJSON, cls).skip_checks()
-        if CONF.telemetry.too_slow_to_test:
-            raise cls.skipException("Ceilometer feature for fast work mysql "
-                                    "is disabled")
-
     @test.idempotent_id('d7f8c1c8-d470-4731-8604-315d3956caad')
     @test.services('compute')
     def test_check_nova_notification(self):
@@ -75,13 +68,6 @@
 
 class TelemetryNotificationAdminAPITestJSON(base.BaseTelemetryAdminTest):
 
-    @classmethod
-    def skip_checks(cls):
-        super(TelemetryNotificationAdminAPITestJSON, cls).skip_checks()
-        if CONF.telemetry.too_slow_to_test:
-            raise cls.skipException("Ceilometer feature for fast work mysql "
-                                    "is disabled")
-
     @test.idempotent_id('29604198-8b45-4fc0-8af8-1cae4f94ebe9')
     @test.services('compute')
     @decorators.skip_because(bug='1480490')
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index bbdf4a8..4337922 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -71,7 +71,8 @@
 
         params = {self.name_field: vol_name, 'volume_type': type_name}
 
-        self.volume = self.admin_volume_client.create_volume(**params)
+        self.volume = self.admin_volume_client.create_volume(
+            **params)['volume']
         if with_prefix:
             self.volume_id_list_with_prefix.append(self.volume['id'])
         else:
@@ -135,7 +136,7 @@
         # the multi backend feature has been enabled
         # if multi-backend is enabled: os-vol-attr:host should be like:
         # host@backend_name
-        volume = self.admin_volume_client.show_volume(volume_id)
+        volume = self.admin_volume_client.show_volume(volume_id)['volume']
 
         volume1_host = volume['os-vol-host-attr:host']
         msg = ("multi-backend reporting incorrect values for volume %s" %
@@ -146,10 +147,10 @@
         # this test checks that the two 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 = 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 = 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" %
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 66973a7..784f1b6 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -34,7 +34,7 @@
         cls.name_field = cls.special_fields['name_field']
         params = {cls.name_field: vol_name}
         cls.volume = \
-            cls.volumes_client.create_volume(**params)
+            cls.volumes_client.create_volume(**params)['volume']
         cls.volumes_client.wait_for_volume_status(cls.volume['id'],
                                                   'available')
 
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 1a48204..f9117ed 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -32,14 +32,15 @@
 
     @test.idempotent_id('59eada70-403c-4cef-a2a3-a8ce2f1b07a0')
     def test_list_quotas(self):
-        quotas = self.quotas_client.show_quota_set(self.demo_tenant_id)
+        quotas = (self.quotas_client.show_quota_set(self.demo_tenant_id)
+                  ['quota_set'])
         for key in QUOTA_KEYS:
             self.assertIn(key, quotas)
 
     @test.idempotent_id('2be020a2-5fdd-423d-8d35-a7ffbc36e9f7')
     def test_list_default_quotas(self):
         quotas = self.quotas_client.show_default_quota_set(
-            self.demo_tenant_id)
+            self.demo_tenant_id)['quota_set']
         for key in QUOTA_KEYS:
             self.assertIn(key, quotas)
 
@@ -47,7 +48,7 @@
     def test_update_all_quota_resources_for_tenant(self):
         # Admin can update all the resource quota limits for a tenant
         default_quota_set = self.quotas_client.show_default_quota_set(
-            self.demo_tenant_id)
+            self.demo_tenant_id)['quota_set']
         new_quota_set = {'gigabytes': 1009,
                          'volumes': 11,
                          'snapshots': 11}
@@ -55,7 +56,7 @@
         # Update limits for all quota resources
         quota_set = self.quotas_client.update_quota_set(
             self.demo_tenant_id,
-            **new_quota_set)
+            **new_quota_set)['quota_set']
 
         cleanup_quota_set = dict(
             (k, v) for k, v in six.iteritems(default_quota_set)
@@ -70,7 +71,7 @@
     @test.idempotent_id('18c51ae9-cb03-48fc-b234-14a19374dbed')
     def test_show_quota_usage(self):
         quota_usage = self.quotas_client.show_quota_usage(
-            self.os_adm.credentials.tenant_id)
+            self.os_adm.credentials.tenant_id)['quota_set']
         for key in QUOTA_KEYS:
             self.assertIn(key, quota_usage)
             for usage_key in QUOTA_USAGE_KEYS:
@@ -79,14 +80,14 @@
     @test.idempotent_id('ae8b6091-48ad-4bfa-a188-bbf5cc02115f')
     def test_quota_usage(self):
         quota_usage = self.quotas_client.show_quota_usage(
-            self.demo_tenant_id)
+            self.demo_tenant_id)['quota_set']
 
         volume = self.create_volume()
         self.addCleanup(self.admin_volume_client.delete_volume,
                         volume['id'])
 
         new_quota_usage = self.quotas_client.show_quota_usage(
-            self.demo_tenant_id)
+            self.demo_tenant_id)['quota_set']
 
         self.assertEqual(quota_usage['volumes']['in_use'] + 1,
                          new_quota_usage['volumes']['in_use'])
@@ -104,14 +105,15 @@
         tenant_id = tenant['id']
         self.addCleanup(identity_client.delete_tenant, tenant_id)
         quota_set_default = self.quotas_client.show_default_quota_set(
-            tenant_id)
+            tenant_id)['quota_set']
         volume_default = quota_set_default['volumes']
 
         self.quotas_client.update_quota_set(tenant_id,
                                             volumes=(int(volume_default) + 5))
 
         self.quotas_client.delete_quota_set(tenant_id)
-        quota_set_new = self.quotas_client.show_quota_set(tenant_id)
+        quota_set_new = (self.quotas_client.show_quota_set(tenant_id)
+                         ['quota_set'])
         self.assertEqual(volume_default, quota_set_new['volumes'])
 
 
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index dd69b7f..2d9019a 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -58,7 +58,7 @@
                   'volume_type': volume_types[0]['id']}
 
         # Create volume
-        volume = self.volumes_client.create_volume(**params)
+        volume = self.volumes_client.create_volume(**params)['volume']
         self.addCleanup(self._delete_volume, volume['id'])
         self.assertEqual(volume_types[0]['name'], volume["volume_type"])
         self.assertEqual(volume[self.name_field], vol_name,
@@ -74,7 +74,8 @@
         self.volumes_client.wait_for_volume_status(volume['id'], 'available')
 
         # Get volume details and Verify
-        fetched_volume = self.volumes_client.show_volume(volume['id'])
+        fetched_volume = self.volumes_client.show_volume(
+            volume['id'])['volume']
         self.assertEqual(volume_types[1]['name'],
                          fetched_volume['volume_type'],
                          'The fetched Volume type is different '
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 4288d58..6c32321 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -34,7 +34,7 @@
         cls.name_field = cls.special_fields['name_field']
         params = {cls.name_field: vol_name}
 
-        cls.volume = cls.client.create_volume(**params)
+        cls.volume = cls.client.create_volume(**params)['volume']
         cls.client.wait_for_volume_status(cls.volume['id'], 'available')
 
     @classmethod
@@ -60,7 +60,7 @@
         # Create a temp volume for force delete tests
         vol_name = utils.rand_name('Volume')
         params = {self.name_field: vol_name}
-        temp_volume = self.client.create_volume(**params)
+        temp_volume = self.client.create_volume(**params)['volume']
         self.client.wait_for_volume_status(temp_volume['id'], 'available')
 
         return temp_volume
@@ -78,7 +78,7 @@
         # test volume reset status : available->error->available
         self._reset_volume_status(self.volume['id'], 'error')
         volume_get = self.admin_volume_client.show_volume(
-            self.volume['id'])
+            self.volume['id'])['volume']
         self.assertEqual('error', volume_get['status'])
 
     @test.idempotent_id('21737d5a-92f2-46d7-b009-a0cc0ee7a570')
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index 9b206a6..0399413 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -125,7 +125,7 @@
                                                         'available')
 
         # Verify if restored volume is there in volume list
-        volumes = self.admin_volume_client.list_volumes()
+        volumes = self.admin_volume_client.list_volumes()['volumes']
         self.assertIn(restore['volume_id'], [v['id'] for v in volumes])
         self.backups_adm_client.wait_for_backup_status(import_backup['id'],
                                                        'available')
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index c987100..cc020e3 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -16,7 +16,7 @@
 from oslo_log import log as logging
 from tempest_lib import exceptions as lib_exc
 
-from tempest.common import fixed_network
+from tempest.common import compute
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -113,7 +113,7 @@
         name_field = cls.special_fields['name_field']
 
         kwargs[name_field] = name
-        volume = cls.volumes_client.create_volume(size, **kwargs)
+        volume = cls.volumes_client.create_volume(size, **kwargs)['volume']
 
         cls.volumes.append(volume)
         cls.volumes_client.wait_for_volume_status(volume['id'], 'available')
@@ -162,12 +162,13 @@
 
     @classmethod
     def create_server(cls, name, **kwargs):
-        network = cls.get_tenant_network()
-        network_kwargs = fixed_network.set_networks_kwarg(network, kwargs)
-        return cls.servers_client.create_server(name,
-                                                cls.image_ref,
-                                                cls.flavor_ref,
-                                                **network_kwargs)
+        tenant_network = cls.get_tenant_network()
+        body, _ = compute.create_test_server(
+            cls.os,
+            tenant_network=tenant_network,
+            name=name,
+            **kwargs)
+        return body
 
 
 class BaseVolumeAdminTest(BaseVolumeTest):
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index 8529cfc..e529538 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -42,14 +42,16 @@
                     "key4": "<value&special_chars>"}
 
         body = self.volumes_client.create_volume_metadata(self.volume_id,
-                                                          metadata)
+                                                          metadata)['metadata']
         # Get the metadata of the volume
-        body = self.volumes_client.show_volume_metadata(self.volume_id)
+        body = self.volumes_client.show_volume_metadata(
+            self.volume_id)['metadata']
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Delete one item metadata of the volume
         self.volumes_client.delete_volume_metadata_item(
             self.volume_id, "key1")
-        body = self.volumes_client.show_volume_metadata(self.volume_id)
+        body = self.volumes_client.show_volume_metadata(
+            self.volume_id)['metadata']
         self.assertNotIn("key1", body)
         del metadata["key1"]
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
@@ -66,15 +68,17 @@
 
         # Create metadata for the volume
         body = self.volumes_client.create_volume_metadata(
-            self.volume_id, metadata)
+            self.volume_id, metadata)['metadata']
         # Get the metadata of the volume
-        body = self.volumes_client.show_volume_metadata(self.volume_id)
+        body = self.volumes_client.show_volume_metadata(
+            self.volume_id)['metadata']
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Update metadata
         body = self.volumes_client.update_volume_metadata(
-            self.volume_id, update)
+            self.volume_id, update)['metadata']
         # Get the metadata of the volume
-        body = self.volumes_client.show_volume_metadata(self.volume_id)
+        body = self.volumes_client.show_volume_metadata(
+            self.volume_id)['metadata']
         self.assertEqual(update, body)
 
     @test.idempotent_id('862261c5-8df4-475a-8c21-946e50e36a20')
@@ -89,13 +93,14 @@
                   "key3": "value3_update"}
         # Create metadata for the volume
         body = self.volumes_client.create_volume_metadata(
-            self.volume_id, metadata)
+            self.volume_id, metadata)['metadata']
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Update metadata item
         body = self.volumes_client.update_volume_metadata_item(
-            self.volume_id, "key3", update_item)
+            self.volume_id, "key3", update_item)['meta']
         # Get the metadata of the volume
-        body = self.volumes_client.show_volume_metadata(self.volume_id)
+        body = self.volumes_client.show_volume_metadata(
+            self.volume_id)['metadata']
         self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
 
 
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 27f8112..c0b6b7e 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -47,24 +47,24 @@
         self.addCleanup(self._delete_volume, volume['id'])
 
         # Create a volume transfer
-        transfer = self.client.create_volume_transfer(volume['id'])
+        transfer = self.client.create_volume_transfer(volume['id'])['transfer']
         transfer_id = transfer['id']
         auth_key = transfer['auth_key']
         self.client.wait_for_volume_status(volume['id'],
                                            'awaiting-transfer')
 
         # Get a volume transfer
-        body = self.client.show_volume_transfer(transfer_id)
+        body = self.client.show_volume_transfer(transfer_id)['transfer']
         self.assertEqual(volume['id'], body['volume_id'])
 
         # List volume transfers, the result should be greater than
         # or equal to 1
-        body = self.client.list_volume_transfers()
+        body = self.client.list_volume_transfers()['transfers']
         self.assertThat(len(body), matchers.GreaterThan(0))
 
         # Accept a volume transfer by alt_tenant
         body = self.alt_client.accept_volume_transfer(transfer_id,
-                                                      auth_key)
+                                                      auth_key)['transfer']
         self.alt_client.wait_for_volume_status(volume['id'], 'available')
 
     @test.idempotent_id('ab526943-b725-4c07-b875-8e8ef87a2c30')
@@ -74,13 +74,13 @@
         self.addCleanup(self._delete_volume, volume['id'])
 
         # Create a volume transfer
-        body = self.client.create_volume_transfer(volume['id'])
+        body = self.client.create_volume_transfer(volume['id'])['transfer']
         transfer_id = body['id']
         self.client.wait_for_volume_status(volume['id'],
                                            'awaiting-transfer')
 
         # List all volume transfers (looking for the one we created)
-        body = self.client.list_volume_transfers()
+        body = self.client.list_volume_transfers()['transfers']
         for transfer in body:
             if volume['id'] == transfer['volume_id']:
                 break
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 79615b3..d4636ee 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -37,9 +37,9 @@
 
         # Create a test shared instance
         srv_name = data_utils.rand_name(cls.__name__ + '-Instance')
-        cls.server = cls.create_server(srv_name)
-        waiters.wait_for_server_status(cls.servers_client, cls.server['id'],
-                                       'ACTIVE')
+        cls.server = cls.create_server(
+            name=srv_name,
+            wait_until='ACTIVE')
 
         # Create a test shared volume for attach/detach tests
         cls.volume = cls.create_volume()
@@ -75,7 +75,8 @@
         # Verify that a volume bootable flag is retrieved
         for bool_bootable in [True, False]:
             self.client.set_bootable_volume(self.volume['id'], bool_bootable)
-            fetched_volume = self.client.show_volume(self.volume['id'])
+            fetched_volume = self.client.show_volume(
+                self.volume['id'])['volume']
             # Get Volume information
             bool_flag = self._is_true(fetched_volume['bootable'])
             self.assertEqual(bool_bootable, bool_flag)
@@ -96,7 +97,7 @@
                         self.volume['id'],
                         'available')
         self.addCleanup(self.client.detach_volume, self.volume['id'])
-        volume = self.client.show_volume(self.volume['id'])
+        volume = self.client.show_volume(self.volume['id'])['volume']
         self.assertIn('attachments', volume)
         attachment = self.client.get_attachment_from_volume(volume)
         self.assertEqual(mountpoint, attachment['device'])
@@ -112,9 +113,9 @@
         # there is no way to delete it from Cinder, so we delete it from Glance
         # using the Glance image_client and from Cinder via tearDownClass.
         image_name = data_utils.rand_name('Image')
-        body = self.client.upload_volume(self.volume['id'],
-                                         image_name,
-                                         CONF.volume.disk_format)
+        body = self.client.upload_volume(
+            self.volume['id'], image_name,
+            CONF.volume.disk_format)['os-volume_upload_image']
         image_id = body["image_id"]
         self.addCleanup(self.image_client.delete_image, image_id)
         self.image_client.wait_for_image_status(image_id, 'active')
@@ -125,12 +126,12 @@
         # Mark volume as reserved.
         body = self.client.reserve_volume(self.volume['id'])
         # To get the volume info
-        body = self.client.show_volume(self.volume['id'])
+        body = self.client.show_volume(self.volume['id'])['volume']
         self.assertIn('attaching', body['status'])
         # Unmark volume as reserved.
         body = self.client.unreserve_volume(self.volume['id'])
         # To get the volume info
-        body = self.client.show_volume(self.volume['id'])
+        body = self.client.show_volume(self.volume['id'])['volume']
         self.assertIn('available', body['status'])
 
     def _is_true(self, val):
@@ -143,7 +144,7 @@
         self.client.update_volume_readonly(self.volume['id'],
                                            readonly)
         # Get Volume information
-        fetched_volume = self.client.show_volume(self.volume['id'])
+        fetched_volume = self.client.show_volume(self.volume['id'])['volume']
         bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
         self.assertEqual(True, bool_flag)
 
@@ -152,7 +153,7 @@
         self.client.update_volume_readonly(self.volume['id'], readonly)
 
         # Get Volume information
-        fetched_volume = self.client.show_volume(self.volume['id'])
+        fetched_volume = self.client.show_volume(self.volume['id'])['volume']
         bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
         self.assertEqual(False, bool_flag)
 
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index 179f8d3..78f5571 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -34,7 +34,7 @@
         extend_size = int(self.volume['size']) + 1
         self.client.extend_volume(self.volume['id'], extend_size)
         self.client.wait_for_volume_status(self.volume['id'], 'available')
-        volume = self.client.show_volume(self.volume['id'])
+        volume = self.client.show_volume(self.volume['id'])['volume']
         self.assertEqual(int(volume['size']), extend_size)
 
 
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index db156f0..35c8898 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -50,7 +50,7 @@
         # Create a volume
         kwargs[self.name_field] = v_name
         kwargs['metadata'] = metadata
-        volume = self.client.create_volume(**kwargs)
+        volume = self.client.create_volume(**kwargs)['volume']
         self.assertIn('id', volume)
         self.addCleanup(self._delete_volume, volume['id'])
         self.client.wait_for_volume_status(volume['id'], 'available')
@@ -61,7 +61,7 @@
         self.assertTrue(volume['id'] is not None,
                         "Field volume id is empty or not found.")
         # Get Volume information
-        fetched_volume = self.client.show_volume(volume['id'])
+        fetched_volume = self.client.show_volume(volume['id'])['volume']
         self.assertEqual(v_name,
                          fetched_volume[self.name_field],
                          'The fetched Volume name is different '
@@ -89,12 +89,13 @@
         new_desc = 'This is the new description of volume'
         params = {self.name_field: new_v_name,
                   self.descrip_field: new_desc}
-        update_volume = self.client.update_volume(volume['id'], **params)
+        update_volume = self.client.update_volume(
+            volume['id'], **params)['volume']
         # Assert response body for update_volume method
         self.assertEqual(new_v_name, update_volume[self.name_field])
         self.assertEqual(new_desc, update_volume[self.descrip_field])
         # Assert response body for show_volume method
-        updated_volume = self.client.show_volume(volume['id'])
+        updated_volume = self.client.show_volume(volume['id'])['volume']
         self.assertEqual(volume['id'], updated_volume['id'])
         self.assertEqual(new_v_name, updated_volume[self.name_field])
         self.assertEqual(new_desc, updated_volume[self.descrip_field])
@@ -109,7 +110,7 @@
         new_v_desc = data_utils.rand_name('@#$%^* description')
         params = {self.descrip_field: new_v_desc,
                   'availability_zone': volume['availability_zone']}
-        new_volume = self.client.create_volume(**params)
+        new_volume = self.client.create_volume(**params)['volume']
         self.assertIn('id', new_volume)
         self.addCleanup(self._delete_volume, new_volume['id'])
         self.client.wait_for_volume_status(new_volume['id'], 'available')
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 3847877..620366a 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -70,7 +70,7 @@
         cls.metadata = {'Type': 'work'}
         for i in range(3):
             volume = cls.create_volume(metadata=cls.metadata)
-            volume = cls.client.show_volume(volume['id'])
+            volume = cls.client.show_volume(volume['id'])['volume']
             cls.volume_list.append(volume)
             cls.volume_id_list.append(volume['id'])
 
@@ -89,9 +89,10 @@
         """
         if with_detail:
             fetched_vol_list = \
-                self.client.list_volumes(detail=True, params=params)
+                self.client.list_volumes(detail=True, params=params)['volumes']
         else:
-            fetched_vol_list = self.client.list_volumes(params=params)
+            fetched_vol_list = self.client.list_volumes(
+                params=params)['volumes']
 
         # Validating params of fetched volumes
         # In v2, only list detail view includes items in params.
@@ -116,7 +117,7 @@
     def test_volume_list(self):
         # Get a list of Volumes
         # Fetch all volumes
-        fetched_list = self.client.list_volumes()
+        fetched_list = self.client.list_volumes()['volumes']
         self.assertVolumesIn(fetched_list, self.volume_list,
                              fields=self.VOLUME_FIELDS)
 
@@ -124,14 +125,14 @@
     def test_volume_list_with_details(self):
         # Get a list of Volumes with details
         # Fetch all Volumes
-        fetched_list = self.client.list_volumes(detail=True)
+        fetched_list = self.client.list_volumes(detail=True)['volumes']
         self.assertVolumesIn(fetched_list, self.volume_list)
 
     @test.idempotent_id('a28e8da4-0b56-472f-87a8-0f4d3f819c02')
     def test_volume_list_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {self.name: volume[self.name]}
-        fetched_vol = self.client.list_volumes(params=params)
+        fetched_vol = self.client.list_volumes(params=params)['volumes']
         self.assertEqual(1, len(fetched_vol), str(fetched_vol))
         self.assertEqual(fetched_vol[0][self.name],
                          volume[self.name])
@@ -140,7 +141,8 @@
     def test_volume_list_details_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {self.name: volume[self.name]}
-        fetched_vol = self.client.list_volumes(detail=True, params=params)
+        fetched_vol = self.client.list_volumes(
+            detail=True, params=params)['volumes']
         self.assertEqual(1, len(fetched_vol), str(fetched_vol))
         self.assertEqual(fetched_vol[0][self.name],
                          volume[self.name])
@@ -148,7 +150,7 @@
     @test.idempotent_id('39654e13-734c-4dab-95ce-7613bf8407ce')
     def test_volumes_list_by_status(self):
         params = {'status': 'available'}
-        fetched_list = self.client.list_volumes(params=params)
+        fetched_list = self.client.list_volumes(params=params)['volumes']
         self._list_by_param_value_and_assert(params)
         self.assertVolumesIn(fetched_list, self.volume_list,
                              fields=self.VOLUME_FIELDS)
@@ -156,7 +158,8 @@
     @test.idempotent_id('2943f712-71ec-482a-bf49-d5ca06216b9f')
     def test_volumes_list_details_by_status(self):
         params = {'status': 'available'}
-        fetched_list = self.client.list_volumes(detail=True, params=params)
+        fetched_list = self.client.list_volumes(
+            detail=True, params=params)['volumes']
         for volume in fetched_list:
             self.assertEqual('available', volume['status'])
         self.assertVolumesIn(fetched_list, self.volume_list)
@@ -166,7 +169,7 @@
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
-        fetched_list = self.client.list_volumes(params=params)
+        fetched_list = self.client.list_volumes(params=params)['volumes']
         self._list_by_param_value_and_assert(params)
         self.assertVolumesIn(fetched_list, self.volume_list,
                              fields=self.VOLUME_FIELDS)
@@ -176,7 +179,8 @@
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
-        fetched_list = self.client.list_volumes(detail=True, params=params)
+        fetched_list = self.client.list_volumes(
+            detail=True, params=params)['volumes']
         for volume in fetched_list:
             self.assertEqual(zone, volume['availability_zone'])
         self.assertVolumesIn(fetched_list, self.volume_list)
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 48f40f0..0af40ea 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -180,12 +180,13 @@
     @test.services('compute')
     def test_attach_volumes_with_nonexistent_volume_id(self):
         srv_name = data_utils.rand_name('Instance')
-        server = self.create_server(srv_name)
+        server = self.create_server(
+            name=srv_name,
+            wait_until='ACTIVE')
         self.addCleanup(waiters.wait_for_server_termination,
                         self.servers_client, server['id'])
         self.addCleanup(self.servers_client.delete_server, server['id'])
-        waiters.wait_for_server_status(self.servers_client, server['id'],
-                                       'ACTIVE')
+
         self.assertRaises(lib_exc.NotFound,
                           self.client.attach_volume,
                           str(uuid.uuid4()),
@@ -270,7 +271,7 @@
     def test_list_volumes_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume')
         params = {self.name_field: v_name}
-        fetched_volume = self.client.list_volumes(params=params)
+        fetched_volume = self.client.list_volumes(params=params)['volumes']
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative'])
@@ -279,14 +280,14 @@
         v_name = data_utils.rand_name('Volume')
         params = {self.name_field: v_name}
         fetched_volume = \
-            self.client.list_volumes(detail=True, params=params)
+            self.client.list_volumes(detail=True, params=params)['volumes']
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative'])
     @test.idempotent_id('143b279b-7522-466b-81be-34a87d564a7c')
     def test_list_volumes_with_invalid_status(self):
         params = {'status': 'null'}
-        fetched_volume = self.client.list_volumes(params=params)
+        fetched_volume = self.client.list_volumes(params=params)['volumes']
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative'])
@@ -294,7 +295,7 @@
     def test_list_volumes_detail_with_invalid_status(self):
         params = {'status': 'null'}
         fetched_volume = \
-            self.client.list_volumes(detail=True, params=params)
+            self.client.list_volumes(detail=True, params=params)['volumes']
         self.assertEqual(0, len(fetched_volume))
 
 
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 058e220..7eaa9cc 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -14,7 +14,6 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest.common import waiters
 from tempest import config
 from tempest import test
 
@@ -68,10 +67,10 @@
         # Create a snapshot when volume status is in-use
         # Create a test instance
         server_name = data_utils.rand_name('instance')
-        server = self.create_server(server_name)
+        server = self.create_server(
+            name=server_name,
+            wait_until='ACTIVE')
         self.addCleanup(self.servers_client.delete_server, server['id'])
-        waiters.wait_for_server_status(self.servers_client, server['id'],
-                                       'ACTIVE')
         mountpoint = '/dev/%s' % CONF.compute.volume_device_name
         self.servers_client.attach_volume(
             server['id'], volumeId=self.volume_origin['id'],
@@ -178,7 +177,7 @@
         snapshot = self.create_snapshot(self.volume_origin['id'])
         # NOTE(gfidente): size is required also when passing snapshot_id
         volume = self.volumes_client.create_volume(
-            snapshot_id=snapshot['id'])
+            snapshot_id=snapshot['id'])['volume']
         self.volumes_client.wait_for_volume_status(volume['id'], 'available')
         self.volumes_client.delete_volume(volume['id'])
         self.volumes_client.wait_for_resource_deletion(volume['id'])
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index ddc6822..94a9d16 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -47,7 +47,7 @@
         cls.metadata = {'Type': 'work'}
         for i in range(3):
             volume = cls.create_volume(metadata=cls.metadata)
-            volume = cls.client.show_volume(volume['id'])
+            volume = cls.client.show_volume(volume['id'])['volume']
             cls.volume_list.append(volume)
             cls.volume_id_list.append(volume['id'])
 
@@ -71,8 +71,8 @@
                       'sort_dir': sort_dir,
                       'sort_key': sort_key
                       }
-            fetched_volume = self.client.list_volumes(detail=True,
-                                                      params=params)
+            fetched_volume = self.client.list_volumes(
+                detail=True, params=params)['volumes']
             self.assertEqual(limit, len(fetched_volume),
                              "The count of volumes is %s, expected:%s " %
                              (len(fetched_volume), limit))
@@ -123,7 +123,7 @@
 
         while True:
             # Get a list page
-            response = method(return_body=True, params=params, **kwargs)
+            response = method(params=params, **kwargs)
 
             # If we have to check ids
             if remaining is not None:
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 07d1d75..6d4e3a9 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -322,7 +322,7 @@
 
     def list(self):
         client = self.client
-        vols = client.list_volumes()
+        vols = client.list_volumes()['volumes']
         LOG.debug("List count, %s Volumes" % len(vols))
         return vols
 
@@ -353,7 +353,7 @@
             LOG.exception("Delete Volume Quotas exception.")
 
     def dry_run(self):
-        quotas = self.client.show_quota_usage(self.tenant_id)
+        quotas = self.client.show_quota_usage(self.tenant_id)['quota_set']
         self.data['volume_quotas'] = quotas
 
 
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 7f896d1..6973c87 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -945,7 +945,7 @@
 #######################
 
 def _get_volume_by_name(client, name):
-    body = client.volumes.list_volumes()
+    body = client.volumes.list_volumes()['volumes']
     for volume in body:
         if name == volume['display_name']:
             return volume
@@ -967,7 +967,7 @@
         size = volume['gb']
         v_name = volume['name']
         body = client.volumes.create_volume(size=size,
-                                            display_name=v_name)
+                                            display_name=v_name)['volume']
         client.volumes.wait_for_volume_status(body['id'], 'available')
 
 
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 9e7d894..6d53b59 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -144,6 +144,12 @@
         'neutron': os.network_client,
         'swift': os.account_client,
     }
+    # NOTE (e0ne): Use Cinder API v2 by default because v1 is deprecated
+    if CONF.volume_feature_enabled.api_v2:
+        extensions_client['cinder'] = os.volumes_v2_extension_client
+    else:
+        extensions_client['cinder'] = os.volumes_extension_client
+
     if service not in extensions_client:
         print('No tempest extensions client for %s' % service)
         exit(1)
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 803ad6c..b0afcc1 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -163,12 +163,19 @@
 def wait_for_volume_status(client, volume_id, status):
     """Waits for a Volume to reach a given status."""
     body = client.show_volume(volume_id)
+    if 'volume' in body:
+        body = body['volume']
     volume_status = body['status']
     start = int(time.time())
 
     while volume_status != status:
         time.sleep(client.build_interval)
         body = client.show_volume(volume_id)
+        # TODO(jswarren) always extract 'volume' value
+        # once the compute clients also return the full
+        # response.
+        if 'volume' in body:
+            body = body['volume']
         volume_status = body['status']
         if volume_status == 'error':
             raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
diff --git a/tempest/config.py b/tempest/config.py
index b6daa2e..5721c27 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -860,6 +860,7 @@
                help="The endpoint type to use for the telemetry service."),
     cfg.BoolOpt('too_slow_to_test',
                 default=True,
+                deprecated_for_removal=True,
                 help="This variable is used as flag to enable "
                      "notification tests")
 ]
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index db6375f..06ca09b 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -29,6 +29,7 @@
 VI_HEADER_RE = re.compile(r"^#\s+vim?:.+")
 RAND_NAME_HYPHEN_RE = re.compile(r".*rand_name\(.+[\-\_][\"\']\)")
 mutable_default_args = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
+TESTTOOLS_SKIP_DECORATOR = re.compile(r'\s*@testtools\.skip\((.*)\)')
 
 
 def import_no_clients_in_api_and_scenario_tests(physical_line, filename):
@@ -132,6 +133,16 @@
         yield (0, msg)
 
 
+def no_testtools_skip_decorator(logical_line):
+    """Check that methods do not have the testtools.skip decorator
+
+    T109
+    """
+    if TESTTOOLS_SKIP_DECORATOR.match(logical_line):
+        yield (0, "T109: Cannot use testtools.skip decorator; instead use "
+               "decorators.skip_because from tempest-lib")
+
+
 def factory(register):
     register(import_no_clients_in_api_and_scenario_tests)
     register(scenario_tests_need_service_tags)
@@ -140,3 +151,4 @@
     register(service_tags_not_in_module_path)
     register(no_hyphen_at_end_of_rand_name)
     register(no_mutable_default_args)
+    register(no_testtools_skip_decorator)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index a406aa3..4f113d3 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -58,14 +58,19 @@
         cls.security_group_rules_client = (
             cls.manager.security_group_rules_client)
         cls.servers_client = cls.manager.servers_client
-        cls.volumes_client = cls.manager.volumes_client
-        cls.snapshots_client = cls.manager.snapshots_client
         cls.interface_client = cls.manager.interfaces_client
         # Neutron network client
         cls.network_client = cls.manager.network_client
         # Heat client
         cls.orchestration_client = cls.manager.orchestration_client
 
+        if CONF.volume_feature_enabled.api_v1:
+            cls.volumes_client = cls.manager.volumes_client
+            cls.snapshots_client = cls.manager.snapshots_client
+        else:
+            cls.volumes_client = cls.manager.volumes_v2_client
+            cls.snapshots_client = cls.manager.snapshots_v2_client
+
     # ## Methods to handle sync and async deletes
 
     def setUp(self):
@@ -202,7 +207,7 @@
             name = data_utils.rand_name(self.__class__.__name__)
         volume = self.volumes_client.create_volume(
             size=size, display_name=name, snapshot_id=snapshot_id,
-            imageRef=imageRef, volume_type=volume_type)
+            imageRef=imageRef, volume_type=volume_type)['volume']
 
         if wait_on_delete:
             self.addCleanup(self.volumes_client.wait_for_resource_deletion,
@@ -216,11 +221,15 @@
                 cleanup_callable=self.delete_wrapper,
                 cleanup_args=[self.volumes_client.delete_volume, volume['id']])
 
-        self.assertEqual(name, volume['display_name'])
+        # NOTE(e0ne): Cinder API v2 uses name instead of display_name
+        if 'display_name' in volume:
+            self.assertEqual(name, volume['display_name'])
+        else:
+            self.assertEqual(name, volume['name'])
         self.volumes_client.wait_for_volume_status(volume['id'], 'available')
         # The volume retrieved on creation has a non-up-to-date status.
         # Retrieval after it becomes active ensures correct details.
-        volume = self.volumes_client.show_volume(volume['id'])
+        volume = self.volumes_client.show_volume(volume['id'])['volume']
         return volume
 
     def _create_loginable_secgroup_rule(self, secgroup_id=None):
@@ -445,14 +454,14 @@
         self.assertEqual(self.volume['id'], volume['id'])
         self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
         # Refresh the volume after the attachment
-        self.volume = self.volumes_client.show_volume(volume['id'])
+        self.volume = self.volumes_client.show_volume(volume['id'])['volume']
 
     def nova_volume_detach(self):
         self.servers_client.detach_volume(self.server['id'], self.volume['id'])
         self.volumes_client.wait_for_volume_status(self.volume['id'],
                                                    'available')
 
-        volume = self.volumes_client.show_volume(self.volume['id'])
+        volume = self.volumes_client.show_volume(self.volume['id'])['volume']
         self.assertEqual('available', volume['status'])
 
     def rebuild_server(self, server_id, image=None,
@@ -1291,7 +1300,10 @@
     @classmethod
     def setup_clients(cls):
         super(EncryptionScenarioTest, cls).setup_clients()
-        cls.admin_volume_types_client = cls.os_adm.volume_types_client
+        if CONF.volume_feature_enabled.api_v1:
+            cls.admin_volume_types_client = cls.os_adm.volume_types_client
+        else:
+            cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
 
     def _wait_for_volume_status(self, status):
         self.status_timeout(
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 31459cb..402bc68 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -74,11 +74,11 @@
         self.volume = self.create_volume()
 
     def cinder_list(self):
-        volumes = self.volumes_client.list_volumes()
+        volumes = self.volumes_client.list_volumes()['volumes']
         self.assertIn(self.volume['id'], [x['id'] for x in volumes])
 
     def cinder_show(self):
-        volume = self.volumes_client.show_volume(self.volume['id'])
+        volume = self.volumes_client.show_volume(self.volume['id'])['volume']
         self.assertEqual(self.volume, volume)
 
     def nova_reboot(self):
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 2a22c42..8ca5e72 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -17,7 +17,6 @@
 import re
 
 from oslo_log import log as logging
-from tempest_lib import decorators
 import testtools
 
 from tempest.common.utils import data_utils
@@ -660,7 +659,6 @@
         self.assertEqual('', port['device_owner'])
 
     @test.idempotent_id('2e788c46-fb3f-4ac9-8f82-0561555bea73')
-    @decorators.skip_because(bug="1489929")
     @test.services('compute', 'network')
     def test_router_rescheduling(self):
         """Tests that router can be removed from agent and add to a new agent.
@@ -686,6 +684,14 @@
         agent_list = set(a["id"] for a in
                          self._list_agents(agent_type="L3 agent"))
         self._setup_network_and_servers()
+
+        # NOTE(kevinbenton): we have to use the admin credentials to check
+        # for the distributed flag because self.router only has a tenant view.
+        admin = self.admin_manager.network_client.show_router(self.router.id)
+        if admin['router'].get('distributed', False):
+            msg = "Rescheduling test does not apply to distributed routers."
+            raise self.skipException(msg)
+
         self.check_public_network_connectivity(should_connect=True)
 
         # remove resource from agents
diff --git a/tempest/scenario/test_swift_telemetry_middleware.py b/tempest/scenario/test_swift_telemetry_middleware.py
index 29ce1a0..c5a0e7c 100644
--- a/tempest/scenario/test_swift_telemetry_middleware.py
+++ b/tempest/scenario/test_swift_telemetry_middleware.py
@@ -50,9 +50,6 @@
             skip_msg = ("%s skipped as ceilometer is not available" %
                         cls.__name__)
             raise cls.skipException(skip_msg)
-        elif CONF.telemetry.too_slow_to_test:
-            skip_msg = "Ceilometer feature for fast work mysql is disabled"
-            raise cls.skipException(skip_msg)
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 82f8b4c..ba419a6 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -83,7 +83,13 @@
             self.snapshots_client.wait_for_resource_deletion, snap['id'])
         self.addCleanup(self.snapshots_client.delete_snapshot, snap['id'])
         self.snapshots_client.wait_for_snapshot_status(snap['id'], 'available')
-        self.assertEqual(snap_name, snap['display_name'])
+
+        # NOTE(e0ne): Cinder API v2 uses name instead of display_name
+        if 'display_name' in snap:
+            self.assertEqual(snap_name, snap['display_name'])
+        else:
+            self.assertEqual(snap_name, snap['name'])
+
         return snap
 
     def _create_volume_from_snapshot(self, snap_id):
diff --git a/tempest/services/compute/json/floating_ips_bulk_client.py b/tempest/services/compute/json/floating_ips_bulk_client.py
index cabeeb1..dfe69f0 100644
--- a/tempest/services/compute/json/floating_ips_bulk_client.py
+++ b/tempest/services/compute/json/floating_ips_bulk_client.py
@@ -47,5 +47,4 @@
         resp, body = self.put('os-floating-ips-bulk/delete', post_body)
         body = json.loads(body)
         self.validate_response(schema.delete_floating_ips_bulk, resp, body)
-        data = body['floating_ips_bulk_delete']
-        return service_client.ResponseBodyData(resp, data)
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 9fbd03c..5603fed 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -97,35 +97,16 @@
         self.validate_response(create_schema, resp, body)
         return service_client.ResponseBody(resp, body['server'])
 
-    def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
-                      accessIPv6=None, disk_config=None):
+    def update_server(self, server_id, **kwargs):
+        """Updates the properties of an existing server.
+        Most parameters except the following are passed to the API without
+        any changes.
+        :param disk_config: The name is changed to OS-DCF:diskConfig
         """
-        Updates the properties of an existing server.
-        server_id: The id of an existing server.
-        name: The name of the server.
-        personality: A list of files to be injected into the server.
-        accessIPv4: The IPv4 access address for the server.
-        accessIPv6: The IPv6 access address for the server.
-        """
+        if kwargs.get('disk_config'):
+            kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config')
 
-        post_body = {}
-
-        if meta is not None:
-            post_body['metadata'] = meta
-
-        if name is not None:
-            post_body['name'] = name
-
-        if accessIPv4 is not None:
-            post_body['accessIPv4'] = accessIPv4
-
-        if accessIPv6 is not None:
-            post_body['accessIPv6'] = accessIPv6
-
-        if disk_config is not None:
-            post_body['OS-DCF:diskConfig'] = disk_config
-
-        post_body = json.dumps({'server': post_body})
+        post_body = json.dumps({'server': kwargs})
         resp, body = self.put("servers/%s" % server_id, post_body)
         body = json.loads(body)
         self.validate_response(schema.update_server, resp, body)
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index c5aa41a..6cad746 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -71,7 +71,8 @@
                                    "-json-patch"}
         resp, body = self.patch('v2/images/%s' % image_id, data, headers)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, self._parse_resp(body))
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
 
     def create_image(self, name, container_format, disk_format, **kwargs):
         params = {
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
index a979523..207554d 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -31,7 +31,8 @@
         url = 'os-quota-sets/%s/defaults' % tenant_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, self._parse_resp(body))
+        body = jsonutils.loads(body)
+        return service_client.ResponseBody(resp, body)
 
     def show_quota_set(self, tenant_id, params=None):
         """List the quota set for a tenant."""
@@ -42,7 +43,8 @@
 
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, self._parse_resp(body))
+        body = jsonutils.loads(body)
+        return service_client.ResponseBody(resp, body)
 
     def show_quota_usage(self, tenant_id):
         """List the quota set for a tenant."""
@@ -66,7 +68,8 @@
         post_body = jsonutils.dumps({'quota_set': post_body})
         resp, body = self.put('os-quota-sets/%s' % tenant_id, post_body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, self._parse_resp(body))
+        body = jsonutils.loads(body)
+        return service_client.ResponseBody(resp, body)
 
     def delete_quota_set(self, tenant_id):
         """Delete the tenant's quota set."""
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 26f186e..9304f63 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -39,30 +39,6 @@
         """Return the element 'attachment' from input volumes."""
         return volume['attachments'][0]
 
-    def _ext_get(self, url, key=None, status=200):
-        """Extended get method.
-
-        Retrieves requested url, checks that status is expected status and
-        return a ResponseBody, ResponseBodyList or ResponseBodyData depending
-        on received data's key entry.
-
-        If key is not specified or is None we will return the whole body in a
-        ResponseBody class.
-        """
-
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.expected_success(status, resp.status)
-
-        if not key:
-            return service_client.ResponseBody(resp, body)
-        elif isinstance(body[key], dict):
-            return service_client.ResponseBody(resp, body[key])
-        elif isinstance(body[key], list):
-            return service_client.ResponseBodyList(resp, body[key])
-
-        return service_client.ResponseBodyData(resp, body[key])
-
     def _prepare_params(self, params):
         """Prepares params for use in get or _ext_get methods.
 
@@ -73,14 +49,10 @@
             return params
         return urllib.urlencode(params)
 
-    def list_volumes(self, detail=False, params=None, return_body=False):
+    def list_volumes(self, detail=False, params=None):
         """List all the volumes created.
 
         Params can be a string (must be urlencoded) or a dictionary.
-        If return_body is True then we will return the whole response body in
-        a ResponseBody class, it it's False or has not been specified we will
-        return only the list of volumes in a ResponseBodyList (inherits from
-        list).
         """
         url = 'volumes'
         if detail:
@@ -88,8 +60,10 @@
         if params:
             url += '?%s' % self._prepare_params(params)
 
-        key = None if return_body else 'volumes'
-        return self._ext_get(url, key)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return service_client.ResponseBody(resp, body)
 
     def show_volume(self, volume_id):
         """Returns the details of a single volume."""
@@ -97,7 +71,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body['volume'])
+        return service_client.ResponseBody(resp, body)
 
     def create_volume(self, size=None, **kwargs):
         """
@@ -119,7 +93,7 @@
         resp, body = self.post('volumes', post_body)
         body = json.loads(body)
         self.expected_success(self.create_resp, resp.status)
-        return service_client.ResponseBody(resp, body['volume'])
+        return service_client.ResponseBody(resp, body)
 
     def update_volume(self, volume_id, **kwargs):
         """Updates the Specified Volume."""
@@ -127,7 +101,7 @@
         resp, body = self.put('volumes/%s' % volume_id, put_body)
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body['volume'])
+        return service_client.ResponseBody(resp, body)
 
     def delete_volume(self, volume_id):
         """Deletes the Specified Volume."""
@@ -146,8 +120,7 @@
         resp, body = self.post(url, post_body)
         body = json.loads(body)
         self.expected_success(202, resp.status)
-        return service_client.ResponseBody(resp,
-                                           body['os-volume_upload_image'])
+        return service_client.ResponseBody(resp, body)
 
     def attach_volume(self, volume_id, instance_uuid, mountpoint):
         """Attaches a volume to a given instance on a given mountpoint."""
@@ -258,7 +231,7 @@
         resp, body = self.post('os-volume-transfer', post_body)
         body = json.loads(body)
         self.expected_success(202, resp.status)
-        return service_client.ResponseBody(resp, body['transfer'])
+        return service_client.ResponseBody(resp, body)
 
     def show_volume_transfer(self, transfer_id):
         """Returns the details of a volume transfer."""
@@ -266,7 +239,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body['transfer'])
+        return service_client.ResponseBody(resp, body)
 
     def list_volume_transfers(self, params=None):
         """List all the volume transfers created."""
@@ -276,7 +249,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBodyList(resp, body['transfers'])
+        return service_client.ResponseBody(resp, body)
 
     def delete_volume_transfer(self, transfer_id):
         """Delete a volume transfer."""
@@ -294,7 +267,7 @@
         resp, body = self.post(url, post_body)
         body = json.loads(body)
         self.expected_success(202, resp.status)
-        return service_client.ResponseBody(resp, body['transfer'])
+        return service_client.ResponseBody(resp, body)
 
     def update_volume_readonly(self, volume_id, readonly):
         """Update the Specified Volume readonly."""
@@ -321,7 +294,7 @@
         resp, body = self.post(url, put_body)
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body['metadata'])
+        return service_client.ResponseBody(resp, body)
 
     def show_volume_metadata(self, volume_id):
         """Get metadata of the volume."""
@@ -329,7 +302,7 @@
         resp, body = self.get(url)
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body['metadata'])
+        return service_client.ResponseBody(resp, body)
 
     def update_volume_metadata(self, volume_id, metadata):
         """Update metadata for the volume."""
@@ -338,7 +311,7 @@
         resp, body = self.put(url, put_body)
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body['metadata'])
+        return service_client.ResponseBody(resp, body)
 
     def update_volume_metadata_item(self, volume_id, id, meta_item):
         """Update metadata item for the volume."""
@@ -347,7 +320,7 @@
         resp, body = self.put(url, put_body)
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body['meta'])
+        return service_client.ResponseBody(resp, body)
 
     def delete_volume_metadata_item(self, volume_id, id):
         """Delete metadata item for the volume."""
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index 68e2989..b35f587 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -30,7 +30,7 @@
         name = data_utils.rand_name("volume")
         self.logger.info("creating volume: %s" % name)
         volume = self.manager.volumes_client.create_volume(
-            display_name=name)
+            display_name=name)['volume']
         self.manager.volumes_client.wait_for_volume_status(volume['id'],
                                                            'available')
         self.logger.info("created volume: %s" % volume['id'])
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index dc7d217..fe481c4 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -85,7 +85,7 @@
         self.logger.info("creating volume: %s" % name)
         volumes_client = self.manager.volumes_client
         self.volume = volumes_client.create_volume(
-            display_name=name)
+            display_name=name)['volume']
         volumes_client.wait_for_volume_status(self.volume['id'],
                                               'available')
         self.logger.info("created volume: %s" % self.volume['id'])
diff --git a/tempest/stress/actions/volume_create_delete.py b/tempest/stress/actions/volume_create_delete.py
index 4870055..3986748 100644
--- a/tempest/stress/actions/volume_create_delete.py
+++ b/tempest/stress/actions/volume_create_delete.py
@@ -20,7 +20,7 @@
         name = data_utils.rand_name("volume")
         self.logger.info("creating %s" % name)
         volumes_client = self.manager.volumes_client
-        volume = volumes_client.create_volume(display_name=name)
+        volume = volumes_client.create_volume(display_name=name)['volume']
         vol_id = volume['id']
         volumes_client.wait_for_volume_status(vol_id, 'available')
         self.logger.info("created %s" % volume['id'])
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index a95d400..4a8f729 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -227,7 +227,7 @@
             display_name=self.fake_object['name'])
         mocked_function = self.fake_client.volumes.wait_for_volume_status
         mocked_function.assert_called_once_with(
-            self.fake_object.body['id'],
+            self.fake_object.body['volume']['id'],
             'available')
 
     def test_create_volume_existing(self):
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 6bc96f2..2de5802 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -240,7 +240,10 @@
                                    {'alias': 'fake2'},
                                    {'alias': 'not_fake'}]}
         fake_os = mock.MagicMock()
+        # NOTE (e0ne): mock both v1 and v2 APIs
         fake_os.volumes_extension_client.list_extensions = fake_list_extensions
+        fake_os.volumes_v2_extension_client.list_extensions = (
+            fake_list_extensions)
         self.useFixture(mockpatch.PatchObject(
             verify_tempest_config, 'get_enabled_extensions',
             return_value=(['fake1', 'fake2', 'fake3'])))
@@ -262,7 +265,10 @@
                                    {'alias': 'fake2'},
                                    {'alias': 'not_fake'}]}
         fake_os = mock.MagicMock()
+        # NOTE (e0ne): mock both v1 and v2 APIs
         fake_os.volumes_extension_client.list_extensions = fake_list_extensions
+        fake_os.volumes_v2_extension_client.list_extensions = (
+            fake_list_extensions)
         self.useFixture(mockpatch.PatchObject(
             verify_tempest_config, 'get_enabled_extensions',
             return_value=(['all'])))
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index 1acef8a..9bf8059 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -41,7 +41,7 @@
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.fake_http = fake_http.fake_httplib2(return_type=200)
-        self.stubs.Set(token_client.TokenClientJSON, 'raw_request',
+        self.stubs.Set(token_client.TokenClient, 'raw_request',
                        fake_identity._fake_v2_response)
         self.useFixture(lockutils_fixtures.ExternalLockFixture())
         self.test_accounts = [
@@ -86,7 +86,7 @@
         return hash_list
 
     def test_get_hash(self):
-        self.stubs.Set(token_client.TokenClientJSON, 'raw_request',
+        self.stubs.Set(token_client.TokenClient, 'raw_request',
                        fake_identity._fake_v2_response)
         test_account_class = accounts.Accounts('v2', 'test_name')
         hash_list = self._get_hash_list(self.test_accounts)
diff --git a/tempest/tests/common/test_cred_provider.py b/tempest/tests/common/test_cred_provider.py
index ed3f931..1bc7147 100644
--- a/tempest/tests/common/test_cred_provider.py
+++ b/tempest/tests/common/test_cred_provider.py
@@ -36,7 +36,7 @@
 
     identity_response = fake_identity._fake_v2_response
     credentials_class = auth.KeystoneV2Credentials
-    tokenclient_class = v2_client.TokenClientJSON
+    tokenclient_class = v2_client.TokenClient
     identity_version = 'v2'
 
     def setUp(self):
@@ -114,7 +114,7 @@
 
     credentials_class = auth.KeystoneV3Credentials
     identity_response = fake_identity._fake_v3_response
-    tokenclient_class = v3_client.V3TokenClientJSON
+    tokenclient_class = v3_client.V3TokenClient
     identity_version = 'v3'
 
     def setUp(self):
diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py
index 7aa6595..68a8295 100644
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -55,8 +55,8 @@
         # the volume status is 'error_restoring'.
         client = mock.Mock(spec=volumes_client.BaseVolumesClient,
                            build_interval=1)
-        volume1 = {'status': 'restoring-backup'}
-        volume2 = {'status': 'error_restoring'}
+        volume1 = {'volume': {'status': 'restoring-backup'}}
+        volume2 = {'volume': {'status': 'error_restoring'}}
         mock_show = mock.Mock(side_effect=(volume1, volume2))
         client.show_volume = mock_show
         volume_id = '7532b91e-aa0a-4e06-b3e5-20c0c5ee1caa'
diff --git a/tempest/tests/services/compute/test_certificates_client.py b/tempest/tests/services/compute/test_certificates_client.py
index 51c3e85..c926fce 100644
--- a/tempest/tests/services/compute/test_certificates_client.py
+++ b/tempest/tests/services/compute/test_certificates_client.py
@@ -13,17 +13,13 @@
 #    under the License.
 
 import copy
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
 
 from tempest.services.compute.json import certificates_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestCertificatesClient(base.TestCase):
+class TestCertificatesClient(base.BaseComputeServiceTest):
 
     FAKE_CERTIFICATE = {
         "certificate": {
@@ -39,16 +35,12 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_show_certificate(self, bytes_body=False):
-        serialized_body = json.dumps(self.FAKE_CERTIFICATE)
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.show_certificate,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_certificate("fake-id")
-        self.assertEqual(self.FAKE_CERTIFICATE, resp)
+            self.FAKE_CERTIFICATE,
+            bytes_body,
+            certificate_id="fake-id")
 
     def test_show_certificate_with_str_body(self):
         self._test_show_certificate()
@@ -59,16 +51,11 @@
     def _test_create_certificate(self, bytes_body=False):
         cert = copy.deepcopy(self.FAKE_CERTIFICATE)
         cert['certificate']['private_key'] = "my_private_key"
-        serialized_body = json.dumps(cert)
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.create_certificate,
             'tempest.common.service_client.ServiceClient.post',
-            return_value=mocked_resp))
-        resp = self.client.create_certificate()
-        self.assertEqual(cert, resp)
+            cert,
+            bytes_body)
 
     def test_create_certificate_with_str_body(self):
         self._test_create_certificate()
diff --git a/tempest/tests/services/compute/test_fixedIPs_client.py b/tempest/tests/services/compute/test_fixedIPs_client.py
new file mode 100644
index 0000000..d7a9694
--- /dev/null
+++ b/tempest/tests/services/compute/test_fixedIPs_client.py
@@ -0,0 +1,45 @@
+# 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.services.compute.json import fixed_ips_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFixedIPsClient(base.BaseComputeServiceTest):
+    FIXED_IP_INFO = {"fixed_ip": {"address": "10.0.0.1",
+                                  "cidr": "10.11.12.0/24",
+                                  "host": "localhost",
+                                  "hostname": "OpenStack"}}
+
+    def setUp(self):
+        super(TestFixedIPsClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.fixedIPsClient = (fixed_ips_client.
+                               FixedIPsClient
+                               (fake_auth, 'compute',
+                                'regionOne'))
+
+    def _test_show_fixed_ip(self, bytes_body=False):
+        self.check_service_client_function(
+            self.fixedIPsClient.show_fixed_ip,
+            'tempest.common.service_client.ServiceClient.get',
+            self.FIXED_IP_INFO, bytes_body,
+            status=200, fixed_ip='Identifier')
+
+    def test_show_fixed_ip_with_str_body(self):
+        self._test_show_fixed_ip()
+
+    def test_show_fixed_ip_with_bytes_body(self):
+        self._test_show_fixed_ip(True)
diff --git a/tempest/tests/services/compute/test_instance_usage_audit_log_client.py b/tempest/tests/services/compute/test_instance_usage_audit_log_client.py
index 07efeca..d4bc889 100644
--- a/tempest/tests/services/compute/test_instance_usage_audit_log_client.py
+++ b/tempest/tests/services/compute/test_instance_usage_audit_log_client.py
@@ -13,17 +13,13 @@
 #    under the License.
 
 import datetime
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
 
 from tempest.services.compute.json import instance_usage_audit_log_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestInstanceUsagesAuditLogClient(base.TestCase):
+class TestInstanceUsagesAuditLogClient(base.BaseComputeServiceTest):
 
     FAKE_AUDIT_LOG = {
         "hosts_not_run": [
@@ -49,18 +45,11 @@
                                                     'regionOne'))
 
     def _test_list_instance_usage_audit_logs(self, bytes_body=False):
-        serialized_body = json.dumps({"instance_usage_audit_logs":
-                                      self.FAKE_AUDIT_LOG})
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.list_instance_usage_audit_logs,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.list_instance_usage_audit_logs()
-        self.assertEqual({"instance_usage_audit_logs": self.FAKE_AUDIT_LOG},
-                         resp)
+            {"instance_usage_audit_logs": self.FAKE_AUDIT_LOG},
+            bytes_body)
 
     def test_list_instance_usage_audit_logs_with_str_body(self):
         self._test_list_instance_usage_audit_logs()
@@ -70,18 +59,12 @@
 
     def _test_show_instance_usage_audit_log(self, bytes_body=False):
         before_time = datetime.datetime(2012, 12, 1, 0, 0)
-        serialized_body = json.dumps({"instance_usage_audit_log":
-                                      self.FAKE_AUDIT_LOG})
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.show_instance_usage_audit_log,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_instance_usage_audit_log(before_time)
-        self.assertEqual({"instance_usage_audit_log": self.FAKE_AUDIT_LOG},
-                         resp)
+            {"instance_usage_audit_log": self.FAKE_AUDIT_LOG},
+            bytes_body,
+            time_before=before_time)
 
     def test_show_instance_usage_audit_log_with_str_body(self):
         self._test_show_instance_usage_audit_log()
diff --git a/tempest/tests/services/compute/test_migrations_client.py b/tempest/tests/services/compute/test_migrations_client.py
new file mode 100644
index 0000000..83fe461
--- /dev/null
+++ b/tempest/tests/services/compute/test_migrations_client.py
@@ -0,0 +1,52 @@
+# 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.services.compute.json import migrations_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestMigrationsClient(base.BaseComputeServiceTest):
+    FAKE_MIGRATION_INFO = {"migrations": [{
+        "created_at": "2012-10-29T13:42:02",
+        "dest_compute": "compute2",
+        "dest_host": "1.2.3.4",
+        "dest_node": "node2",
+        "id": 1234,
+        "instance_uuid": "e9e4fdd7-f956-44ff-bfeb-d654a96ab3a2",
+        "new_instance_type_id": 2,
+        "old_instance_type_id": 1,
+        "source_compute": "compute1",
+        "source_node": "node1",
+        "status": "finished",
+        "updated_at": "2012-10-29T13:42:02"}]}
+
+    def setUp(self):
+        super(TestMigrationsClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.mg_client_obj = migrations_client.MigrationsClient(
+            fake_auth, 'compute', 'regionOne')
+
+    def _test_list_migrations(self, bytes_body=False):
+        self.check_service_client_function(
+            self.mg_client_obj.list_migrations,
+            'tempest.common.service_client.ServiceClient.get',
+            self.FAKE_MIGRATION_INFO,
+            bytes_body)
+
+    def test_list_migration_with_str_body(self):
+        self._test_list_migrations()
+
+    def test_list_migration_with_bytes_body(self):
+        self._test_list_migrations(True)
diff --git a/tempest/tests/services/compute/test_networks_client.py b/tempest/tests/services/compute/test_networks_client.py
index 49a2344..b47430b 100644
--- a/tempest/tests/services/compute/test_networks_client.py
+++ b/tempest/tests/services/compute/test_networks_client.py
@@ -82,7 +82,7 @@
         self.check_service_client_function(
             self.client.show_network,
             'tempest.common.service_client.ServiceClient.get',
-            {"network": self.FAKE_NETWORKS},
+            {"network": self.FAKE_NETWORK},
             bytes_body,
             network_id=self.network_id
             )
diff --git a/tempest/tests/services/compute/test_tenant_networks_client.py b/tempest/tests/services/compute/test_tenant_networks_client.py
index d7c85f0..dc2de00 100644
--- a/tempest/tests/services/compute/test_tenant_networks_client.py
+++ b/tempest/tests/services/compute/test_tenant_networks_client.py
@@ -12,17 +12,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
 from tempest.services.compute.json import tenant_networks_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestTenantNetworksClient(base.TestCase):
+class TestTenantNetworksClient(base.BaseComputeServiceTest):
 
     FAKE_NETWORK = {
         "cidr": "None",
@@ -41,16 +36,11 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_list_tenant_networks(self, bytes_body=False):
-        serialized_body = json.dumps({"networks": self.FAKE_NETWORKS})
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.list_tenant_networks,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.list_tenant_networks()
-        self.assertEqual({"networks": self.FAKE_NETWORKS}, resp)
+            {"networks": self.FAKE_NETWORKS},
+            bytes_body)
 
     def test_list_tenant_networks_with_str_body(self):
         self._test_list_tenant_networks()
@@ -59,16 +49,12 @@
         self._test_list_tenant_networks(bytes_body=True)
 
     def _test_show_tenant_network(self, bytes_body=False):
-        serialized_body = json.dumps({"network": self.FAKE_NETWORK})
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.show_tenant_network,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_tenant_network(self.NETWORK_ID)
-        self.assertEqual({"network": self.FAKE_NETWORK}, resp)
+            {"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()
diff --git a/tempest/tests/test_hacking.py b/tempest/tests/test_hacking.py
index 9bc9cfe..62d2aee 100644
--- a/tempest/tests/test_hacking.py
+++ b/tempest/tests/test_hacking.py
@@ -138,3 +138,11 @@
 
         self.assertEqual(0, len(list(checks.no_mutable_default_args(
             "defined, undefined = [], {}"))))
+
+    def test_no_testtools_skip_decorator(self):
+        self.assertEqual(1, len(list(checks.no_testtools_skip_decorator(
+            " @testtools.skip('Bug xxx')"))))
+        self.assertEqual(0, len(list(checks.no_testtools_skip_decorator(
+            " @testtools.skipUnless(CONF.something, 'msg')"))))
+        self.assertEqual(0, len(list(checks.no_testtools_skip_decorator(
+            " @testtools.skipIf(CONF.something, 'msg')"))))
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index fa1b6f7..7bdc1d7 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -37,7 +37,7 @@
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.fake_http = fake_http.fake_httplib2(return_type=200)
-        self.stubs.Set(json_token_client.TokenClientJSON, 'raw_request',
+        self.stubs.Set(json_token_client.TokenClient, 'raw_request',
                        fake_identity._fake_v2_response)
         cfg.CONF.set_default('operator_role', 'FakeRole',
                              group='object-storage')
diff --git a/tox.ini b/tox.ini
index 15652e8..3250344 100644
--- a/tox.ini
+++ b/tox.ini
@@ -108,7 +108,6 @@
 commands = {posargs}
 
 [testenv:docs]
-# The sample config file we generate is included in the sphinxdoc, so build that first.
 commands =
    python setup.py build_sphinx {posargs}