Merge "Add hacking check for testtools.skip"
diff --git a/HACKING.rst b/HACKING.rst
index 76efd28..e15e213 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -74,11 +74,10 @@
 Most other assert method can include more information by default.
 For example ``self.assertIn`` can include the whole set.
 
-It is recommended to use testtools matcher for the more tricky assertions.
-`[doc] <http://testtools.readthedocs.org/en/latest/for-test-authors.html#matchers>`_
+It is recommended to use testtools `matcher`_ for the more tricky assertions.
+You can implement your own specific `matcher`_ as well.
 
-You can implement your own specific matcher as well.
-`[doc] <http://testtools.readthedocs.org/en/latest/for-test-authors.html#writing-your-own-matchers>`_
+.. _matcher: http://testtools.readthedocs.org/en/latest/for-test-authors.html#matchers
 
 If the test case fails you can see the related logs and the information
 carried by the exception (exception class, backtrack and exception info).
@@ -160,8 +159,8 @@
 sections for the test (one of those is mandatory):
 
  - A resource (part of the URL of the request): Resources needed for a test
- must be created in `setUpClass` and registered with `set_resource` e.g.:
- `cls.set_resource("server", server['id'])`
+   must be created in `setUpClass` and registered with `set_resource` e.g.:
+   `cls.set_resource("server", server['id'])`
 
  - A json schema: defines properties for a request.
 
diff --git a/README.rst b/README.rst
index d94fbdd..7108eaf 100644
--- a/README.rst
+++ b/README.rst
@@ -191,8 +191,6 @@
 
     $> testr run --parallel
 
-.. _testr: http://testrepository.readthedocs.org/en/latest/MANUAL.html
-
 To run one single test serially ::
 
     $> testr run tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server
diff --git a/REVIEWING.rst b/REVIEWING.rst
index 74bd2ad..12ccb75 100644
--- a/REVIEWING.rst
+++ b/REVIEWING.rst
@@ -34,7 +34,7 @@
 
 
 Reject Copy and Paste Test Code
-------------------------
+-------------------------------
 When creating new tests that are similar to existing tests it is tempting to
 simply copy the code and make a few modifications. This increases code size and
 the maintenance burden. Such changes should not be approved if it is easy to
diff --git a/doc/source/account_generator.rst b/doc/source/account_generator.rst
index 1c30473..032a20d 100644
--- a/doc/source/account_generator.rst
+++ b/doc/source/account_generator.rst
@@ -1,5 +1,5 @@
---------------------------------
+--------------------------------------
 Tempest Test-Account Generator Utility
---------------------------------
+--------------------------------------
 
-.. automodule:: tempest.cmd.account_generator
\ No newline at end of file
+.. automodule:: tempest.cmd.account_generator
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 3c109b5..ec430b7 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -6,7 +6,8 @@
 This guide is a starting point for configuring tempest. It aims to elaborate
 on and explain some of the mandatory and common configuration settings and how
 they are used in conjunction. The source of truth on each option is the sample
-config file which explains the purpose of each individual option.
+config file which explains the purpose of each individual option. You can see
+the sample config file here: :ref:`tempest-sampleconf`
 
 Lock Path
 ---------
diff --git a/doc/source/index.rst b/doc/source/index.rst
index e9f2161..fe6074f 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -24,7 +24,6 @@
 
    field_guide/index
    field_guide/api
-   field_guide/cli
    field_guide/scenario
    field_guide/stress
    field_guide/thirdparty
diff --git a/requirements.txt b/requirements.txt
index cc2a187..5ebcb65 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,7 +9,7 @@
 testtools>=1.4.0
 boto>=2.32.1
 paramiko>=1.13.0
-netaddr>=0.7.12
+netaddr>=0.7.12,!=0.7.16
 testrepository>=0.0.18
 pyOpenSSL>=0.14
 oslo.concurrency>=2.3.0 # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index ab40f12..46e21f1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -42,5 +42,8 @@
 build-dir = doc/build
 source-dir = doc/source
 
+[pbr]
+warnerrors = True
+
 [wheel]
 universal = 1
diff --git a/tempest/README.rst b/tempest/README.rst
index fec2874..f93a173 100644
--- a/tempest/README.rst
+++ b/tempest/README.rst
@@ -57,7 +57,7 @@
 stress job.
 
 :ref:`third_party_field_guide`
------------------------------
+------------------------------
 
 Many openstack components include 3rdparty API support. It is
 completely legitimate for Tempest to include tests of 3rdparty APIs,
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index 0809bb4..f81d665 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -45,7 +45,7 @@
         self.servers_client.resize_server(server_id, self.flavor_ref_alt)
         waiters.wait_for_server_status(self.servers_client,
                                        server_id, 'VERIFY_RESIZE')
-        self.servers_client.confirm_resize(server_id)
+        self.servers_client.confirm_resize_server(server_id)
         waiters.wait_for_server_status(self.servers_client,
                                        server_id, 'ACTIVE')
 
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index a25a2af..2624fca 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -89,6 +89,7 @@
         cls.migrations_client = cls.os.migrations_client
         cls.security_group_default_rules_client = (
             cls.os.security_group_default_rules_client)
+        cls.versions_client = cls.os.compute_versions_client
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 7f23730..126d092 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -74,7 +74,7 @@
     @test.idempotent_id('aaacd1d0-55a2-4ce8-818a-b5439df8adc9')
     def test_create_image_from_stopped_server(self):
         server = self.create_test_server(wait_until='ACTIVE')
-        self.servers_client.stop(server['id'])
+        self.servers_client.stop_server(server['id'])
         waiters.wait_for_server_status(self.servers_client,
                                        server['id'], 'SHUTOFF')
         self.addCleanup(self.servers_client.delete_server, server['id'])
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index cf0cf97..d7b4470 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -51,7 +51,7 @@
     def test_delete_server_while_in_shutoff_state(self):
         # Delete a server while it's VM state is Shutoff
         server = self.create_test_server(wait_until='ACTIVE')
-        self.client.stop(server['id'])
+        self.client.stop_server(server['id'])
         waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
         self.client.delete_server(server['id'])
         waiters.wait_for_server_termination(self.client, server['id'])
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 5b9338a..929b300 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -105,7 +105,7 @@
                                   disk_config='AUTO')
         waiters.wait_for_server_status(self.client, self.server_id,
                                        'VERIFY_RESIZE')
-        self.client.confirm_resize(self.server_id)
+        self.client.confirm_resize_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
 
         server = self.client.show_server(self.server_id)
@@ -124,7 +124,7 @@
                                   disk_config='MANUAL')
         waiters.wait_for_server_status(self.client, self.server_id,
                                        'VERIFY_RESIZE')
-        self.client.confirm_resize(self.server_id)
+        self.client.confirm_resize_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
 
         server = self.client.show_server(self.server_id)
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 5c63557..16e4392 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -137,11 +137,11 @@
     def test_list_servers_filter_by_shutoff_status(self):
         # Filter the list of servers by server shutoff status
         params = {'status': 'shutoff'}
-        self.client.stop(self.s1['id'])
+        self.client.stop_server(self.s1['id'])
         waiters.wait_for_server_status(self.client, self.s1['id'],
                                        'SHUTOFF')
         body = self.client.list_servers(**params)
-        self.client.start(self.s1['id'])
+        self.client.start_server(self.s1['id'])
         waiters.wait_for_server_status(self.client, self.s1['id'],
                                        'ACTIVE')
         servers = body['servers']
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 6b3b661..47629c0 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -191,7 +191,7 @@
         old_image = server['image']['id']
         new_image = (self.image_ref_alt
                      if old_image == self.image_ref else self.image_ref)
-        self.client.stop(self.server_id)
+        self.client.stop_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
         rebuilt_server = self.client.rebuild_server(self.server_id, new_image)
         # If the server was rebuilt on a different image, restore it to the
@@ -212,14 +212,14 @@
         rebuilt_image_id = server['image']['id']
         self.assertEqual(new_image, rebuilt_image_id)
 
-        self.client.start(self.server_id)
+        self.client.start_server(self.server_id)
 
     def _test_resize_server_confirm(self, stop=False):
         # The server's RAM and disk space should be modified to that of
         # the provided flavor
 
         if stop:
-            self.client.stop(self.server_id)
+            self.client.stop_server(self.server_id)
             waiters.wait_for_server_status(self.client, self.server_id,
                                            'SHUTOFF')
 
@@ -227,7 +227,7 @@
         waiters.wait_for_server_status(self.client, self.server_id,
                                        'VERIFY_RESIZE')
 
-        self.client.confirm_resize(self.server_id)
+        self.client.confirm_resize_server(self.server_id)
         expected_status = 'SHUTOFF' if stop else 'ACTIVE'
         waiters.wait_for_server_status(self.client, self.server_id,
                                        expected_status)
@@ -237,7 +237,7 @@
 
         if stop:
             # NOTE(mriedem): tearDown requires the server to be started.
-            self.client.start(self.server_id)
+            self.client.start_server(self.server_id)
 
         # NOTE(jlk): Explicitly delete the server to get a new one for later
         # tests. Avoids resize down race issues.
@@ -266,7 +266,7 @@
         waiters.wait_for_server_status(self.client, self.server_id,
                                        'VERIFY_RESIZE')
 
-        self.client.revert_resize(self.server_id)
+        self.client.revert_resize_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
 
         server = self.client.show_server(self.server_id)
@@ -411,7 +411,7 @@
         server = self.create_test_server(wait_until='ACTIVE')
         temp_server_id = server['id']
 
-        self.client.stop(temp_server_id)
+        self.client.stop_server(temp_server_id)
         waiters.wait_for_server_status(self.client, temp_server_id, 'SHUTOFF')
         self.wait_for(self._get_output)
 
@@ -465,9 +465,9 @@
 
     @test.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
     def test_stop_start_server(self):
-        self.client.stop(self.server_id)
+        self.client.stop_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
-        self.client.start(self.server_id)
+        self.client.start_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
 
     @test.idempotent_id('80a8094c-211e-440a-ab88-9e59d556c7ee')
@@ -479,11 +479,11 @@
         self.assertEqual(server['status'], 'ACTIVE')
         # Locked server is not allowed to be stopped by non-admin user
         self.assertRaises(lib_exc.Conflict,
-                          self.client.stop, self.server_id)
+                          self.client.stop_server, self.server_id)
         self.client.unlock_server(self.server_id)
-        self.client.stop(self.server_id)
+        self.client.stop_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
-        self.client.start(self.server_id)
+        self.client.start_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
 
     def _validate_url(self, url):
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index c243adf..8cfb670 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -95,7 +95,7 @@
     def test_update_server_name_in_stop_state(self):
         # The server name should be changed to the the provided value
         server = self.create_test_server(wait_until='ACTIVE')
-        self.client.stop(server['id'])
+        self.client.stop_server(server['id'])
         waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
         updated_server = self._update_server_name(server['id'], 'SHUTOFF')
         self.assertNotIn('progress', updated_server)
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 8f81de0..d5b60da 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -243,22 +243,21 @@
     def test_update_name_of_non_existent_server(self):
         # Update name of a non-existent server
 
-        server_name = data_utils.rand_name('server')
+        nonexistent_server = data_utils.rand_uuid()
         new_name = data_utils.rand_name('server') + '_updated'
 
         self.assertRaises(lib_exc.NotFound, self.client.update_server,
-                          server_name, name=new_name)
+                          nonexistent_server, name=new_name)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('38204696-17c6-44da-9590-40f87fb5a899')
     def test_update_server_set_empty_name(self):
         # Update name of the server to an empty string
 
-        server_name = data_utils.rand_name('server')
         new_name = ''
 
         self.assertRaises(lib_exc.BadRequest, self.client.update_server,
-                          server_name, name=new_name)
+                          self.server_id, name=new_name)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
@@ -336,7 +335,7 @@
     def test_stop_non_existent_server(self):
         # Stop a non existent server
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.servers_client.stop,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.stop_server,
                           nonexistent_server)
 
     @test.idempotent_id('6a8dc0c6-6cd4-4c0a-9f32-413881828091')
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 85f0041..7aa6d34 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -57,4 +57,5 @@
         for virt_iface in virt_ifaces['virtual_interfaces']:
             mac_address = virt_iface['mac_address']
             self.assertTrue(netaddr.valid_mac(mac_address),
-                            "Invalid mac address detected.")
+                            "Invalid mac address detected. mac address: %s"
+                            % mac_address)
diff --git a/tempest/api/compute/test_networks.py b/tempest/api/compute/test_networks.py
index bf2a78d..b53db3d 100644
--- a/tempest/api/compute/test_networks.py
+++ b/tempest/api/compute/test_networks.py
@@ -19,16 +19,16 @@
 CONF = config.CONF
 
 
-class NetworksTestJSON(base.BaseV2ComputeTest):
+class ComputeNetworksTest(base.BaseV2ComputeTest):
     @classmethod
     def skip_checks(cls):
-        super(NetworksTestJSON, cls).skip_checks()
+        super(ComputeNetworksTest, cls).skip_checks()
         if CONF.service_available.neutron:
             raise cls.skipException('nova-network is not available.')
 
     @classmethod
     def setup_clients(cls):
-        super(NetworksTestJSON, cls).setup_clients()
+        super(ComputeNetworksTest, cls).setup_clients()
         cls.client = cls.os.networks_client
 
     @test.idempotent_id('3fe07175-312e-49a5-a623-5f52eeada4c2')
diff --git a/tempest/api/compute/test_tenant_networks.py b/tempest/api/compute/test_tenant_networks.py
index 11f572e..96b7ef6 100644
--- a/tempest/api/compute/test_tenant_networks.py
+++ b/tempest/api/compute/test_tenant_networks.py
@@ -16,19 +16,29 @@
 from tempest import test
 
 
-class NetworksTestJSON(base.BaseV2ComputeTest):
+class ComputeTenantNetworksTest(base.BaseV2ComputeTest):
 
     @classmethod
     def resource_setup(cls):
-        super(NetworksTestJSON, cls).resource_setup()
+        super(ComputeTenantNetworksTest, cls).resource_setup()
         cls.client = cls.os.tenant_networks_client
+        cls.network = cls.get_tenant_network()
+
+    @classmethod
+    def setup_credentials(cls):
+        cls.set_network_resources(network=True)
+        super(ComputeTenantNetworksTest, cls).setup_credentials()
 
     @test.idempotent_id('edfea98e-bbe3-4c7a-9739-87b986baff26')
+    @test.services('network')
     def test_list_show_tenant_networks(self):
-        tenant_networks = self.client.list_tenant_networks()['networks']
-        self.assertNotEmpty(tenant_networks, "No tenant networks found.")
+        # Fetch all networks that are visible to the tenant: this may include
+        # shared and external networks
+        tenant_networks = [
+            n['id'] for n in self.client.list_tenant_networks()['networks']
+        ]
+        self.assertIn(self.network['id'], tenant_networks,
+                      "No tenant networks found.")
 
-        for net in tenant_networks:
-            tenant_network = (self.client.show_tenant_network(net['id'])
-                              ['network'])
-            self.assertEqual(net['id'], tenant_network['id'])
+        net = self.client.show_tenant_network(self.network['id'])
+        self.assertEqual(self.network['id'], net['network']['id'])
diff --git a/tempest/api/compute/test_versions.py b/tempest/api/compute/test_versions.py
new file mode 100644
index 0000000..369cf31
--- /dev/null
+++ b/tempest/api/compute/test_versions.py
@@ -0,0 +1,24 @@
+# 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 tempest.api.compute import base
+from tempest import test
+
+
+class TestVersions(base.BaseComputeTest):
+
+    @test.idempotent_id('6c0a0990-43b6-4529-9b61-5fd8daf7c55c')
+    def test_list_api_versions(self):
+        result = self.versions_client.list_versions()
+        self.assertIsNotNone(result)
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 6496854..abff422 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -97,11 +97,11 @@
         # the volume remains attached.
         self._create_and_attach()
 
-        self.servers_client.stop(self.server['id'])
+        self.servers_client.stop_server(self.server['id'])
         waiters.wait_for_server_status(self.servers_client, self.server['id'],
                                        'SHUTOFF')
 
-        self.servers_client.start(self.server['id'])
+        self.servers_client.start_server(self.server['id'])
         waiters.wait_for_server_status(self.servers_client, self.server['id'],
                                        'ACTIVE')
 
@@ -116,11 +116,11 @@
 
         self._detach(self.server['id'], self.volume['id'])
         self.attachment = None
-        self.servers_client.stop(self.server['id'])
+        self.servers_client.stop_server(self.server['id'])
         waiters.wait_for_server_status(self.servers_client, self.server['id'],
                                        'SHUTOFF')
 
-        self.servers_client.start(self.server['id'])
+        self.servers_client.start_server(self.server['id'])
         waiters.wait_for_server_status(self.servers_client, self.server['id'],
                                        'ACTIVE')
 
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 7b23e66..ada292f 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -77,7 +77,7 @@
     @classmethod
     def setup_clients(cls):
         super(BaseIdentityV2Test, cls).setup_clients()
-        cls.non_admin_client = cls.os.identity_client
+        cls.non_admin_client = cls.os.identity_public_client
         cls.non_admin_token_client = cls.os.token_client
 
     @classmethod
@@ -97,6 +97,7 @@
     def setup_clients(cls):
         super(BaseIdentityV2AdminTest, cls).setup_clients()
         cls.client = cls.os_adm.identity_client
+        cls.non_admin_client = cls.os.identity_client
         cls.token_client = cls.os_adm.token_client
 
     @classmethod
diff --git a/tempest/api/identity/v2/test_tenants.py b/tempest/api/identity/v2/test_tenants.py
new file mode 100644
index 0000000..1fcff8d
--- /dev/null
+++ b/tempest/api/identity/v2/test_tenants.py
@@ -0,0 +1,50 @@
+# Copyright 2015 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_lib import exceptions as lib_exc
+
+from tempest.api.identity import base
+from tempest import test
+
+
+class IdentityTenantsTest(base.BaseIdentityV2Test):
+
+    credentials = ['primary', 'alt']
+
+    @test.idempotent_id('ecae2459-243d-4ba1-ad02-65f15dc82b78')
+    def test_list_tenants_returns_only_authorized_tenants(self):
+        alt_tenant_name = self.alt_manager.credentials.credentials.tenant_name
+        resp = self.non_admin_client.list_tenants()
+
+        # check that user can see only that tenants that he presents in so user
+        # can successfully authenticate using his credentials and tenant name
+        # from received tenants list
+        for tenant in resp['tenants']:
+            body = self.non_admin_token_client.auth(
+                self.os.credentials.username,
+                self.os.credentials.password,
+                tenant['name'])
+            self.assertNotEmpty(body['token']['id'])
+            self.assertEqual(body['token']['tenant']['id'], tenant['id'])
+            self.assertEqual(body['token']['tenant']['name'], tenant['name'])
+            self.assertEqual(body['user']['id'], self.os.credentials.user_id)
+
+        # check that user cannot log in to alt user's tenant
+        self.assertRaises(
+            lib_exc.Unauthorized,
+            self.non_admin_token_client.auth,
+            self.os.credentials.username,
+            self.os.credentials.password,
+            alt_tenant_name)
diff --git a/tempest/api/identity/v2/test_users.py b/tempest/api/identity/v2/test_users.py
new file mode 100644
index 0000000..4e5b41d
--- /dev/null
+++ b/tempest/api/identity/v2/test_users.py
@@ -0,0 +1,78 @@
+# Copyright 2015 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.
+
+import copy
+
+from tempest_lib.common.utils import data_utils
+from tempest_lib import exceptions
+
+from tempest.api.identity import base
+from tempest import manager
+from tempest import test
+
+
+class IdentityUsersTest(base.BaseIdentityV2Test):
+
+    @classmethod
+    def resource_setup(cls):
+        super(IdentityUsersTest, cls).resource_setup()
+        cls.creds = cls.os.credentials
+        cls.username = cls.creds.username
+        cls.password = cls.creds.password
+        cls.tenant_name = cls.creds.tenant_name
+
+    @test.idempotent_id('165859c9-277f-4124-9479-a7d1627b0ca7')
+    def test_user_update_own_password(self):
+        self.new_creds = copy.copy(self.creds.credentials)
+        self.new_creds.password = data_utils.rand_password()
+        # we need new non-admin Identity Client with new credentials, since
+        # current non_admin_client token will be revoked after updating
+        # password
+        self.non_admin_client_for_cleanup = copy.copy(self.non_admin_client)
+        self.non_admin_client_for_cleanup.auth_provider = (
+            manager.get_auth_provider(self.new_creds))
+        user_id = self.creds.credentials.user_id
+        old_pass = self.creds.credentials.password
+        new_pass = self.new_creds.password
+
+        # to change password back. important for allow_tenant_isolation = false
+        self.addCleanup(
+            self.non_admin_client_for_cleanup.update_user_own_password,
+            user_id=user_id,
+            new_pass=old_pass,
+            old_pass=new_pass)
+
+        # user updates own password
+        resp = self.non_admin_client.update_user_own_password(
+            user_id=user_id, new_pass=new_pass, old_pass=old_pass)
+
+        # check authorization with new token
+        self.non_admin_token_client.auth_token(resp['token']['id'])
+        # check authorization with new password
+        self.non_admin_token_client.auth(self.username,
+                                         new_pass,
+                                         self.tenant_name)
+
+        # authorize with old token should lead to Unauthorized
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_token_client.auth_token,
+                          self.non_admin_client.token)
+
+        # authorize with old password should lead to Unauthorized
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_token_client.auth,
+                          self.username,
+                          old_pass,
+                          self.tenant_name)
diff --git a/tempest/api/identity/v3/test_projects.py b/tempest/api/identity/v3/test_projects.py
new file mode 100644
index 0000000..a547b06
--- /dev/null
+++ b/tempest/api/identity/v3/test_projects.py
@@ -0,0 +1,53 @@
+# Copyright 2015 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_lib import exceptions as lib_exc
+
+from tempest.api.identity import base
+from tempest import test
+
+
+class IdentityV3ProjectsTest(base.BaseIdentityV3Test):
+
+    credentials = ['primary', 'alt']
+
+    @test.idempotent_id('86128d46-e170-4644-866a-cc487f699e1d')
+    def test_list_projects_returns_only_authorized_projects(self):
+        alt_project_name =\
+            self.alt_manager.credentials.credentials.project_name
+        resp = self.non_admin_client.list_user_projects(
+            self.os.credentials.user_id)
+
+        # check that user can see only that projects that he presents in so
+        # user can successfully authenticate using his credentials and
+        # project name from received projects list
+        for project in resp['projects']:
+            token_id, body = self.non_admin_token.get_token(
+                username=self.os.credentials.username,
+                password=self.os.credentials.password,
+                project_name=project['name'],
+                auth_data=True)
+            self.assertNotEmpty(token_id)
+            self.assertEqual(body['project']['id'], project['id'])
+            self.assertEqual(body['project']['name'], project['name'])
+            self.assertEqual(body['user']['id'], self.os.credentials.user_id)
+
+        # check that user cannot log in to alt user's project
+        self.assertRaises(
+            lib_exc.Unauthorized,
+            self.non_admin_token.get_token,
+            username=self.os.credentials.username,
+            password=self.os.credentials.password,
+            project_name=alt_project_name)
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
new file mode 100644
index 0000000..a1f664f
--- /dev/null
+++ b/tempest/api/identity/v3/test_users.py
@@ -0,0 +1,72 @@
+# Copyright 2015 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.
+
+import copy
+
+from tempest_lib.common.utils import data_utils
+from tempest_lib import exceptions
+
+from tempest.api.identity import base
+from tempest import manager
+from tempest import test
+
+
+class IdentityV3UsersTest(base.BaseIdentityV3Test):
+
+    @classmethod
+    def resource_setup(cls):
+        super(IdentityV3UsersTest, cls).resource_setup()
+        cls.creds = cls.os.credentials
+        cls.user_id = cls.creds.user_id
+        cls.username = cls.creds.username
+        cls.password = cls.creds.password
+
+    @test.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
+    def test_user_update_own_password(self):
+        self.new_creds = copy.copy(self.creds.credentials)
+        self.new_creds.password = data_utils.rand_password()
+        # we need new non-admin Identity V3 Client with new credentials, since
+        # current non_admin_client token will be revoked after updating
+        # password
+        self.non_admin_client_for_cleanup = copy.copy(self.non_admin_client)
+        self.non_admin_client_for_cleanup.auth_provider = (
+            manager.get_auth_provider(self.new_creds))
+        user_id = self.creds.credentials.user_id
+        old_pass = self.creds.credentials.password
+        new_pass = self.new_creds.password
+        # to change password back. important for allow_tenant_isolation = false
+        self.addCleanup(
+            self.non_admin_client_for_cleanup.update_user_password,
+            user_id=user_id,
+            password=old_pass,
+            original_password=new_pass)
+
+        # user updates own password
+        self.non_admin_client.update_user_password(
+            user_id=user_id, password=new_pass, original_password=old_pass)
+
+        # check authorization with new password
+        self.non_admin_token.auth(user_id=self.user_id, password=new_pass)
+
+        # authorize with old token should lead to IdentityError (404 code)
+        self.assertRaises(exceptions.IdentityError,
+                          self.non_admin_token.auth,
+                          token=self.non_admin_client.token)
+
+        # authorize with old password should lead to Unauthorized
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_token.auth,
+                          user_id=self.user_id,
+                          password=old_pass)
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index f56688f..d6b03eb 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -40,7 +40,7 @@
                           'agent', 'dhcp_agent_scheduler', 'provider',
                           'router', 'extraroute', 'external-net',
                           'allowed-address-pairs', 'extra_dhcp_opt',
-                          'metering', 'dvr', 'service-type']
+                          'metering', 'dvr']
         expected_alias = [ext for ext in expected_alias if
                           test.is_extension_enabled(ext, 'network')]
         actual_alias = list()
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 5685be8..1116573 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -27,7 +27,7 @@
 CONF = config.CONF
 
 
-class NetworksTestJSON(base.BaseNetworkTest):
+class NetworksTest(base.BaseNetworkTest):
     """
     Tests the following operations in the Neutron API using the REST client for
     Neutron:
@@ -61,7 +61,7 @@
 
     @classmethod
     def resource_setup(cls):
-        super(NetworksTestJSON, cls).resource_setup()
+        super(NetworksTest, cls).resource_setup()
         cls.network = cls.create_network()
         cls.name = cls.network['name']
         cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
@@ -533,7 +533,7 @@
     _ip_version = 6
 
 
-class NetworksIpV6TestJSON(NetworksTestJSON):
+class NetworksIpV6TestJSON(NetworksTest):
     _ip_version = 6
 
     @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index 5dc1c21..94c3f9a 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -26,35 +26,35 @@
     @test.attr(type=['negative'])
     @test.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
     def test_show_non_existent_network(self):
-        non_exist_id = data_utils.rand_name('network')
+        non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.show_network,
                           non_exist_id)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
     def test_show_non_existent_subnet(self):
-        non_exist_id = data_utils.rand_name('subnet')
+        non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
                           non_exist_id)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('a954861d-cbfd-44e8-b0a9-7fab111f235d')
     def test_show_non_existent_port(self):
-        non_exist_id = data_utils.rand_name('port')
+        non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.show_port,
                           non_exist_id)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('98bfe4e3-574e-4012-8b17-b2647063de87')
     def test_update_non_existent_network(self):
-        non_exist_id = data_utils.rand_name('network')
+        non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.update_network,
                           non_exist_id, name="new_name")
 
     @test.attr(type=['negative'])
     @test.idempotent_id('03795047-4a94-4120-a0a1-bd376e36fd4e')
     def test_delete_non_existent_network(self):
-        non_exist_id = data_utils.rand_name('network')
+        non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.delete_network,
                           non_exist_id)
 
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index 5d1784f..8f07614 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -15,6 +15,7 @@
 from oslo_utils import timeutils
 from tempest_lib import exceptions as lib_exc
 
+from tempest.common import compute
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -73,9 +74,11 @@
 
     @classmethod
     def create_server(cls):
-        body = cls.servers_client.create_server(
-            data_utils.rand_name('ceilometer-instance'),
-            CONF.compute.image_ref, CONF.compute.flavor_ref,
+        tenant_network = cls.get_tenant_network()
+        body, server = compute.create_test_server(
+            cls.os,
+            tenant_network=tenant_network,
+            name=data_utils.rand_name('ceilometer-instance'),
             wait_until='ACTIVE')
         cls.server_ids.append(body['id'])
         return body
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index c987100..80f858b 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
@@ -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_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 79615b3..d81462e 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()
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 9db2321..db156f0 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
 from testtools import matchers
 
 from tempest.api.volume import base
@@ -138,6 +139,8 @@
             imageRef=CONF.compute.image_ref, size=disk_size)
 
     @test.idempotent_id('3f591b4a-7dc6-444c-bd51-77469506b3a1')
+    @testtools.skipUnless(CONF.volume_feature_enabled.clone,
+                          'Cinder volume clones are disabled')
     def test_volume_create_get_update_delete_as_clone(self):
         origin = self.create_volume()
         self._volume_create_get_update_delete(source_volid=origin['id'])
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 48f40f0..7c373b7 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()),
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 058e220..4bbb0f1 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'],
diff --git a/tempest/api_schema/response/compute/v2_1/version.py b/tempest/api_schema/response/compute/v2_1/version.py
deleted file mode 100644
index 6579c63..0000000
--- a/tempest/api_schema/response/compute/v2_1/version.py
+++ /dev/null
@@ -1,59 +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.
-
-version = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            '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']
-                        }
-                    },
-                    'media-types': {
-                        'type': 'array',
-                        'items': {
-                            'type': 'object',
-                            'properties': {
-                                'base': {'type': 'string'},
-                                'type': {'type': 'string'}
-                            },
-                            'required': ['base', 'type']
-                        }
-                    },
-                    'status': {'type': 'string'},
-                    'updated': {'type': 'string', 'format': 'date-time'},
-                    'version': {'type': 'string'},
-                    'min_version': {'type': 'string'}
-                },
-                # NOTE: version and min_version have been added since Kilo,
-                # so they should not be required.
-                'required': ['id', 'links', 'media-types', 'status', 'updated']
-            }
-        },
-        'required': ['version']
-    }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/versions.py b/tempest/api_schema/response/compute/v2_1/versions.py
new file mode 100644
index 0000000..a01dd41
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_1/versions.py
@@ -0,0 +1,54 @@
+# 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.
+
+list_versions = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'versions': {
+                'type': 'array',
+                'items': {
+                    'type': 'object',
+                    'properties': {
+                        'id': {'type': 'string'},
+                        'links': {
+                            'type': 'array',
+                            'items': {
+                                'type': 'object',
+                                'properties': {
+                                    'href': {'type': 'string',
+                                             'format': 'uri'},
+                                    'rel': {'type': 'string'},
+                                },
+                                'required': ['href', 'rel'],
+                                'additionalProperties': False
+                            }
+                        },
+                        'status': {'type': 'string'},
+                        'updated': {'type': 'string', 'format': 'date-time'},
+                        'version': {'type': 'string'},
+                        'min_version': {'type': 'string'}
+                    },
+                    # NOTE: version and min_version have been added since Kilo,
+                    # so they should not be required.
+                    'required': ['id', 'links', 'status', 'updated'],
+                    'additionalProperties': False
+                }
+            }
+        },
+        'required': ['versions'],
+        'additionalProperties': False
+    }
+}
diff --git a/tempest/clients.py b/tempest/clients.py
index b9f7991..c0d4585 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -77,6 +77,7 @@
     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_extensions_client import \
     VolumesExtensionsClient
 from tempest.services.data_processing.v1_1.data_processing_client import \
@@ -322,6 +323,8 @@
         })
         self.volumes_extensions_client = VolumesExtensionsClient(
             self.auth_provider, **params_volume)
+        self.compute_versions_client = VersionsClient(self.auth_provider,
+                                                      **params_volume)
 
     def _set_database_clients(self):
         self.database_flavors_client = DatabaseFlavorsClient(
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index e05cab3..3d24547 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -25,7 +25,7 @@
 **Usage:** ``tempest-account-generator [-h] [OPTIONS] accounts_file.yaml``.
 
 Positional Arguments
------------------
+--------------------
 **accounts_file.yaml** (Required) Provide an output accounts yaml file. Utility
 creates a .yaml file in the directory where the command is ran. The appropriate
 name for the file is *accounts.yaml* and it should be placed in *tempest/etc*
@@ -49,7 +49,7 @@
     +----------+------------------+----------------------+
 
 Optional Arguments
------------------
+------------------
 **-h**, **--help** (Optional) Shows help message with the description of
 utility and its arguments, and exits.
 
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 365f37f..07d1d75 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -930,7 +930,7 @@
 
     def list(self):
         client = self.client
-        domains = client.list_domains()
+        domains = client.list_domains()['domains']
         if not self.is_save_state:
             domains = [domain for domain in domains if domain['id']
                        not in self.saved_state_json['domains'].keys()]
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 05ea393..5c4d8af 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -27,7 +27,7 @@
 
 
 def create_test_server(clients, validatable=False, validation_resources=None,
-                       tenant_network=None, **kwargs):
+                       tenant_network=None, wait_until=None, **kwargs):
     """Common wrapper utility returning a test server.
 
     This method is a common wrapper returning a test server that can be
@@ -37,6 +37,9 @@
     :param validatable: Whether the server will be pingable or sshable.
     :param validation_resources: Resources created for the connection to the
     server. Include a keypair, a security group and an IP.
+    :param tenant_network: Tenant network to be used for creating a server.
+    :param wait_until: Server status to wait for the server to reach after
+    its creation.
     :returns a tuple
     """
 
@@ -78,8 +81,8 @@
                 LOG.debug("No key provided.")
 
         if CONF.validation.connect_method == 'floating':
-            if 'wait_until' not in kwargs:
-                kwargs['wait_until'] = 'ACTIVE'
+            if wait_until is None:
+                wait_until = 'ACTIVE'
 
     body = clients.servers_client.create_server(name, image_id, flavor,
                                                 **kwargs)
@@ -96,11 +99,11 @@
     # long for PEP8 compliance so:
     assoc = clients.floating_ips_client.associate_floating_ip_to_server
 
-    if 'wait_until' in kwargs:
+    if wait_until:
         for server in servers:
             try:
                 waiters.wait_for_server_status(
-                    clients.servers_client, server['id'], kwargs['wait_until'])
+                    clients.servers_client, server['id'], wait_until)
 
                 # Multiple validatable servers are not supported for now. Their
                 # creation will fail with the condition above (l.58).
diff --git a/tempest/config.py b/tempest/config.py
index b5f1de1..b6daa2e 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -702,6 +702,9 @@
     cfg.BoolOpt('snapshot',
                 default=True,
                 help='Runs Cinder volume snapshot test'),
+    cfg.BoolOpt('clone',
+                default=True,
+                help='Runs Cinder volume clone test'),
     cfg.ListOpt('api_extensions',
                 default=['all'],
                 help='A list of enabled volume extensions with a special '
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index c38ce2d..31459cb 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -63,9 +63,12 @@
 
     def nova_show(self):
         got_server = self.servers_client.show_server(self.server['id'])
+        excluded_keys = ['OS-EXT-AZ:availability_zone']
+        # Exclude these keys because of LP:#1486475
+        excluded_keys.extend(['OS-EXT-STS:power_state', 'updated'])
         self.assertThat(
             self.server, custom_matchers.MatchesDictExceptForKeys(
-                got_server, excluded_keys=['OS-EXT-AZ:availability_zone']))
+                got_server, excluded_keys=excluded_keys))
 
     def cinder_create(self):
         self.volume = self.create_volume()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 71c48fe..62b2976 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -100,11 +100,11 @@
     @test.services('compute', 'network')
     def test_server_connectivity_stop_start(self):
         self._setup_network_and_servers()
-        self.servers_client.stop(self.server['id'])
+        self.servers_client.stop_server(self.server['id'])
         waiters.wait_for_server_status(self.servers_client,
                                        self.server['id'], 'SHUTOFF')
         self._check_network_connectivity(should_connect=False)
-        self.servers_client.start(self.server['id'])
+        self.servers_client.start_server(self.server['id'])
         self._wait_server_status_and_check_network_connectivity()
 
     @test.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
@@ -164,5 +164,5 @@
                                           flavor_ref=resize_flavor)
         waiters.wait_for_server_status(self.servers_client, self.server['id'],
                                        'VERIFY_RESIZE')
-        self.servers_client.confirm_resize(self.server['id'])
+        self.servers_client.confirm_resize_server(self.server['id'])
         self._wait_server_status_and_check_network_connectivity()
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_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 8693fb3..99eecae 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -63,7 +63,7 @@
                                        'VERIFY_RESIZE')
 
         LOG.debug("Confirming resize of instance %s", instance_id)
-        self.servers_client.confirm_resize(instance_id)
+        self.servers_client.confirm_resize_server(instance_id)
 
         waiters.wait_for_server_status(self.servers_client, instance_id,
                                        'ACTIVE')
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 0066213..82f8b4c 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -93,21 +93,14 @@
     def _stop_instances(self, instances):
         # NOTE(gfidente): two loops so we do not wait for the status twice
         for i in instances:
-            self.servers_client.stop(i['id'])
+            self.servers_client.stop_server(i['id'])
         for i in instances:
             waiters.wait_for_server_status(self.servers_client,
                                            i['id'], 'SHUTOFF')
 
     def _ssh_to_server(self, server, keypair):
         if CONF.compute.use_floatingip_for_ssh:
-            floating_ip = (self.floating_ips_client.create_floating_ip()
-                           ['floating_ip'])
-            self.addCleanup(self.delete_wrapper,
-                            self.floating_ips_client.delete_floating_ip,
-                            floating_ip['id'])
-            self.floating_ips_client.associate_floating_ip_to_server(
-                floating_ip['ip'], server['id'])
-            ip = floating_ip['ip']
+            ip = self.create_floating_ip(server)['ip']
         else:
             ip = server
 
diff --git a/tempest/services/compute/json/floating_ip_pools_client.py b/tempest/services/compute/json/floating_ip_pools_client.py
index 7a4434f..c83537a 100644
--- a/tempest/services/compute/json/floating_ip_pools_client.py
+++ b/tempest/services/compute/json/floating_ip_pools_client.py
@@ -13,8 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import json
-
+from oslo_serialization import jsonutils as json
 from six.moves.urllib import parse as urllib
 
 from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
diff --git a/tempest/services/compute/json/floating_ips_bulk_client.py b/tempest/services/compute/json/floating_ips_bulk_client.py
index c51f77e..cabeeb1 100644
--- a/tempest/services/compute/json/floating_ips_bulk_client.py
+++ b/tempest/services/compute/json/floating_ips_bulk_client.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import json
+from oslo_serialization import jsonutils as json
 
 from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
 from tempest.common import service_client
diff --git a/tempest/services/compute/json/security_group_rules_client.py b/tempest/services/compute/json/security_group_rules_client.py
index c9096d0..c1c6b1a 100644
--- a/tempest/services/compute/json/security_group_rules_client.py
+++ b/tempest/services/compute/json/security_group_rules_client.py
@@ -13,8 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import json
-
+from oslo_serialization import jsonutils as json
 from tempest_lib import exceptions as lib_exc
 
 from tempest.api_schema.response.compute.v2_1 import security_groups as schema
diff --git a/tempest/services/compute/json/server_groups_client.py b/tempest/services/compute/json/server_groups_client.py
index 30e9e5b..33501fb 100644
--- a/tempest/services/compute/json/server_groups_client.py
+++ b/tempest/services/compute/json/server_groups_client.py
@@ -14,7 +14,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import json
+from oslo_serialization import jsonutils as json
 
 from tempest.api_schema.response.compute.v2_1 import servers as schema
 from tempest.common import service_client
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 671450a..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)
@@ -252,13 +233,13 @@
             kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config')
         return self.action(server_id, 'resize', None, **kwargs)
 
-    def confirm_resize(self, server_id, **kwargs):
+    def confirm_resize_server(self, server_id, **kwargs):
         """Confirms the flavor change for a server."""
         return self.action(server_id, 'confirmResize',
                            None, schema.server_actions_confirm_resize,
                            **kwargs)
 
-    def revert_resize(self, server_id, **kwargs):
+    def revert_resize_server(self, server_id, **kwargs):
         """Reverts a server back to its original flavor."""
         return self.action(server_id, 'revertResize', None, **kwargs)
 
@@ -311,10 +292,10 @@
                                resp, body)
         return service_client.ResponseBody(resp, body)
 
-    def stop(self, server_id, **kwargs):
+    def stop_server(self, server_id, **kwargs):
         return self.action(server_id, 'os-stop', None, **kwargs)
 
-    def start(self, server_id, **kwargs):
+    def start_server(self, server_id, **kwargs):
         return self.action(server_id, 'os-start', None, **kwargs)
 
     def attach_volume(self, server_id, **kwargs):
diff --git a/tempest/services/compute/json/versions_client.py b/tempest/services/compute/json/versions_client.py
new file mode 100644
index 0000000..cbad02c
--- /dev/null
+++ b/tempest/services/compute/json/versions_client.py
@@ -0,0 +1,37 @@
+# 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 list_versions(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)
+        version_url = '%s://%s/' % (url.scheme, url.netloc)
+
+        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)
diff --git a/tempest/services/database/json/limits_client.py b/tempest/services/database/json/limits_client.py
index 9358a33..da495d7 100644
--- a/tempest/services/database/json/limits_client.py
+++ b/tempest/services/database/json/limits_client.py
@@ -13,6 +13,7 @@
 #    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.common import service_client
@@ -27,4 +28,5 @@
             url += '?%s' % urllib.urlencode(params)
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
+        body = json.loads(body)
         return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index 43d253b..7a560d9 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -13,6 +13,7 @@
 #    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.common import service_client
@@ -43,4 +44,5 @@
 
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
+        body = json.loads(body)
         return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
index e6416d6..8eeefe7 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -297,6 +297,17 @@
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, self._parse_resp(body))
 
+    def update_user_own_password(self, user_id, new_pass, old_pass):
+        """User updates own password"""
+        patch_body = {
+            "password": new_pass,
+            "original_password": old_pass
+        }
+        patch_body = json.dumps({'user': patch_body})
+        resp, body = self.patch('OS-KSCRUD/users/%s' % user_id, patch_body)
+        self.expected_success(200, resp.status)
+        return service_client.ResponseBody(resp, self._parse_resp(body))
+
     def list_extensions(self):
         """List all the extensions."""
         resp, body = self.get('/extensions')
diff --git a/tempest/tests/services/compute/base.py b/tempest/tests/services/compute/base.py
new file mode 100644
index 0000000..a35a87c
--- /dev/null
+++ b/tempest/tests/services/compute/base.py
@@ -0,0 +1,43 @@
+# Copyright 2015 Deutsche Telekom AG.  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 httplib2
+
+from oslo_serialization import jsonutils as json
+from oslotest import mockpatch
+
+from tempest.tests import base
+
+
+class BaseComputeServiceTest(base.TestCase):
+    def create_response(self, body, to_utf=False, status=200):
+        json_body = {}
+        if body:
+            json_body = json.dumps(body)
+            if to_utf:
+                json_body = json_body.encode('utf-8')
+        response = (httplib2.Response({'status': status}), json_body)
+        return response
+
+    def check_service_client_function(self, function, function2mock,
+                                      body, to_utf=False, status=200,
+                                      **kwargs):
+        mocked_response = self.create_response(body, to_utf, status)
+        self.useFixture(mockpatch.Patch(
+            function2mock, return_value=mocked_response))
+        if kwargs:
+            resp = function(**kwargs)
+        else:
+            resp = function()
+        self.assertEqual(body, resp)
diff --git a/tempest/tests/services/compute/test_agents_client.py b/tempest/tests/services/compute/test_agents_client.py
index d14d8bf..9493a32 100644
--- a/tempest/tests/services/compute/test_agents_client.py
+++ b/tempest/tests/services/compute/test_agents_client.py
@@ -12,17 +12,37 @@
 #    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 agents_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestAgentsClient(base.TestCase):
+class TestAgentsClient(base.BaseComputeServiceTest):
+    FAKE_CREATE_AGENT = {
+        "agent":
+        {
+            "url": "http://foo.com",
+            "hypervisor": "kvm",
+            "md5hash": "md5",
+            "version": "2",
+            "architecture": "x86_64",
+            "os": "linux",
+            "agent_id": 1
+        }
+    }
+
+    FAKE_UPDATE_AGENT = {
+        "agent":
+        {
+            "url": "http://foo.com",
+            "hypervisor": "kvm",
+            "md5hash": "md5",
+            "version": "2",
+            "architecture": "x86_64",
+            "os": "linux",
+            "agent_id": 1
+        }
+    }
 
     def setUp(self):
         super(TestAgentsClient, self).setUp()
@@ -31,57 +51,34 @@
                                                  'compute', 'regionOne')
 
     def _test_list_agents(self, bytes_body=False):
-        body = '{"agents": []}'
-        if bytes_body:
-            body = body.encode('utf-8')
-        expected = {"agents": []}
-        response = (httplib2.Response({'status': 200}), body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.list_agents,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=response))
-        self.assertEqual(expected, self.client.list_agents())
+            {"agents": []},
+            bytes_body)
 
     def _test_create_agent(self, bytes_body=False):
-        expected = {"agent": {"url": "http://foo.com", "hypervisor": "kvm",
-                              "md5hash": "md5", "version": "2",
-                              "architecture": "x86_64",
-                              "os": "linux", "agent_id": 1}}
-        serialized_body = json.dumps(expected)
-        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_agent,
             'tempest.common.service_client.ServiceClient.post',
-            return_value=mocked_resp))
-        resp = self.client.create_agent(
+            self.FAKE_CREATE_AGENT,
+            bytes_body,
             url="http://foo.com", hypervisor="kvm", md5hash="md5",
-            version="2", architecture="x86_64", os="linux"
-        )
-        self.assertEqual(expected, resp)
+            version="2", architecture="x86_64", os="linux")
 
     def _test_delete_agent(self):
-        mocked_resp = (httplib2.Response({'status': 200}), None)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.delete_agent,
             'tempest.common.service_client.ServiceClient.delete',
-            return_value=mocked_resp))
-        self.client.delete_agent("1")
+            {}, agent_id="1")
 
     def _test_update_agent(self, bytes_body=False):
-        expected = {"agent": {"url": "http://foo.com", "md5hash": "md5",
-                              "version": "2", "agent_id": 1}}
-        serialized_body = json.dumps(expected)
-        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.update_agent,
             'tempest.common.service_client.ServiceClient.put',
-            return_value=mocked_resp))
-        resp = self.client.update_agent(
-            "1", url="http://foo.com", md5hash="md5", version="2"
-        )
-        self.assertEqual(expected, resp)
+            self.FAKE_UPDATE_AGENT,
+            bytes_body,
+            agent_id="1", url="http://foo.com", md5hash="md5", version="2")
 
     def test_list_agents_with_str_body(self):
         self._test_list_agents()
diff --git a/tempest/tests/services/compute/test_aggregates_client.py b/tempest/tests/services/compute/test_aggregates_client.py
index 14930a7..8184a46 100644
--- a/tempest/tests/services/compute/test_aggregates_client.py
+++ b/tempest/tests/services/compute/test_aggregates_client.py
@@ -12,17 +12,55 @@
 #    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 aggregates_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestAggregatesClient(base.TestCase):
+class TestAggregatesClient(base.BaseComputeServiceTest):
+    FAKE_SHOW_AGGREGATE = {
+        "aggregate":
+        {
+            "name": "hoge",
+            "availability_zone": None,
+            "deleted": False,
+            "created_at":
+            "2015-07-16T03:07:32.000000",
+            "updated_at": None,
+            "hosts": [],
+            "deleted_at": None,
+            "id": 1,
+            "metadata": {}
+        }
+    }
+
+    FAKE_CREATE_AGGREGATE = {
+        "aggregate":
+        {
+            "name": u'\xf4',
+            "availability_zone": None,
+            "deleted": False,
+            "created_at": "2015-07-21T04:11:18.000000",
+            "updated_at": None,
+            "deleted_at": None,
+            "id": 1
+        }
+    }
+
+    FAKE_UPDATE_AGGREGATE = {
+        "aggregate":
+        {
+            "name": u'\xe9',
+            "availability_zone": None,
+            "deleted": False,
+            "created_at": "2015-07-16T03:07:32.000000",
+            "updated_at": "2015-07-23T05:16:29.000000",
+            "hosts": [],
+            "deleted_at": None,
+            "id": 1,
+            "metadata": {}
+        }
+    }
 
     def setUp(self):
         super(TestAggregatesClient, self).setUp()
@@ -31,15 +69,11 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_list_aggregates(self, bytes_body=False):
-        body = '{"aggregates": []}'
-        if bytes_body:
-            body = body.encode('utf-8')
-        expected = {"aggregates": []}
-        response = (httplib2.Response({'status': 200}), body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.list_aggregates,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=response))
-        self.assertEqual(expected, self.client.list_aggregates())
+            {"aggregates": []},
+            bytes_body)
 
     def test_list_aggregates_with_str_body(self):
         self._test_list_aggregates()
@@ -48,26 +82,12 @@
         self._test_list_aggregates(bytes_body=True)
 
     def _test_show_aggregate(self, bytes_body=False):
-        expected = {"aggregate": {"name": "hoge",
-                                  "availability_zone": None,
-                                  "deleted": False,
-                                  "created_at":
-                                  "2015-07-16T03:07:32.000000",
-                                  "updated_at": None,
-                                  "hosts": [],
-                                  "deleted_at": None,
-                                  "id": 1,
-                                  "metadata": {}}}
-        serialized_body = json.dumps(expected)
-        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_aggregate,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_aggregate(1)
-        self.assertEqual(expected, resp)
+            self.FAKE_SHOW_AGGREGATE,
+            bytes_body,
+            aggregate_id=1)
 
     def test_show_aggregate_with_str_body(self):
         self._test_show_aggregate()
@@ -76,23 +96,12 @@
         self._test_show_aggregate(bytes_body=True)
 
     def _test_create_aggregate(self, bytes_body=False):
-        expected = {"aggregate": {"name": u'\xf4',
-                                  "availability_zone": None,
-                                  "deleted": False,
-                                  "created_at": "2015-07-21T04:11:18.000000",
-                                  "updated_at": None,
-                                  "deleted_at": None,
-                                  "id": 1}}
-        serialized_body = json.dumps(expected)
-        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_aggregate,
             'tempest.common.service_client.ServiceClient.post',
-            return_value=mocked_resp))
-        resp = self.client.create_aggregate(name='hoge')
-        self.assertEqual(expected, resp)
+            self.FAKE_CREATE_AGGREGATE,
+            bytes_body,
+            name='hoge')
 
     def test_create_aggregate_with_str_body(self):
         self._test_create_aggregate()
@@ -101,34 +110,18 @@
         self._test_create_aggregate(bytes_body=True)
 
     def test_delete_aggregate(self):
-        expected = {}
-        mocked_resp = (httplib2.Response({'status': 200}), None)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.delete_aggregate,
             'tempest.common.service_client.ServiceClient.delete',
-            return_value=mocked_resp))
-        resp = self.client.delete_aggregate("1")
-        self.assertEqual(expected, resp)
+            {}, aggregate_id="1")
 
     def _test_update_aggregate(self, bytes_body=False):
-        expected = {"aggregate": {"name": u'\xe9',
-                                  "availability_zone": None,
-                                  "deleted": False,
-                                  "created_at": "2015-07-16T03:07:32.000000",
-                                  "updated_at": "2015-07-23T05:16:29.000000",
-                                  "hosts": [],
-                                  "deleted_at": None,
-                                  "id": 1,
-                                  "metadata": {}}}
-        serialized_body = json.dumps(expected)
-        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.update_aggregate,
             'tempest.common.service_client.ServiceClient.put',
-            return_value=mocked_resp))
-        resp = self.client.update_aggregate(1)
-        self.assertEqual(expected, resp)
+            self.FAKE_UPDATE_AGGREGATE,
+            bytes_body,
+            aggregate_id=1)
 
     def test_update_aggregate_with_str_body(self):
         self._test_update_aggregate()
diff --git a/tempest/tests/services/compute/test_availability_zone_client.py b/tempest/tests/services/compute/test_availability_zone_client.py
index 64efd08..715cfd7 100644
--- a/tempest/tests/services/compute/test_availability_zone_client.py
+++ b/tempest/tests/services/compute/test_availability_zone_client.py
@@ -12,27 +12,25 @@
 #    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 availability_zone_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestAvailabilityZoneClient(base.TestCase):
+class TestAvailabilityZoneClient(base.BaseComputeServiceTest):
 
-    FAKE_AVAILABIRITY_ZONE_INFO = [
-        {
-            "zoneState": {
-                "available": True
-            },
-            "hosts": None,
-            "zoneName": u'\xf4'
-        }
-    ]
+    FAKE_AVAILABIRITY_ZONE_INFO = {
+        "availabilityZoneInfo":
+        [
+            {
+                "zoneState": {
+                    "available": True
+                },
+                "hosts": None,
+                "zoneName": u'\xf4'
+            }
+        ]
+    }
 
     def setUp(self):
         super(TestAvailabilityZoneClient, self).setUp()
@@ -40,22 +38,14 @@
         self.client = availability_zone_client.AvailabilityZoneClient(
             fake_auth, 'compute', 'regionOne')
 
-    def _test_list_availability_zones(self, bytes_body=False):
-        serialized_body = json.dumps({
-            "availabilityZoneInfo": self.FAKE_AVAILABIRITY_ZONE_INFO})
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
-            'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.list_availability_zones()
-        self.assertEqual({
-            "availabilityZoneInfo": self.FAKE_AVAILABIRITY_ZONE_INFO}, resp)
-
     def test_list_availability_zones_with_str_body(self):
-        self._test_list_availability_zones()
+        self.check_service_client_function(
+            self.client.list_availability_zones,
+            'tempest.common.service_client.ServiceClient.get',
+            self.FAKE_AVAILABIRITY_ZONE_INFO)
 
     def test_list_availability_zones_with_bytes_body(self):
-        self._test_list_availability_zones(bytes_body=True)
+        self.check_service_client_function(
+            self.client.list_availability_zones,
+            'tempest.common.service_client.ServiceClient.get',
+            self.FAKE_AVAILABIRITY_ZONE_INFO, to_utf=True)
diff --git a/tempest/tests/services/compute/test_extensions_client.py b/tempest/tests/services/compute/test_extensions_client.py
index 20a5b7b..86f81f3 100644
--- a/tempest/tests/services/compute/test_extensions_client.py
+++ b/tempest/tests/services/compute/test_extensions_client.py
@@ -12,17 +12,24 @@
 #    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 extensions_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestExtensionsClient(base.TestCase):
+class TestExtensionsClient(base.BaseComputeServiceTest):
+
+    FAKE_SHOW_EXTENSION = {
+        "extension": {
+            "updated": "2011-06-09T00:00:00Z",
+            "name": "Multinic",
+            "links": [],
+            "namespace":
+            "http://docs.openstack.org/compute/ext/multinic/api/v1.1",
+            "alias": "NMN",
+            "description": u'\u2740(*\xb4\u25e1`*)\u2740'
+        }
+    }
 
     def setUp(self):
         super(TestExtensionsClient, self).setUp()
@@ -31,15 +38,11 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_list_extensions(self, bytes_body=False):
-        body = '{"extensions": []}'
-        if bytes_body:
-            body = body.encode('utf-8')
-        expected = {"extensions": []}
-        response = (httplib2.Response({'status': 200}), body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.list_extensions,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=response))
-        self.assertEqual(expected, self.client.list_extensions())
+            {"extensions": []},
+            bytes_body)
 
     def test_list_extensions_with_str_body(self):
         self._test_list_extensions()
@@ -48,25 +51,12 @@
         self._test_list_extensions(bytes_body=True)
 
     def _test_show_extension(self, bytes_body=False):
-        expected = {"extension": {
-            "updated": "2011-06-09T00:00:00Z",
-            "name": "Multinic",
-            "links": [],
-            "namespace":
-            "http://docs.openstack.org/compute/ext/multinic/api/v1.1",
-            "alias": "NMN",
-            "description": u'\u2740(*\xb4\u25e1`*)\u2740'
-        }}
-        serialized_body = json.dumps(expected)
-        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_extension,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_extension("NMN")
-        self.assertEqual(expected, resp)
+            self.FAKE_SHOW_EXTENSION,
+            bytes_body,
+            extension_alias="NMN")
 
     def test_show_extension_with_str_body(self):
         self._test_show_extension()
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_keypairs_client.py b/tempest/tests/services/compute/test_keypairs_client.py
index 8a0edd0..6ad187b 100644
--- a/tempest/tests/services/compute/test_keypairs_client.py
+++ b/tempest/tests/services/compute/test_keypairs_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 keypairs_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestKeyPairsClient(base.TestCase):
+class TestKeyPairsClient(base.BaseComputeServiceTest):
 
     FAKE_KEYPAIR = {"keypair": {
         "public_key": "ssh-rsa foo Generated-by-Nova",
@@ -39,15 +35,11 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_list_keypairs(self, bytes_body=False):
-        body = '{"keypairs": []}'
-        if bytes_body:
-            body = body.encode('utf-8')
-        expected = {"keypairs": []}
-        response = (httplib2.Response({'status': 200}), body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.list_keypairs,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=response))
-        self.assertEqual(expected, self.client.list_keypairs())
+            {"keypairs": []},
+            bytes_body)
 
     def test_list_keypairs_with_str_body(self):
         self._test_list_keypairs()
@@ -64,16 +56,13 @@
             "deleted_at": None,
             "id": 1
             })
-        serialized_body = json.dumps(fake_keypair)
-        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_keypair,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_keypair("test")
-        self.assertEqual(fake_keypair, resp)
+            fake_keypair,
+            bytes_body,
+            keypair_name="test")
 
     def test_show_keypair_with_str_body(self):
         self._test_show_keypair()
@@ -84,16 +73,13 @@
     def _test_create_keypair(self, bytes_body=False):
         fake_keypair = copy.deepcopy(self.FAKE_KEYPAIR)
         fake_keypair["keypair"].update({"private_key": "foo"})
-        serialized_body = json.dumps(fake_keypair)
-        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_keypair,
             'tempest.common.service_client.ServiceClient.post',
-            return_value=mocked_resp))
-        resp = self.client.create_keypair(name='test')
-        self.assertEqual(fake_keypair, resp)
+            fake_keypair,
+            bytes_body,
+            name="test")
 
     def test_create_keypair_with_str_body(self):
         self._test_create_keypair()
@@ -102,10 +88,7 @@
         self._test_create_keypair(bytes_body=True)
 
     def test_delete_keypair(self):
-        expected = {}
-        mocked_resp = (httplib2.Response({'status': 202}), None)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.delete_keypair,
             'tempest.common.service_client.ServiceClient.delete',
-            return_value=mocked_resp))
-        resp = self.client.delete_keypair('test')
-        self.assertEqual(expected, resp)
+            {}, status=202, keypair_name='test')
diff --git a/tempest/tests/services/compute/test_limits_client.py b/tempest/tests/services/compute/test_limits_client.py
index 099d5ca..0036a3d 100644
--- a/tempest/tests/services/compute/test_limits_client.py
+++ b/tempest/tests/services/compute/test_limits_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 limits_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestLimitsClient(base.TestCase):
+class TestLimitsClient(base.BaseComputeServiceTest):
 
     def setUp(self):
         super(TestLimitsClient, self).setUp()
@@ -54,19 +49,15 @@
                     "maxTotalInstances": 10,
                     "maxTotalRAMSize": 51200,
                     "maxServerGroupMembers": 10
-                }
+                    }
             }
         }
-        serialized_body = json.dumps(expected)
-        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_limits,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_limits()
-        self.assertEqual(expected, resp)
+            expected,
+            bytes_body)
 
     def test_show_limits_with_str_body(self):
         self._test_show_limits()
diff --git a/tempest/tests/services/compute/test_networks_client.py b/tempest/tests/services/compute/test_networks_client.py
index cbeaefc..49a2344 100644
--- a/tempest/tests/services/compute/test_networks_client.py
+++ b/tempest/tests/services/compute/test_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 networks_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestNetworksClient(base.TestCase):
+class TestNetworksClient(base.BaseComputeServiceTest):
 
     FAKE_NETWORK = {
         "bridge": None,
@@ -70,17 +65,12 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_list_networks(self, bytes_body=False):
-        expected = {"networks": self.FAKE_NETWORKS}
-        serialized_body = json.dumps(expected)
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        fake_list = {"networks": self.FAKE_NETWORKS}
+        self.check_service_client_function(
+            self.client.list_networks,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.list_networks()
-        self.assertEqual(expected, resp)
+            fake_list,
+            bytes_body)
 
     def test_list_networks_with_str_body(self):
         self._test_list_networks()
@@ -89,17 +79,13 @@
         self._test_list_networks(bytes_body=True)
 
     def _test_show_network(self, bytes_body=False):
-        expected = {"network": self.FAKE_NETWORKS}
-        serialized_body = json.dumps(expected)
-        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_network,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_network(self.network_id)
-        self.assertEqual(expected, resp)
+            {"network": self.FAKE_NETWORKS},
+            bytes_body,
+            network_id=self.network_id
+            )
 
     def test_show_network_with_str_body(self):
         self._test_show_network()
diff --git a/tempest/tests/services/compute/test_quota_classes_client.py b/tempest/tests/services/compute/test_quota_classes_client.py
index bc52511..f4fc51a 100644
--- a/tempest/tests/services/compute/test_quota_classes_client.py
+++ b/tempest/tests/services/compute/test_quota_classes_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 quota_classes_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestQuotaClassesClient(base.TestCase):
+class TestQuotaClassesClient(base.BaseComputeServiceTest):
 
     FAKE_QUOTA_CLASS_SET = {
         "injected_file_content_bytes": 10240,
@@ -50,17 +46,13 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_show_quota_class_set(self, bytes_body=False):
-        expected = {'quota_class_set': self.FAKE_QUOTA_CLASS_SET}
-        serialized_body = json.dumps(expected)
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        fake_body = {'quota_class_set': self.FAKE_QUOTA_CLASS_SET}
+        self.check_service_client_function(
+            self.client.show_quota_class_set,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_quota_class_set("test")
-        self.assertEqual(expected, resp)
+            fake_body,
+            bytes_body,
+            quota_class_id="test")
 
     def test_show_quota_class_set_with_str_body(self):
         self._test_show_quota_class_set()
@@ -71,12 +63,9 @@
     def test_update_quota_class_set(self):
         fake_quota_class_set = copy.deepcopy(self.FAKE_QUOTA_CLASS_SET)
         fake_quota_class_set.pop("id")
-        expected = {'quota_class_set': fake_quota_class_set}
-        serialized_body = json.dumps(expected)
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        fake_body = {'quota_class_set': fake_quota_class_set}
+        self.check_service_client_function(
+            self.client.update_quota_class_set,
             'tempest.common.service_client.ServiceClient.put',
-            return_value=mocked_resp))
-        resp = self.client.update_quota_class_set("test")
-        self.assertEqual(expected, resp)
+            fake_body,
+            quota_class_id="test")
diff --git a/tempest/tests/services/compute/test_quotas_client.py b/tempest/tests/services/compute/test_quotas_client.py
index 0f72b3d..68f74aa 100644
--- a/tempest/tests/services/compute/test_quotas_client.py
+++ b/tempest/tests/services/compute/test_quotas_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 quotas_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestQuotasClient(base.TestCase):
+class TestQuotasClient(base.BaseComputeServiceTest):
 
     FAKE_QUOTA_SET = {
         "quota_set": {
@@ -53,16 +49,12 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_show_quota_set(self, bytes_body=False):
-        serialized_body = json.dumps(self.FAKE_QUOTA_SET)
-        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_quota_set,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_quota_set(self.project_id)
-        self.assertEqual(self.FAKE_QUOTA_SET, resp)
+            self.FAKE_QUOTA_SET,
+            to_utf=bytes_body,
+            tenant_id=self.project_id)
 
     def test_show_quota_set_with_str_body(self):
         self._test_show_quota_set()
@@ -71,16 +63,12 @@
         self._test_show_quota_set(bytes_body=True)
 
     def _test_show_default_quota_set(self, bytes_body=False):
-        serialized_body = json.dumps(self.FAKE_QUOTA_SET)
-        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_default_quota_set,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_default_quota_set(self.project_id)
-        self.assertEqual(self.FAKE_QUOTA_SET, resp)
+            self.FAKE_QUOTA_SET,
+            to_utf=bytes_body,
+            tenant_id=self.project_id)
 
     def test_show_default_quota_set_with_str_body(self):
         self._test_show_quota_set()
@@ -91,19 +79,14 @@
     def test_update_quota_set(self):
         fake_quota_set = copy.deepcopy(self.FAKE_QUOTA_SET)
         fake_quota_set['quota_set'].pop("id")
-        serialized_body = json.dumps(fake_quota_set)
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.update_quota_set,
             'tempest.common.service_client.ServiceClient.put',
-            return_value=mocked_resp))
-        resp = self.client.update_quota_set(self.project_id)
-        self.assertEqual(fake_quota_set, resp)
+            fake_quota_set,
+            tenant_id=self.project_id)
 
     def test_delete_quota_set(self):
-        expected = {}
-        mocked_resp = (httplib2.Response({'status': 202}), None)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.delete_quota_set,
             'tempest.common.service_client.ServiceClient.delete',
-            return_value=mocked_resp))
-        resp = self.client.delete_quota_set(self.project_id)
-        self.assertEqual(expected, resp)
+            {}, status=202, tenant_id=self.project_id)
diff --git a/tempest/tests/services/compute/test_services_client.py b/tempest/tests/services/compute/test_services_client.py
index 7d87711..fe63de9 100644
--- a/tempest/tests/services/compute/test_services_client.py
+++ b/tempest/tests/services/compute/test_services_client.py
@@ -13,34 +13,36 @@
 #    under the License.
 
 import copy
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
 
 from tempest.services.compute.json import services_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestServicesClient(base.TestCase):
+class TestServicesClient(base.BaseComputeServiceTest):
 
-    FAKE_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_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 = {
-        "status": "enabled",
-        "binary": "nova-conductor",
-        "host": "controller"
+        "service":
+        {
+            "status": "enabled",
+            "binary": "nova-conductor",
+            "host": "controller"
         }
+    }
 
     def setUp(self):
         super(TestServicesClient, self).setUp()
@@ -48,37 +50,25 @@
         self.client = services_client.ServicesClient(
             fake_auth, 'compute', 'regionOne')
 
-    def _test_list_services(self, bytes_body=False):
-        expected = {"services": self.FAKE_SERVICES}
-        serialized_body = json.dumps(expected)
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
-
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
-            'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.list_services()
-        self.assertEqual(expected, resp)
-
     def test_list_services_with_str_body(self):
-        self._test_list_services()
+        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._test_list_services(bytes_body=True)
+        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):
-        expected = {"service": self.FAKE_SERVICE}
-        serialized_body = json.dumps(expected)
-        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.enable_service,
             'tempest.common.service_client.ServiceClient.put',
-            return_value=mocked_resp))
-        resp = self.client.enable_service("nova-conductor", "controller")
-        self.assertEqual(expected, resp)
+            self.FAKE_SERVICE,
+            bytes_body,
+            host_name="nova-conductor", binary="controller")
 
     def test_enable_service_with_str_body(self):
         self._test_enable_service()
@@ -88,18 +78,14 @@
 
     def _test_disable_service(self, bytes_body=False):
         fake_service = copy.deepcopy(self.FAKE_SERVICE)
-        fake_service["status"] = "disable"
-        expected = {"service": self.FAKE_SERVICE}
-        serialized_body = json.dumps(expected)
-        if bytes_body:
-            serialized_body = serialized_body.encode('utf-8')
+        fake_service["service"]["status"] = "disable"
 
-        mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
-        self.useFixture(mockpatch.Patch(
+        self.check_service_client_function(
+            self.client.enable_service,
             'tempest.common.service_client.ServiceClient.put',
-            return_value=mocked_resp))
-        resp = self.client.disable_service("nova-conductor", "controller")
-        self.assertEqual(expected, resp)
+            fake_service,
+            bytes_body,
+            host_name="nova-conductor", binary="controller")
 
     def test_disable_service_with_str_body(self):
         self._test_enable_service()
diff --git a/tempest/tests/services/compute/test_tenant_networks_client.py b/tempest/tests/services/compute/test_tenant_networks_client.py
new file mode 100644
index 0000000..d7c85f0
--- /dev/null
+++ b/tempest/tests/services/compute/test_tenant_networks_client.py
@@ -0,0 +1,77 @@
+# 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 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
+
+
+class TestTenantNetworksClient(base.TestCase):
+
+    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):
+        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(
+            'tempest.common.service_client.ServiceClient.get',
+            return_value=mocked_resp))
+        resp = self.client.list_tenant_networks()
+        self.assertEqual({"networks": self.FAKE_NETWORKS}, resp)
+
+    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):
+        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(
+            '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)
+
+    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
index f6bcf5f..8a2c1a4 100644
--- a/tempest/tests/services/compute/test_tenant_usages_client.py
+++ b/tempest/tests/services/compute/test_tenant_usages_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_usages_client
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
 
 
-class TestTenantUsagesClient(base.TestCase):
+class TestTenantUsagesClient(base.BaseComputeServiceTest):
 
     FAKE_SERVER_USAGES = [{
         "ended_at": None,
@@ -57,17 +52,11 @@
             fake_auth, 'compute', 'regionOne')
 
     def _test_list_tenant_usages(self, bytes_body=False):
-        serialized_body = json.dumps({"tenant_usages":
-                                      self.FAKE_TENANT_USAGES})
-        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_usages,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.list_tenant_usages()
-        self.assertEqual({"tenant_usages": self.FAKE_TENANT_USAGES}, resp)
+            {"tenant_usages": self.FAKE_TENANT_USAGES},
+            to_utf=bytes_body)
 
     def test_list_tenant_usages_with_str_body(self):
         self._test_list_tenant_usages()
@@ -76,17 +65,12 @@
         self._test_list_tenant_usages(bytes_body=True)
 
     def _test_show_tenant_usage(self, bytes_body=False):
-        serialized_body = json.dumps({"tenant_usage":
-                                      self.FAKE_TENANT_USAGES[0]})
-        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_usage,
             'tempest.common.service_client.ServiceClient.get',
-            return_value=mocked_resp))
-        resp = self.client.show_tenant_usage('openstack')
-        self.assertEqual({"tenant_usage": self.FAKE_TENANT_USAGES[0]}, resp)
+            {"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()
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}