Merge "Skip the test_get_service_by_host_name"
diff --git a/.coveragerc b/.coveragerc
index c9b6467..51482d3 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,4 +1,4 @@
 [run]
 branch = True
 source = tempest
-omit = tempest/tests/*,tempest/openstack/*
+omit = tempest/tests/*,tempest/scenario/test_*.py,tempest/api_schema/*,tempest/api/*
diff --git a/.gitignore b/.gitignore
index efba45e..d58b162 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,9 @@
 dist
 build
 .testrepository
+.idea
+.project
+.pydevproject
 .coverage*
 !.coveragerc
 cover/
diff --git a/.mailmap b/.mailmap
index 5c37a5e..a43c0b9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,9 +1,25 @@
-Ravikumar Venkatesan <ravikumar.venkatesan@hp.com> ravikumar-venkatesan <ravikumar.venkatesan@hp.com>
-Ravikumar Venkatesan <ravikumar.venkatesan@hp.com> ravikumar venkatesan <ravikumar.venkatesan@hp.com>
-Rohit Karajgi <rohit.karajgi@nttdata.com> Rohit Karajgi <rohit.karajgi@vertex.co.in>
-Jay Pipes <jaypipes@gmail.com> Jay Pipes <jpipes@librebox.gateway.2wire.net>
-Joe Gordon <joe.gordon0@gmail.com> <jogo@cloudscaling.com>
 <brian.waldon@rackspace.com> <bcwaldon@gmail.com>
-Daryl Walleck <daryl.walleck@rackspace.com> dwalleck <daryl.walleck@rackspace.com>
 <jeblair@hp.com> <corvus@inaugust.com>
 <jeblair@hp.com> <james.blair@rackspace.com>
+Adam Gandelman <adamg@ubuntu.com> Adam Gandelman <adamg@canonical.com>
+Andrea Frittoli (andreaf) <andrea.frittoli@hpe.com> Andrea Frittoli (andreaf) <andrea.frittoli@hp.com>
+Andrea Frittoli (andreaf) <andrea.frittoli@hpe.com> Andrea Frittoli <andrea.frittoli@hp.com>
+Daryl Walleck <daryl.walleck@rackspace.com> dwalleck <daryl.walleck@rackspace.com>
+David Kranz <dkranz@redhat.com> David Kranz <david.kranz@qrclab.com>
+Ghanshyam <ghanshyam.mann@nectechnologies.in> Ghanshyam Mann <ghanshyam.mann@nectechnologies.in>
+Ghanshyam <ghanshyam.mann@nectechnologies.in> ghanshyam <ghanshyam.mann@nectechnologies.in>
+Jay Pipes <jaypipes@gmail.com> Jay Pipes <jpipes@librebox.gateway.2wire.net>
+Joe Gordon <joe.gordon0@gmail.com> <jogo@cloudscaling.com>
+Ken'ichi Ohmichi <ken-oomichi@wx.jp.nec.com> Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
+Marc Koderer <marc@koderer.com> Marc Koderer <m.koderer@telekom.de>
+Masayuki Igawa <masayuki.igawa@gmail.com> Masayuki Igawa <igawa@mxs.nes.nec.co.jp>
+Masayuki Igawa <masayuki.igawa@gmail.com> Masayuki Igawa <mas-igawa@ut.jp.nec.com>
+Matthew Treinish <mtreinish@kortar.org> Matthew Treinish <treinish@linux.vnet.ibm.com>
+Nayna Patel <nayna.patel@hp.com> nayna-patel <nayna.patel@hp.com>
+ravikumar-venkatesan <ravikumar.venkatesan@hp.com> Ravikumar Venkatesan <ravikumar.venkatesan@hp.com>
+ravikumar-venkatesan <ravikumar.venkatesan@hp.com> ravikumar venkatesan <ravikumar.venkatesan@hp.com>
+Rohit Karajgi <rohit.karajgi@nttdata.com> Rohit Karajgi <rohit.karajgi@vertex.co.in>
+Sean Dague <sean@dague.net> Sean Dague <sdague@linux.vnet.ibm.com>
+Sean Dague <sean@dague.net> Sean Dague <sean.dague@samsung.com>
+Yuiko Takada <takada-yuiko@mxn.nes.nec.co.jp> YuikoTakada <takada-yuiko@mxn.nes.nec.co.jp>
+Zhi Kun Liu <zhikunli@cn.ibm.com> Liu, Zhi Kun <zhikunli@cn.ibm.com>
diff --git a/requirements.txt b/requirements.txt
index aa304a4..66e5696 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,27 +1,27 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-pbr>=1.6
-cliff>=1.15.0 # Apache-2.0
-anyjson>=0.3.3
-httplib2>=0.7.5
-jsonschema!=2.5.0,<3.0.0,>=2.0.0
-testtools>=1.4.0
-paramiko>=1.13.0
-netaddr!=0.7.16,>=0.7.12
-testrepository>=0.0.18
-pyOpenSSL>=0.14
+pbr>=1.6 # Apache-2.0
+cliff!=1.16.0,>=1.15.0 # Apache-2.0
+anyjson>=0.3.3 # BSD
+httplib2>=0.7.5 # MIT
+jsonschema!=2.5.0,<3.0.0,>=2.0.0 # MIT
+testtools>=1.4.0 # MIT
+paramiko>=1.16.0 # LGPL
+netaddr!=0.7.16,>=0.7.12 # BSD
+testrepository>=0.0.18 # Apache-2.0/BSD
+pyOpenSSL>=0.14 # Apache-2.0
 oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=3.2.0 # Apache-2.0
-oslo.i18n>=1.5.0 # Apache-2.0
+oslo.config>=3.4.0 # Apache-2.0
+oslo.i18n>=2.1.0 # Apache-2.0
 oslo.log>=1.14.0 # Apache-2.0
 oslo.serialization>=1.10.0 # Apache-2.0
-oslo.utils>=3.2.0 # Apache-2.0
-six>=1.9.0
-iso8601>=0.1.9
-fixtures>=1.3.1
-testscenarios>=0.4
-tempest-lib>=0.13.0
-PyYAML>=3.1.0
+oslo.utils>=3.4.0 # Apache-2.0
+six>=1.9.0 # MIT
+iso8601>=0.1.9 # MIT
+fixtures>=1.3.1 # Apache-2.0/BSD
+testscenarios>=0.4 # Apache-2.0/BSD
+tempest-lib>=0.14.0 # Apache-2.0
+PyYAML>=3.1.0 # MIT
 stevedore>=1.5.0 # Apache-2.0
-PrettyTable<0.8,>=0.7
+PrettyTable<0.8,>=0.7 # BSD
diff --git a/setup.cfg b/setup.cfg
index b94a4f4..cc3a365 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -33,10 +33,12 @@
     tempest-account-generator = tempest.cmd.account_generator:main
     tempest = tempest.cmd.main:main
 tempest.cm =
+    account-generator = tempest.cmd.account_generator:TempestAccountGenerator
     init = tempest.cmd.init:TempestInit
     cleanup = tempest.cmd.cleanup:TempestCleanup
     run-stress = tempest.cmd.run_stress:TempestRunStress
     list-plugins = tempest.cmd.list_plugins:TempestListPlugins
+    verify-config = tempest.cmd.verify_tempest_config:TempestVerifyConfig
 oslo.config.opts =
     tempest.config = tempest.config:list_opts
 
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 7c4c30c..3ad9305 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -76,14 +76,6 @@
             if host != target_host:
                 return target_host
 
-    def _get_server_status(self, server_id):
-        return self._get_server_details(server_id)['status']
-
-    def _create_server(self, volume_backed=False):
-            server = self.create_test_server(wait_until="ACTIVE",
-                                             volume_backed=volume_backed)
-            return server['id']
-
     def _volume_clean_up(self, server_id, volume_id):
         body = self.volumes_client.show_volume(volume_id)['volume']
         if body['status'] == 'in-use':
@@ -103,7 +95,8 @@
                               volume_backed, *block* migration is not used.
         """
         # Live migrate an instance to another host
-        server_id = self._create_server(volume_backed=volume_backed)
+        server_id = self.create_test_server(wait_until="ACTIVE",
+                                            volume_backed=volume_backed)['id']
         actual_host = self._get_host_for_server(server_id)
         target_host = self._get_host_other_than(actual_host)
 
@@ -133,10 +126,6 @@
     @test.idempotent_id('1e107f21-61b2-4988-8f22-b196e938ab88')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
-    @testtools.skipUnless(CONF.compute_feature_enabled
-                              .live_migrate_paused_instances,
-                          'Live migration of paused instances is not '
-                          'available.')
     def test_live_block_migration_paused(self):
         self._test_live_migration(state='PAUSED')
 
@@ -153,7 +142,7 @@
                       block_migrate_cinder_iscsi,
                       'Block Live migration not configured for iSCSI')
     def test_iscsi_volume(self):
-        server_id = self._create_server()
+        server_id = self.create_test_server(wait_until="ACTIVE")['id']
         actual_host = self._get_host_for_server(server_id)
         target_host = self._get_host_other_than(actual_host)
 
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index fd6f105..49c7318 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -15,6 +15,7 @@
 from tempest_lib import decorators
 
 from tempest.api.compute import base
+from tempest.common import compute
 from tempest.common import fixed_network
 from tempest.common.utils import data_utils
 from tempest.common import waiters
@@ -104,16 +105,14 @@
     def test_list_servers_filter_by_exist_host(self):
         # Filter the list of servers by existent host
         name = data_utils.rand_name('server')
-        flavor = self.flavor_ref
-        image_id = self.image_ref
         network = self.get_tenant_network()
         network_kwargs = fixed_network.set_networks_kwarg(network)
-        test_server = self.client.create_server(name=name, imageRef=image_id,
-                                                flavorRef=flavor,
-                                                **network_kwargs)['server']
+        # We need to create the server as an admin, so we can't use
+        # self.create_test_server() here as this method creates the server
+        # in the "primary" (i.e non-admin) tenant.
+        test_server, _ = compute.create_test_server(
+            self.os_adm, wait_until="ACTIVE", name=name, **network_kwargs)
         self.addCleanup(self.client.delete_server, test_server['id'])
-        waiters.wait_for_server_status(self.client,
-                                       test_server['id'], 'ACTIVE')
         server = self.client.show_server(test_server['id'])['server']
         self.assertEqual(server['status'], 'ACTIVE')
         hostname = server[self._host_key]
diff --git a/tempest/api/compute/admin/test_servers_on_multinodes.py b/tempest/api/compute/admin/test_servers_on_multinodes.py
new file mode 100644
index 0000000..814a876
--- /dev/null
+++ b/tempest/api/compute/admin/test_servers_on_multinodes.py
@@ -0,0 +1,68 @@
+# Copyright 2016 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class ServersOnMultiNodesTest(base.BaseV2ComputeAdminTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(ServersOnMultiNodesTest, cls).skip_checks()
+
+        if CONF.compute.min_compute_nodes < 2:
+            raise cls.skipException(
+                "Less than 2 compute nodes, skipping multi-nodes test.")
+
+    def _get_host(self, server_id):
+        return self.os_adm.servers_client.show_server(
+            server_id)['server']['OS-EXT-SRV-ATTR:host']
+
+    @test.idempotent_id('26a9d5df-6890-45f2-abc4-a659290cb130')
+    def test_create_servers_on_same_host(self):
+        server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+        hints = {'same_host': server01}
+        server02 = self.create_test_server(scheduler_hints=hints,
+                                           wait_until='ACTIVE')['id']
+        host01 = self._get_host(server01)
+        host02 = self._get_host(server02)
+        self.assertEqual(host01, host02)
+
+    @test.idempotent_id('cc7ca884-6e3e-42a3-a92f-c522fcf25e8e')
+    def test_create_servers_on_different_hosts(self):
+        server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+        hints = {'different_host': server01}
+        server02 = self.create_test_server(scheduler_hints=hints,
+                                           wait_until='ACTIVE')['id']
+        host01 = self._get_host(server01)
+        host02 = self._get_host(server02)
+        self.assertNotEqual(host01, host02)
+
+    @test.idempotent_id('7869cc84-d661-4e14-9f00-c18cdc89cf57')
+    def test_create_servers_on_different_hosts_with_list_of_servers(self):
+        server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+        # This scheduler-hint supports list of servers also.
+        hints = {'different_host': [server01]}
+        server02 = self.create_test_server(scheduler_hints=hints,
+                                           wait_until='ACTIVE')['id']
+        host01 = self._get_host(server01)
+        host02 = self._get_host(server02)
+        self.assertNotEqual(host01, host02)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 8a27929..0856983 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -23,6 +23,7 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
+from tempest import exceptions
 import tempest.test
 
 CONF = config.CONF
@@ -329,11 +330,12 @@
             except Exception:
                 LOG.exception('Failed to delete server %s' % server_id)
 
+        cls.password = data_utils.rand_password()
         server = cls.create_test_server(
             validatable,
             wait_until='ACTIVE',
+            adminPass=cls.password,
             **kwargs)
-        cls.password = server['adminPass']
         return server['id']
 
     @classmethod
@@ -355,16 +357,19 @@
     def get_server_ip(cls, server):
         """Get the server fixed or floating IP.
 
-        For the floating IP, the address created by the validation resources
-        is returned.
-        For the fixed IP, the server is returned and the current mechanism of
-        address extraction in the remote_client is followed.
+        Based on the configuration we're in, return a correct ip
+        address for validating that a guest is up.
         """
         if CONF.validation.connect_method == 'floating':
-            ip_or_server = cls.validation_resources['floating_ip']['ip']
+            return cls.validation_resources['floating_ip']['ip']
         elif CONF.validation.connect_method == 'fixed':
-            ip_or_server = server
-        return ip_or_server
+            addresses = server['addresses'][CONF.validation.network_for_ssh]
+            for address in addresses:
+                if address['version'] == CONF.validation.ip_version_for_ssh:
+                    return address['addr']
+            raise exceptions.ServerUnreachable()
+        else:
+            raise exceptions.InvalidConfiguration()
 
 
 class BaseV2ComputeAdminTest(BaseV2ComputeTest):
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 8f6ede9..8706566 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -68,7 +68,7 @@
         resp = {}
         resp['status'] = None
         self.assertRaises(lib_exc.NotFound, self.create_image_from_server,
-                          '!@#$%^&*()', name=name, meta=meta)
+                          '!@$%^&*()', name=name, meta=meta)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('ec176029-73dc-4037-8d72-2e4ff60cf538')
diff --git a/tempest/api/compute/keypairs/base.py b/tempest/api/compute/keypairs/base.py
index 15f231b..ebfb724 100644
--- a/tempest/api/compute/keypairs/base.py
+++ b/tempest/api/compute/keypairs/base.py
@@ -27,10 +27,12 @@
     def _delete_keypair(self, keypair_name):
         self.client.delete_keypair(keypair_name)
 
-    def _create_keypair(self, keypair_name, pub_key=None):
+    def _create_keypair(self, keypair_name, pub_key=None, keypair_type=None):
         kwargs = {'name': keypair_name}
         if pub_key:
             kwargs.update({'public_key': pub_key})
+        if keypair_type:
+            kwargs.update({'type': keypair_type})
         body = self.client.create_keypair(**kwargs)['keypair']
         self.addCleanup(self._delete_keypair, keypair_name)
         return body
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index d10bf14..be6f615 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -19,6 +19,8 @@
 
 
 class KeyPairsV2TestJSON(base.BaseKeypairTest):
+    max_microversion = '2.1'
+
     @test.idempotent_id('1d1dbedb-d7a0-432a-9d09-83f543c3c19b')
     def test_keypairs_create_list_delete(self):
         # Keypairs created should be available in the response list
diff --git a/tempest/api/compute/keypairs/test_keypairs_v22.py b/tempest/api/compute/keypairs/test_keypairs_v22.py
new file mode 100644
index 0000000..997ef9b
--- /dev/null
+++ b/tempest/api/compute/keypairs/test_keypairs_v22.py
@@ -0,0 +1,51 @@
+# Copyright 2016 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute.keypairs import test_keypairs
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class KeyPairsV22TestJSON(test_keypairs.KeyPairsV2TestJSON):
+    min_microversion = '2.2'
+    max_microversion = 'latest'
+
+    def _check_keypair_type(self, keypair, keypair_type):
+        if keypair_type is None:
+            keypair_type = 'ssh'
+        self.assertEqual(keypair_type, keypair['type'])
+
+    def _test_keypairs_create_list_show(self, keypair_type=None):
+        k_name = data_utils.rand_name('keypair')
+        keypair = self._create_keypair(k_name, keypair_type=keypair_type)
+        # Verify whether 'type' is present in keypair create response of
+        # version 2.2 and it is with default value 'ssh'.
+        self._check_keypair_type(keypair, keypair_type)
+        keypair_detail = self.client.show_keypair(k_name)['keypair']
+        self._check_keypair_type(keypair_detail, keypair_type)
+        fetched_list = self.client.list_keypairs()['keypairs']
+        for keypair in fetched_list:
+            # Verify whether 'type' is present in keypair list response of
+            # version 2.2 and it is with default value 'ssh'.
+            if keypair['keypair']['name'] == k_name:
+                self._check_keypair_type(keypair['keypair'], keypair_type)
+
+    @test.idempotent_id('8726fa85-7f98-4b20-af9e-f710a4f3391c')
+    def test_keypairsv22_create_list_show(self):
+        self._test_keypairs_create_list_show()
+
+    @test.idempotent_id('89d59d43-f735-441a-abcf-0601727f47b6')
+    def test_keypairsv22_create_list_show_with_type(self):
+        keypair_type = 'x509'
+        self._test_keypairs_create_list_show(keypair_type=keypair_type)
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index 73e852f..773bf23 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -31,7 +31,6 @@
     def setup_clients(cls):
         super(AbsoluteLimitsNegativeTestJSON, cls).setup_clients()
         cls.client = cls.limits_client
-        cls.server_client = cls.servers_client
 
     @test.attr(type=['negative'])
     @test.idempotent_id('215cd465-d8ae-49c9-bf33-9c911913a5c8')
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 9aa59f7..38c294b 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -158,7 +158,9 @@
             to_port=to_port2)['security_group_rule']
         rule2_id = rule['id']
         # Delete the Security Group rule2 at the end of this method
-        self.addCleanup(self.client.delete_security_group_rule, rule2_id)
+        self.addCleanup(
+            self.security_group_rules_client.delete_security_group_rule,
+            rule2_id)
 
         # Get rules of the created Security Group
         rules = self.security_groups_client.show_security_group(
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index a6ccdd3..be79163 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -45,6 +45,7 @@
     def setup_clients(cls):
         super(AttachInterfacesTestJSON, cls).setup_clients()
         cls.client = cls.os.interfaces_client
+        cls.ports_client = cls.os.ports_client
 
     def wait_for_interface_status(self, server, port_id, status):
         """Waits for an interface to reach a given status."""
@@ -108,6 +109,18 @@
         self._check_interface(iface, network_id=network_id)
         return iface
 
+    def _test_create_interface_by_port_id(self, server, ifs):
+        network_id = ifs[0]['net_id']
+        port = self.ports_client.create_port(network_id=network_id)
+        port_id = port['port']['id']
+        self.addCleanup(self.ports_client.delete_port, port_id)
+        iface = self.client.create_interface(
+            server['id'], port_id=port_id)['interfaceAttachment']
+        iface = self.wait_for_interface_status(
+            server['id'], iface['port_id'], 'ACTIVE')
+        self._check_interface(iface, port_id=port_id)
+        return iface
+
     def _test_show_interface(self, server, ifs):
         iface = ifs[0]
         _iface = self.client.show_interface(
@@ -167,6 +180,9 @@
         iface = self._test_create_interface_by_network_id(server, ifs)
         ifs.append(iface)
 
+        iface = self._test_create_interface_by_port_id(server, ifs)
+        ifs.append(iface)
+
         _ifs = (self.client.list_interfaces(server['id'])
                 ['interfaceAttachments'])
         self._compare_iface_list(ifs, _ifs)
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index e1c22e5..f719bfc 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -50,6 +50,7 @@
         cls.accessIPv4 = '1.1.1.1'
         cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
         cls.name = data_utils.rand_name('server')
+        cls.password = data_utils.rand_password()
         disk_config = cls.disk_config
         cls.server_initial = cls.create_test_server(
             validatable=True,
@@ -58,8 +59,8 @@
             metadata=cls.meta,
             accessIPv4=cls.accessIPv4,
             accessIPv6=cls.accessIPv6,
-            disk_config=disk_config)
-        cls.password = cls.server_initial['adminPass']
+            disk_config=disk_config,
+            adminPass=cls.password)
         cls.server = (cls.client.show_server(cls.server_initial['id'])
                       ['server'])
 
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index d1ec064..37f322f 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import decorators
 from tempest_lib import exceptions as lib_exc
 
 from tempest.api.compute import base
@@ -290,6 +291,7 @@
         self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
+    @decorators.skip_because(bug="1540645")
     @test.idempotent_id('a905e287-c35e-42f2-b132-d02b09f3654a')
     def test_list_servers_filtered_by_ip_regex(self):
         # Filter servers by regex ip
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index d7f0d75..66e85a6 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -172,11 +172,16 @@
         self.assertEqual(new_name, server['name'])
 
         if CONF.validation.run_validation:
-            # TODO(jlanoux) add authentication with the provided password
+            # Authentication is attempted in the following order of priority:
+            # 1.The key passed in, if one was passed in.
+            # 2.Any key we can find through an SSH agent (if allowed).
+            # 3.Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in
+            #   ~/.ssh/ (if allowed).
+            # 4.Plain username/password auth, if a password was given.
             linux_client = remote_client.RemoteClient(
                 self.get_server_ip(rebuilt_server),
                 self.ssh_user,
-                self.password,
+                password,
                 self.validation_resources['keypair']['private_key'])
             linux_client.validate_authentication()
 
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index c23b365..e32f6b0 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest_lib import decorators
-
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import test
@@ -81,13 +79,6 @@
         policy = ['anti-affinity']
         self._create_delete_server_group(policy)
 
-    @decorators.skip_because(bug="1324348")
-    @test.idempotent_id('6d9bae05-eb32-425d-a673-e14e1b1c6306')
-    def test_create_delete_server_group_with_multiple_policies(self):
-        # Create and Delete the server-group with multiple policies
-        policies = ['affinity', 'affinity']
-        self._create_delete_server_group(policies)
-
     @test.idempotent_id('154dc5a4-a2fe-44b5-b99e-f15806a4a113')
     def test_create_delete_multiple_server_groups_with_same_name_policy(self):
         # Create and Delete the server-groups with same name and same policy
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index c948f8c..dad8e90 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 import base64
+from tempest_lib.common.utils import data_utils
 from tempest_lib import exceptions as lib_exc
 
 from tempest.api.compute import base
@@ -55,14 +56,16 @@
         file_path = '/test.txt'
         personality = [{'path': file_path,
                         'contents': base64.b64encode(file_contents)}]
+        password = data_utils.rand_password()
         created_server = self.create_test_server(personality=personality,
+                                                 adminPass=password,
                                                  wait_until='ACTIVE',
                                                  validatable=True)
         server = self.client.show_server(created_server['id'])['server']
         if CONF.validation.run_validation:
             linux_client = remote_client.RemoteClient(
                 self.get_server_ip(server),
-                self.ssh_user, created_server['adminPass'],
+                self.ssh_user, password,
                 self.validation_resources['keypair']['private_key'])
             self.assertEqual(file_contents,
                              linux_client.exec_command(
@@ -117,14 +120,16 @@
                 'path': path,
                 'contents': base64.b64encode(file_contents),
             })
+        password = data_utils.rand_password()
         created_server = self.create_test_server(personality=person,
+                                                 adminPass=password,
                                                  wait_until='ACTIVE',
                                                  validatable=True)
         server = self.client.show_server(created_server['id'])['server']
         if CONF.validation.run_validation:
             linux_client = remote_client.RemoteClient(
                 self.get_server_ip(server),
-                self.ssh_user, created_server['adminPass'],
+                self.ssh_user, password,
                 self.validation_resources['keypair']['private_key'])
             for i in person:
                 self.assertEqual(base64.b64decode(i['contents']),
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 2296980..12b824f 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -52,10 +52,11 @@
             name=cls.sg_name, description=cls.sg_desc)['security_group']
         cls.sg_id = cls.sg['id']
 
+        cls.password = data_utils.rand_password()
         # Server for positive tests
-        server = cls.create_test_server(wait_until='BUILD')
+        server = cls.create_test_server(adminPass=cls.password,
+                                        wait_until='BUILD')
         cls.server_id = server['id']
-        cls.password = server['adminPass']
         waiters.wait_for_server_status(cls.servers_client, cls.server_id,
                                        'ACTIVE')
 
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 65ad2f5..5afb4d1 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -43,14 +43,15 @@
     def resource_setup(cls):
         super(ServerRescueNegativeTestJSON, cls).resource_setup()
         cls.device = CONF.compute.volume_device_name
-
+        cls.password = data_utils.rand_password()
+        rescue_password = data_utils.rand_password()
         # Server for negative tests
-        server = cls.create_test_server(wait_until='BUILD')
-        resc_server = cls.create_test_server(wait_until='ACTIVE')
+        server = cls.create_test_server(adminPass=cls.password,
+                                        wait_until='BUILD')
+        resc_server = cls.create_test_server(adminPass=rescue_password,
+                                             wait_until='ACTIVE')
         cls.server_id = server['id']
-        cls.password = server['adminPass']
         cls.rescue_id = resc_server['id']
-        rescue_password = resc_server['adminPass']
 
         cls.servers_client.rescue_server(
             cls.rescue_id, adminPass=rescue_password)
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index 8e2fbf1..2f79d47 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -13,11 +13,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest.common import waiters
+from tempest import config
 from tempest import test
 
+CONF = config.CONF
+
 
 class ServersTestJSON(base.BaseV2ComputeTest):
 
@@ -31,6 +36,9 @@
         super(ServersTestJSON, self).tearDown()
 
     @test.idempotent_id('b92d5ec7-b1dd-44a2-87e4-45e888c46ef0')
+    @testtools.skipUnless(CONF.compute_feature_enabled.
+                          enable_instance_password,
+                          'Instance password not available.')
     def test_create_server_with_admin_password(self):
         # If an admin password is provided on server creation, the server's
         # root password should be set to that password.
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 468c79a..01a8e58 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -63,11 +63,11 @@
 
     def _create_and_attach(self):
         # Start a server and wait for it to become ready
-        admin_pass = self.image_ssh_password
+        self.admin_pass = self.image_ssh_password
         self.server = self.create_test_server(
             validatable=True,
             wait_until='ACTIVE',
-            adminPass=admin_pass)
+            adminPass=self.admin_pass)
 
         # Record addresses so that we can ssh later
         self.server['addresses'] = self.servers_client.list_addresses(
@@ -108,7 +108,7 @@
         linux_client = remote_client.RemoteClient(
             self.get_server_ip(self.server),
             self.image_ssh_user,
-            self.server['adminPass'],
+            self.admin_pass,
             self.validation_resources['keypair']['private_key'])
 
         partitions = linux_client.get_partitions()
@@ -127,7 +127,7 @@
         linux_client = remote_client.RemoteClient(
             self.get_server_ip(self.server),
             self.image_ssh_user,
-            self.server['adminPass'],
+            self.admin_pass,
             self.validation_resources['keypair']['private_key'])
 
         partitions = linux_client.get_partitions()
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index 4e88f65..8424db0 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -13,6 +13,7 @@
 #    under the License.
 
 from collections import OrderedDict
+import copy
 
 import six
 from tempest_lib import exceptions as lib_exc
@@ -27,42 +28,93 @@
 """Default templates.
 There should always be at least a master1 and a worker1 node
 group template."""
-DEFAULT_TEMPLATES = {
-    'vanilla': OrderedDict([
-        ('2.6.0', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['namenode', 'resourcemanager',
-                                       'hiveserver']
+BASE_VANILLA_DESC = {
+    'NODES': {
+        'master1': {
+            'count': 1,
+            'node_processes': ['namenode', 'resourcemanager',
+                               'hiveserver']
+        },
+        'master2': {
+            'count': 1,
+            'node_processes': ['oozie', 'historyserver',
+                               'secondarynamenode']
+        },
+        'worker1': {
+            'count': 1,
+            'node_processes': ['datanode', 'nodemanager'],
+            'node_configs': {
+                'MapReduce': {
+                    'yarn.app.mapreduce.am.resource.mb': 256,
+                    'yarn.app.mapreduce.am.command-opts': '-Xmx256m'
                 },
-                'master2': {
-                    'count': 1,
-                    'node_processes': ['oozie', 'historyserver',
-                                       'secondarynamenode']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['datanode', 'nodemanager'],
-                    'node_configs': {
-                        'MapReduce': {
-                            'yarn.app.mapreduce.am.resource.mb': 256,
-                            'yarn.app.mapreduce.am.command-opts': '-Xmx256m'
-                        },
-                        'YARN': {
-                            'yarn.scheduler.minimum-allocation-mb': 256,
-                            'yarn.scheduler.maximum-allocation-mb': 1024,
-                            'yarn.nodemanager.vmem-check-enabled': False
-                        }
-                    }
-                }
-            },
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs.replication': 1
+                'YARN': {
+                    'yarn.scheduler.minimum-allocation-mb': 256,
+                    'yarn.scheduler.maximum-allocation-mb': 1024,
+                    'yarn.nodemanager.vmem-check-enabled': False
                 }
             }
-        }),
+        }
+    },
+    'cluster_configs': {
+        'HDFS': {
+            'dfs.replication': 1
+        }
+    }
+}
+
+BASE_SPARK_DESC = {
+    'NODES': {
+        'master1': {
+            'count': 1,
+            'node_processes': ['namenode', 'master']
+        },
+        'worker1': {
+            'count': 1,
+            'node_processes': ['datanode', 'slave']
+        }
+    },
+    'cluster_configs': {
+        'HDFS': {
+            'dfs.replication': 1
+        }
+    }
+}
+
+BASE_CDH_DESC = {
+    'NODES': {
+        'master1': {
+            'count': 1,
+            'node_processes': ['CLOUDERA_MANAGER']
+        },
+        'master2': {
+            'count': 1,
+            'node_processes': ['HDFS_NAMENODE',
+                               'YARN_RESOURCEMANAGER']
+        },
+        'master3': {
+            'count': 1,
+            'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
+                               'HDFS_SECONDARYNAMENODE',
+                               'HIVE_METASTORE', 'HIVE_SERVER2']
+        },
+        'worker1': {
+            'count': 1,
+            'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
+        }
+    },
+    'cluster_configs': {
+        'HDFS': {
+            'dfs_replication': 1
+        }
+    }
+}
+
+
+DEFAULT_TEMPLATES = {
+    'vanilla': OrderedDict([
+        ('2.6.0', copy.deepcopy(BASE_VANILLA_DESC)),
+        ('2.7.1', copy.deepcopy(BASE_VANILLA_DESC)),
         ('1.2.1', {
             'NODES': {
                 'master1': {
@@ -123,102 +175,13 @@
         })
     ]),
     'spark': OrderedDict([
-        ('1.0.0', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['namenode', 'master']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['datanode', 'slave']
-                }
-            },
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs.replication': 1
-                }
-            }
-        })
+        ('1.0.0', copy.deepcopy(BASE_SPARK_DESC)),
+        ('1.3.1', copy.deepcopy(BASE_SPARK_DESC))
     ]),
     'cdh': OrderedDict([
-        ('5.3.0', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['CLOUDERA_MANAGER']
-                },
-                'master2': {
-                    'count': 1,
-                    'node_processes': ['HDFS_NAMENODE',
-                                       'YARN_RESOURCEMANAGER']
-                },
-                'master3': {
-                    'count': 1,
-                    'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
-                                       'HDFS_SECONDARYNAMENODE',
-                                       'HIVE_METASTORE', 'HIVE_SERVER2']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
-                }
-            },
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs_replication': 1
-                }
-            }
-        }),
-        ('5', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['CLOUDERA_MANAGER']
-                },
-                'master2': {
-                    'count': 1,
-                    'node_processes': ['HDFS_NAMENODE',
-                                       'YARN_RESOURCEMANAGER']
-                },
-                'master3': {
-                    'count': 1,
-                    'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
-                                       'HDFS_SECONDARYNAMENODE',
-                                       'HIVE_METASTORE', 'HIVE_SERVER2']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
-                }
-            },
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs_replication': 1
-                }
-            }
-        })
-    ]),
-    'mapr': OrderedDict([
-        ('4.0.1.mrv2', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['CLDB', 'FileServer', 'ZooKeeper',
-                                       'NodeManager', 'ResourceManager',
-                                       'HistoryServer', 'Oozie']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['FileServer', 'NodeManager', 'Pig']
-                }
-            },
-            'cluster_configs': {
-                'Hive': {
-                    'Hive Version': '0.13',
-                }
-            }
-        })
+        ('5.4.0', copy.deepcopy(BASE_CDH_DESC)),
+        ('5.3.0', copy.deepcopy(BASE_CDH_DESC)),
+        ('5', copy.deepcopy(BASE_CDH_DESC))
     ]),
 }
 
diff --git a/tempest/api/identity/admin/v2/test_endpoints.py b/tempest/api/identity/admin/v2/test_endpoints.py
index bff4f91..df75d0a 100644
--- a/tempest/api/identity/admin/v2/test_endpoints.py
+++ b/tempest/api/identity/admin/v2/test_endpoints.py
@@ -27,7 +27,7 @@
         s_name = data_utils.rand_name('service')
         s_type = data_utils.rand_name('type')
         s_description = data_utils.rand_name('description')
-        cls.service_data = cls.client.create_service(
+        cls.service_data = cls.services_client.create_service(
             s_name, s_type, description=s_description)['OS-KSADM:service']
         cls.service_id = cls.service_data['id']
         cls.service_ids.append(cls.service_id)
@@ -36,11 +36,12 @@
         for i in range(2):
             region = data_utils.rand_name('region')
             url = data_utils.rand_url()
-            endpoint = cls.client.create_endpoint(cls.service_id,
-                                                  region,
-                                                  publicurl=url,
-                                                  adminurl=url,
-                                                  internalurl=url)['endpoint']
+            endpoint = cls.endpoints_client.create_endpoint(
+                cls.service_id,
+                region,
+                publicurl=url,
+                adminurl=url,
+                internalurl=url)['endpoint']
             # list_endpoints() will return 'enabled' field
             endpoint['enabled'] = True
             cls.setup_endpoints.append(endpoint)
@@ -48,15 +49,15 @@
     @classmethod
     def resource_cleanup(cls):
         for e in cls.setup_endpoints:
-            cls.client.delete_endpoint(e['id'])
+            cls.endpoints_client.delete_endpoint(e['id'])
         for s in cls.service_ids:
-            cls.client.delete_service(s)
+            cls.services_client.delete_service(s)
         super(EndPointsTestJSON, cls).resource_cleanup()
 
     @test.idempotent_id('11f590eb-59d8-4067-8b2b-980c7f387f51')
     def test_list_endpoints(self):
         # Get a list of endpoints
-        fetched_endpoints = self.client.list_endpoints()['endpoints']
+        fetched_endpoints = self.endpoints_client.list_endpoints()['endpoints']
         # Asserting LIST endpoints
         missing_endpoints =\
             [e for e in self.setup_endpoints if e not in fetched_endpoints]
@@ -68,22 +69,23 @@
     def test_create_list_delete_endpoint(self):
         region = data_utils.rand_name('region')
         url = data_utils.rand_url()
-        endpoint = self.client.create_endpoint(self.service_id,
-                                               region,
-                                               publicurl=url,
-                                               adminurl=url,
-                                               internalurl=url)['endpoint']
+        endpoint = self.endpoints_client.create_endpoint(
+            self.service_id,
+            region,
+            publicurl=url,
+            adminurl=url,
+            internalurl=url)['endpoint']
         # Asserting Create Endpoint response body
         self.assertIn('id', endpoint)
         self.assertEqual(region, endpoint['region'])
         self.assertEqual(url, endpoint['publicurl'])
         # Checking if created endpoint is present in the list of endpoints
-        fetched_endpoints = self.client.list_endpoints()['endpoints']
+        fetched_endpoints = self.endpoints_client.list_endpoints()['endpoints']
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
         self.assertIn(endpoint['id'], fetched_endpoints_id)
         # Deleting the endpoint created in this method
-        self.client.delete_endpoint(endpoint['id'])
+        self.endpoints_client.delete_endpoint(endpoint['id'])
         # Checking whether endpoint is deleted successfully
-        fetched_endpoints = self.client.list_endpoints()['endpoints']
+        fetched_endpoints = self.endpoints_client.list_endpoints()['endpoints']
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
         self.assertNotIn(endpoint['id'], fetched_endpoints_id)
diff --git a/tempest/api/identity/admin/v2/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
index 3f3d16e..5847129 100644
--- a/tempest/api/identity/admin/v2/test_roles.py
+++ b/tempest/api/identity/admin/v2/test_roles.py
@@ -33,9 +33,9 @@
     def _get_role_params(self):
         self.data.setup_test_user()
         self.data.setup_test_role()
-        user = self.get_user_by_name(self.data.test_user)
-        tenant = self.get_tenant_by_name(self.data.test_tenant)
-        role = self.get_role_by_name(self.data.test_role)
+        user = self.get_user_by_name(self.data.user['name'])
+        tenant = self.get_tenant_by_name(self.data.tenant['name'])
+        role = self.get_role_by_name(self.data.role['name'])
         return (user, tenant, role)
 
     def assert_role_in_role_list(self, role, roles):
diff --git a/tempest/api/identity/admin/v2/test_roles_negative.py b/tempest/api/identity/admin/v2/test_roles_negative.py
index c9af7c6..23a1958 100644
--- a/tempest/api/identity/admin/v2/test_roles_negative.py
+++ b/tempest/api/identity/admin/v2/test_roles_negative.py
@@ -27,9 +27,9 @@
     def _get_role_params(self):
         self.data.setup_test_user()
         self.data.setup_test_role()
-        user = self.get_user_by_name(self.data.test_user)
-        tenant = self.get_tenant_by_name(self.data.test_tenant)
-        role = self.get_role_by_name(self.data.test_role)
+        user = self.get_user_by_name(self.data.user['name'])
+        tenant = self.get_tenant_by_name(self.data.tenant['name'])
+        role = self.get_role_by_name(self.data.role['name'])
         return (user, tenant, role)
 
     @test.attr(type=['negative'])
diff --git a/tempest/api/identity/admin/v2/test_services.py b/tempest/api/identity/admin/v2/test_services.py
index 04e15d2..5685922 100644
--- a/tempest/api/identity/admin/v2/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -25,9 +25,9 @@
 
     def _del_service(self, service_id):
         # Deleting the service created in this method
-        self.client.delete_service(service_id)
+        self.services_client.delete_service(service_id)
         # Checking whether service is deleted successfully
-        self.assertRaises(lib_exc.NotFound, self.client.show_service,
+        self.assertRaises(lib_exc.NotFound, self.services_client.show_service,
                           service_id)
 
     @test.idempotent_id('84521085-c6e6-491c-9a08-ec9f70f90110')
@@ -37,7 +37,7 @@
         name = data_utils.rand_name('service')
         type = data_utils.rand_name('type')
         description = data_utils.rand_name('description')
-        service_data = self.client.create_service(
+        service_data = self.services_client.create_service(
             name, type, description=description)['OS-KSADM:service']
         self.assertFalse(service_data['id'] is None)
         self.addCleanup(self._del_service, service_data['id'])
@@ -50,8 +50,9 @@
         self.assertIn('description', service_data)
         self.assertEqual(description, service_data['description'])
         # Get service
-        fetched_service = (self.client.show_service(service_data['id'])
-                           ['OS-KSADM:service'])
+        fetched_service = (
+            self.services_client.show_service(service_data['id'])
+            ['OS-KSADM:service'])
         # verifying the existence of service created
         self.assertIn('id', fetched_service)
         self.assertEqual(fetched_service['id'], service_data['id'])
@@ -68,7 +69,8 @@
         # Create a service only with name and type
         name = data_utils.rand_name('service')
         type = data_utils.rand_name('type')
-        service = self.client.create_service(name, type)['OS-KSADM:service']
+        service = self.services_client.create_service(name,
+                                                      type)['OS-KSADM:service']
         self.assertIn('id', service)
         self.addCleanup(self._del_service, service['id'])
         self.assertIn('name', service)
@@ -85,17 +87,17 @@
             name = data_utils.rand_name('service')
             type = data_utils.rand_name('type')
             description = data_utils.rand_name('description')
-            service = self.client.create_service(
+            service = self.services_client.create_service(
                 name, type, description=description)['OS-KSADM:service']
             services.append(service)
         service_ids = map(lambda x: x['id'], services)
 
         def delete_services():
             for service_id in service_ids:
-                self.client.delete_service(service_id)
+                self.services_client.delete_service(service_id)
 
         self.addCleanup(delete_services)
         # List and Verify Services
-        body = self.client.list_services()['OS-KSADM:services']
+        body = self.services_client.list_services()['OS-KSADM:services']
         found = [serv for serv in body if serv['id'] in service_ids]
         self.assertEqual(len(found), len(services), 'Services not found')
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 4497575..60c4e97 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -95,27 +95,29 @@
         # Valid user's token is authenticated
         self.data.setup_test_user()
         # Get a token
-        self.token_client.auth(self.data.test_user, self.data.test_password,
-                               self.data.test_tenant)
+        self.token_client.auth(self.data.user['name'],
+                               self.data.user_password,
+                               self.data.tenant['name'])
         # Re-auth
-        self.token_client.auth(self.data.test_user,
-                               self.data.test_password,
-                               self.data.test_tenant)
+        self.token_client.auth(self.data.user['name'],
+                               self.data.user_password,
+                               self.data.tenant['name'])
 
     @test.idempotent_id('5d1fa498-4c2d-4732-a8fe-2b054598cfdd')
     def test_authentication_request_without_token(self):
         # Request for token authentication with a valid token in header
         self.data.setup_test_user()
-        self.token_client.auth(self.data.test_user, self.data.test_password,
-                               self.data.test_tenant)
+        self.token_client.auth(self.data.user['name'],
+                               self.data.user_password,
+                               self.data.tenant['name'])
         # Get the token of the current client
         token = self.client.auth_provider.get_token()
         # Delete the token from database
         self.client.delete_token(token)
         # Re-auth
-        self.token_client.auth(self.data.test_user,
-                               self.data.test_password,
-                               self.data.test_tenant)
+        self.token_client.auth(self.data.user['name'],
+                               self.data.user_password,
+                               self.data.tenant['name'])
         self.client.auth_provider.clear_auth()
 
     @test.idempotent_id('a149c02e-e5e0-4b89-809e-7e8faf33ccda')
@@ -124,8 +126,8 @@
         self.data.setup_test_user()
         users = self.users_client.list_users()['users']
         self.assertThat([u['name'] for u in users],
-                        matchers.Contains(self.data.test_user),
-                        "Could not find %s" % self.data.test_user)
+                        matchers.Contains(self.data.user['name']),
+                        "Could not find %s" % self.data.user['name'])
 
     @test.idempotent_id('6e317209-383a-4bed-9f10-075b7c82c79a')
     def test_list_users_for_tenant(self):
@@ -164,9 +166,9 @@
         # Return list of users on tenant when roles are assigned to users
         self.data.setup_test_user()
         self.data.setup_test_role()
-        user = self.get_user_by_name(self.data.test_user)
-        tenant = self.get_tenant_by_name(self.data.test_tenant)
-        role = self.get_role_by_name(self.data.test_role)
+        user = self.get_user_by_name(self.data.user['name'])
+        tenant = self.get_tenant_by_name(self.data.tenant['name'])
+        role = self.get_role_by_name(self.data.role['name'])
         # Assigning roles to two users
         user_ids = list()
         fetched_user_ids = list()
@@ -208,6 +210,6 @@
 
         # Validate the updated password
         # Get a token
-        body = self.token_client.auth(self.data.test_user, new_pass,
-                                      self.data.test_tenant)
+        body = self.token_client.auth(self.data.user['name'], new_pass,
+                                      self.data.tenant['name'])
         self.assertTrue('id' in body['token'])
diff --git a/tempest/api/identity/admin/v2/test_users_negative.py b/tempest/api/identity/admin/v2/test_users_negative.py
index c5248fd..0a5d0c9 100644
--- a/tempest/api/identity/admin/v2/test_users_negative.py
+++ b/tempest/api/identity/admin/v2/test_users_negative.py
@@ -66,8 +66,8 @@
         # Duplicate user should not be created
         self.data.setup_test_user()
         self.assertRaises(lib_exc.Conflict, self.users_client.create_user,
-                          self.data.test_user, self.data.test_password,
-                          self.data.tenant['id'], self.data.test_email)
+                          self.data.user['name'], self.data.user_password,
+                          self.data.tenant['id'], self.data.user['email'])
 
     @test.attr(type=['negative'])
     @test.idempotent_id('0132cc22-7c4f-42e1-9e50-ac6aad31d59a')
@@ -173,22 +173,22 @@
     def test_authentication_for_disabled_user(self):
         # Disabled user's token should not get authenticated
         self.data.setup_test_user()
-        self.disable_user(self.data.test_user)
+        self.disable_user(self.data.user['name'])
         self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
-                          self.data.test_tenant)
+                          self.data.user['name'],
+                          self.data.user_password,
+                          self.data.tenant['name'])
 
     @test.attr(type=['negative'])
     @test.idempotent_id('440a7a8d-9328-4b7b-83e0-d717010495e4')
     def test_authentication_when_tenant_is_disabled(self):
         # User's token for a disabled tenant should not be authenticated
         self.data.setup_test_user()
-        self.disable_tenant(self.data.test_tenant)
+        self.disable_tenant(self.data.tenant['name'])
         self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
-                          self.data.test_tenant)
+                          self.data.user['name'],
+                          self.data.user_password,
+                          self.data.tenant['name'])
 
     @test.attr(type=['negative'])
     @test.idempotent_id('921f1ad6-7907-40b8-853f-637e7ee52178')
@@ -196,8 +196,8 @@
         # User's token for an invalid tenant should not be authenticated
         self.data.setup_test_user()
         self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
+                          self.data.user['name'],
+                          self.data.user_password,
                           'junktenant1234')
 
     @test.attr(type=['negative'])
@@ -206,8 +206,8 @@
         # Non-existent user's token should not get authenticated
         self.data.setup_test_user()
         self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
-                          'junkuser123', self.data.test_password,
-                          self.data.test_tenant)
+                          'junkuser123', self.data.user_password,
+                          self.data.tenant['name'])
 
     @test.attr(type=['negative'])
     @test.idempotent_id('d5308b33-3574-43c3-8d87-1c090c5e1eca')
@@ -215,8 +215,8 @@
         # User's token with invalid password should not be authenticated
         self.data.setup_test_user()
         self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
-                          self.data.test_user, 'junkpass1234',
-                          self.data.test_tenant)
+                          self.data.user['name'], 'junkpass1234',
+                          self.data.tenant['name'])
 
     @test.attr(type=['negative'])
     @test.idempotent_id('284192ce-fb7c-4909-a63b-9a502e0ddd11')
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index b81bff7..7c2e8e0 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -31,20 +31,20 @@
         u_email = '%s@testmail.tm' % u_name
         u_password = data_utils.rand_password()
         for i in range(2):
-            cls.project = cls.client.create_project(
+            cls.project = cls.projects_client.create_project(
                 data_utils.rand_name('project'),
                 description=data_utils.rand_name('project-desc'))['project']
             cls.projects.append(cls.project['id'])
 
-        cls.user_body = cls.client.create_user(
+        cls.user_body = cls.users_client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email, project_id=cls.projects[0])['user']
 
     @classmethod
     def resource_cleanup(cls):
-        cls.client.delete_user(cls.user_body['id'])
+        cls.users_client.delete_user(cls.user_body['id'])
         for p in cls.projects:
-            cls.client.delete_project(p)
+            cls.projects_client.delete_project(p)
         super(CredentialsTestJSON, cls).resource_cleanup()
 
     def _delete_credential(self, cred_id):
diff --git a/tempest/api/identity/admin/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index 53861ca..3dc3cb6 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -45,10 +45,10 @@
 
         # create a project in the domain
         proj_name = data_utils.rand_name('proj')
-        proj_body = self.client.create_project(proj_name,
-                                               domain_id=dom_id)['project']
+        proj_body = self.projects_client.create_project(
+            proj_name, domain_id=dom_id)['project']
         proj_id = proj_body['id']
-        self.addCleanup(self.client.delete_project, proj_id)
+        self.addCleanup(self.projects_client.delete_project, proj_id)
         self.assertEqual(proj_body['domain_id'], dom_id,
                          "project " + proj_name +
                          "doesn't have domain id " + dom_id)
@@ -56,11 +56,13 @@
         # create a user in the domain, with the previous project as his
         # default project
         user_name = data_utils.rand_name('user')
-        user_body = self.client.create_user(user_name, password=user_name,
-                                            domain_id=dom_id,
-                                            default_project_id=proj_id)['user']
+        user_body = self.users_client.create_user(
+            user_name,
+            password=user_name,
+            domain_id=dom_id,
+            default_project_id=proj_id)['user']
         user_id = user_body['id']
-        self.addCleanup(self.client.delete_user, user_id)
+        self.addCleanup(self.users_client.delete_user, user_id)
         self.assertEqual(user_body['domain_id'], dom_id,
                          "user " + user_name +
                          "doesn't have domain id " + dom_id)
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 15bea28..1729dc9 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -85,7 +85,7 @@
         self.assertEqual(new_desc, updated_domain['description'])
         self.assertEqual(True, updated_domain['enabled'])
 
-        fetched_domain = self.client.get_domain(domain['id'])['domain']
+        fetched_domain = self.client.show_domain(domain['id'])['domain']
         self.assertEqual(new_name, fetched_domain['name'])
         self.assertEqual(new_desc, fetched_domain['description'])
         self.assertEqual(True, fetched_domain['enabled'])
@@ -124,6 +124,6 @@
     @test.attr(type='smoke')
     @test.idempotent_id('17a5de24-e6a0-4e4a-a9ee-d85b6e5612b5')
     def test_default_domain_exists(self):
-        domain = self.client.get_domain(self.domain_id)['domain']
+        domain = self.client.show_domain(self.domain_id)['domain']
 
         self.assertTrue(domain['enabled'])
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 2ac832e..50cf258 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -71,7 +71,7 @@
                          ', '.join(str(e) for e in missing_endpoints))
 
     @test.idempotent_id('0e2446d2-c1fd-461b-a729-b9e73e3e3b37')
-    def test_create_list_delete_endpoint(self):
+    def test_create_list_show_delete_endpoint(self):
         region = data_utils.rand_name('region')
         url = data_utils.rand_url()
         interface = 'public'
@@ -79,16 +79,32 @@
                                                interface=interface,
                                                url=url, region=region,
                                                enabled=True)['endpoint']
+
+        self.setup_endpoints.append(endpoint)
         # Asserting Create Endpoint response body
         self.assertIn('id', endpoint)
         self.assertEqual(region, endpoint['region'])
         self.assertEqual(url, endpoint['url'])
+
         # Checking if created endpoint is present in the list of endpoints
         fetched_endpoints = self.client.list_endpoints()['endpoints']
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
         self.assertIn(endpoint['id'], fetched_endpoints_id)
+
+        # Show endpoint
+        fetched_endpoint = (
+            self.client.show_endpoint(endpoint['id'])['endpoint'])
+        # Asserting if the attributes of endpoint are the same
+        self.assertEqual(self.service_id, fetched_endpoint['service_id'])
+        self.assertEqual(interface, fetched_endpoint['interface'])
+        self.assertEqual(url, fetched_endpoint['url'])
+        self.assertEqual(region, fetched_endpoint['region'])
+        self.assertEqual(True, fetched_endpoint['enabled'])
+
         # Deleting the endpoint created in this method
         self.client.delete_endpoint(endpoint['id'])
+        self.setup_endpoints.remove(endpoint)
+
         # Checking whether endpoint is deleted successfully
         fetched_endpoints = self.client.list_endpoints()['endpoints']
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 21fc62a..010e4a0 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -68,16 +68,18 @@
         for i in range(3):
             name = data_utils.rand_name('User')
             password = data_utils.rand_password()
-            user = self.client.create_user(name, password)['user']
+            user = self.users_client.create_user(name, password)['user']
             users.append(user)
-            self.addCleanup(self.client.delete_user, user['id'])
+            self.addCleanup(self.users_client.delete_user, user['id'])
             self.groups_client.add_group_user(group['id'], user['id'])
 
         # list users in group
         group_users = self.groups_client.list_group_users(group['id'])['users']
         self.assertEqual(sorted(users), sorted(group_users))
-        # delete user in group
+        # check and delete user in group
         for user in users:
+            self.groups_client.check_group_user_existence(
+                group['id'], user['id'])
             self.groups_client.delete_group_user(group['id'], user['id'])
         group_users = self.groups_client.list_group_users(group['id'])['users']
         self.assertEqual(len(group_users), 0)
@@ -85,9 +87,9 @@
     @test.idempotent_id('64573281-d26a-4a52-b899-503cb0f4e4ec')
     def test_list_user_groups(self):
         # create a user
-        user = self.client.create_user(
+        user = self.users_client.create_user(
             data_utils.rand_name('User'), data_utils.rand_password())['user']
-        self.addCleanup(self.client.delete_user, user['id'])
+        self.addCleanup(self.users_client.delete_user, user['id'])
         # create two groups, and add user into them
         groups = []
         for i in range(2):
@@ -97,7 +99,7 @@
             self.addCleanup(self.groups_client.delete_group, group['id'])
             self.groups_client.add_group_user(group['id'], user['id'])
         # list groups which user belongs to
-        user_groups = self.client.list_user_groups(user['id'])['groups']
+        user_groups = self.users_client.list_user_groups(user['id'])['groups']
         self.assertEqual(sorted(groups), sorted(user_groups))
         self.assertEqual(2, len(user_groups))
 
diff --git a/tempest/api/identity/admin/v3/test_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
index 5185fea..928437c 100644
--- a/tempest/api/identity/admin/v3/test_list_projects.py
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -27,25 +27,25 @@
         cls.data.setup_test_domain()
         # Create project with domain
         cls.p1_name = data_utils.rand_name('project')
-        cls.p1 = cls.client.create_project(
+        cls.p1 = cls.projects_client.create_project(
             cls.p1_name, enabled=False,
             domain_id=cls.data.domain['id'])['project']
         cls.data.projects.append(cls.p1)
         cls.project_ids.append(cls.p1['id'])
         # Create default project
         p2_name = data_utils.rand_name('project')
-        cls.p2 = cls.client.create_project(p2_name)['project']
+        cls.p2 = cls.projects_client.create_project(p2_name)['project']
         cls.data.projects.append(cls.p2)
         cls.project_ids.append(cls.p2['id'])
 
     @test.idempotent_id('1d830662-22ad-427c-8c3e-4ec854b0af44')
     def test_projects_list(self):
         # List projects
-        list_projects = self.client.list_projects()['projects']
+        list_projects = self.projects_client.list_projects()['projects']
 
         for p in self.project_ids:
-            get_project = self.client.get_project(p)['project']
-            self.assertIn(get_project, list_projects)
+            show_project = self.projects_client.show_project(p)['project']
+            self.assertIn(show_project, list_projects)
 
     @test.idempotent_id('fab13f3c-f6a6-4b9f-829b-d32fd44fdf10')
     def test_list_projects_with_domains(self):
@@ -64,6 +64,6 @@
         self._list_projects_with_params({'name': self.p1_name}, 'name')
 
     def _list_projects_with_params(self, params, key):
-        body = self.client.list_projects(params)['projects']
+        body = self.projects_client.list_projects(params)['projects']
         self.assertIn(self.p1[key], map(lambda x: x[key], body))
         self.assertNotIn(self.p2[key], map(lambda x: x[key], body))
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index ca91ce5..5b27ab1 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -25,7 +25,7 @@
         # assert the response based on expected and not_expected
         # expected: user expected in the list response
         # not_expected: user, which should not be present in list response
-        body = self.client.list_users(params)['users']
+        body = self.users_client.list_users(params)['users']
         self.assertIn(expected[key], map(lambda x: x[key], body))
         self.assertNotIn(not_expected[key],
                          map(lambda x: x[key], body))
@@ -39,16 +39,16 @@
         cls.data.setup_test_domain()
         # Create user with Domain
         u1_name = data_utils.rand_name('test_user')
-        cls.domain_enabled_user = cls.client.create_user(
+        cls.domain_enabled_user = cls.users_client.create_user(
             u1_name, password=alt_password,
             email=cls.alt_email, domain_id=cls.data.domain['id'])['user']
-        cls.data.v3_users.append(cls.domain_enabled_user)
+        cls.data.users.append(cls.domain_enabled_user)
         # Create default not enabled user
         u2_name = data_utils.rand_name('test_user')
-        cls.non_domain_enabled_user = cls.client.create_user(
+        cls.non_domain_enabled_user = cls.users_client.create_user(
             u2_name, password=alt_password,
             email=cls.alt_email, enabled=False)['user']
-        cls.data.v3_users.append(cls.non_domain_enabled_user)
+        cls.data.users.append(cls.non_domain_enabled_user)
 
     @test.idempotent_id('08f9aabb-dcfe-41d0-8172-82b5fa0bd73d')
     def test_list_user_domains(self):
@@ -77,9 +77,9 @@
     @test.idempotent_id('b30d4651-a2ea-4666-8551-0c0e49692635')
     def test_list_users(self):
         # List users
-        body = self.client.list_users()['users']
+        body = self.users_client.list_users()['users']
         fetched_ids = [u['id'] for u in body]
-        missing_users = [u['id'] for u in self.data.v3_users
+        missing_users = [u['id'] for u in self.data.users
                          if u['id'] not in fetched_ids]
         self.assertEqual(0, len(missing_users),
                          "Failed to find user %s in fetched list" %
@@ -88,8 +88,8 @@
     @test.idempotent_id('b4baa3ae-ac00-4b4e-9e27-80deaad7771f')
     def test_get_user(self):
         # Get a user detail
-        user = self.client.show_user(self.data.v3_users[0]['id'])['user']
-        self.assertEqual(self.data.v3_users[0]['id'], user['id'])
-        self.assertEqual(self.data.v3_users[0]['name'], user['name'])
+        user = self.users_client.show_user(self.data.users[0]['id'])['user']
+        self.assertEqual(self.data.users[0]['id'], user['id'])
+        self.assertEqual(self.data.users[0]['name'], user['name'])
         self.assertEqual(self.alt_email, user['email'])
         self.assertEqual(self.data.domain['id'], user['domain_id'])
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index af9497c..607bebe 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -25,14 +25,14 @@
         # Create project with a description
         project_name = data_utils.rand_name('project')
         project_desc = data_utils.rand_name('desc')
-        project = self.client.create_project(
+        project = self.projects_client.create_project(
             project_name, description=project_desc)['project']
         self.data.projects.append(project)
         project_id = project['id']
         desc1 = project['description']
         self.assertEqual(desc1, project_desc, 'Description should have '
                          'been sent in response for create')
-        body = self.client.get_project(project_id)['project']
+        body = self.projects_client.show_project(project_id)['project']
         desc2 = body['description']
         self.assertEqual(desc2, project_desc, 'Description does not appear'
                          'to be set')
@@ -42,13 +42,13 @@
         # Create project with a domain
         self.data.setup_test_domain()
         project_name = data_utils.rand_name('project')
-        project = self.client.create_project(
+        project = self.projects_client.create_project(
             project_name, domain_id=self.data.domain['id'])['project']
         self.data.projects.append(project)
         project_id = project['id']
         self.assertEqual(project_name, project['name'])
         self.assertEqual(self.data.domain['id'], project['domain_id'])
-        body = self.client.get_project(project_id)['project']
+        body = self.projects_client.show_project(project_id)['project']
         self.assertEqual(project_name, body['name'])
         self.assertEqual(self.data.domain['id'], body['domain_id'])
 
@@ -56,13 +56,13 @@
     def test_project_create_enabled(self):
         # Create a project that is enabled
         project_name = data_utils.rand_name('project')
-        project = self.client.create_project(
+        project = self.projects_client.create_project(
             project_name, enabled=True)['project']
         self.data.projects.append(project)
         project_id = project['id']
         en1 = project['enabled']
         self.assertTrue(en1, 'Enable should be True in response')
-        body = self.client.get_project(project_id)['project']
+        body = self.projects_client.show_project(project_id)['project']
         en2 = body['enabled']
         self.assertTrue(en2, 'Enable should be True in lookup')
 
@@ -70,13 +70,13 @@
     def test_project_create_not_enabled(self):
         # Create a project that is not enabled
         project_name = data_utils.rand_name('project')
-        project = self.client.create_project(
+        project = self.projects_client.create_project(
             project_name, enabled=False)['project']
         self.data.projects.append(project)
         en1 = project['enabled']
         self.assertEqual('false', str(en1).lower(),
                          'Enable should be False in response')
-        body = self.client.get_project(project['id'])['project']
+        body = self.projects_client.show_project(project['id'])['project']
         en2 = body['enabled']
         self.assertEqual('false', str(en2).lower(),
                          'Enable should be False in lookup')
@@ -85,18 +85,18 @@
     def test_project_update_name(self):
         # Update name attribute of a project
         p_name1 = data_utils.rand_name('project')
-        project = self.client.create_project(p_name1)['project']
+        project = self.projects_client.create_project(p_name1)['project']
         self.data.projects.append(project)
 
         resp1_name = project['name']
 
         p_name2 = data_utils.rand_name('project2')
-        body = self.client.update_project(project['id'],
-                                          name=p_name2)['project']
+        body = self.projects_client.update_project(project['id'],
+                                                   name=p_name2)['project']
         resp2_name = body['name']
         self.assertNotEqual(resp1_name, resp2_name)
 
-        body = self.client.get_project(project['id'])['project']
+        body = self.projects_client.show_project(project['id'])['project']
         resp3_name = body['name']
 
         self.assertNotEqual(resp1_name, resp3_name)
@@ -108,18 +108,18 @@
         # Update description attribute of a project
         p_name = data_utils.rand_name('project')
         p_desc = data_utils.rand_name('desc')
-        project = self.client.create_project(
+        project = self.projects_client.create_project(
             p_name, description=p_desc)['project']
         self.data.projects.append(project)
         resp1_desc = project['description']
 
         p_desc2 = data_utils.rand_name('desc2')
-        body = self.client.update_project(
+        body = self.projects_client.update_project(
             project['id'], description=p_desc2)['project']
         resp2_desc = body['description']
         self.assertNotEqual(resp1_desc, resp2_desc)
 
-        body = self.client.get_project(project['id'])['project']
+        body = self.projects_client.show_project(project['id'])['project']
         resp3_desc = body['description']
 
         self.assertNotEqual(resp1_desc, resp3_desc)
@@ -131,18 +131,19 @@
         # Update the enabled attribute of a project
         p_name = data_utils.rand_name('project')
         p_en = False
-        project = self.client.create_project(p_name, enabled=p_en)['project']
+        project = self.projects_client.create_project(p_name,
+                                                      enabled=p_en)['project']
         self.data.projects.append(project)
 
         resp1_en = project['enabled']
 
         p_en2 = True
-        body = self.client.update_project(
-            project['id'], enabled=p_en2)['project']
+        body = self.projects_client.update_project(project['id'],
+                                                   enabled=p_en2)['project']
         resp2_en = body['enabled']
         self.assertNotEqual(resp1_en, resp2_en)
 
-        body = self.client.get_project(project['id'])['project']
+        body = self.projects_client.show_project(project['id'])['project']
         resp3_en = body['enabled']
 
         self.assertNotEqual(resp1_en, resp3_en)
@@ -154,7 +155,7 @@
         # Associate a user to a project
         # Create a Project
         p_name = data_utils.rand_name('project')
-        project = self.client.create_project(p_name)['project']
+        project = self.projects_client.create_project(p_name)['project']
         self.data.projects.append(project)
 
         # Create a User
@@ -162,14 +163,14 @@
         u_desc = u_name + 'description'
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_password()
-        user = self.client.create_user(
+        user = self.users_client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email, project_id=project['id'])['user']
         # Delete the User at the end of this method
-        self.addCleanup(self.client.delete_user, user['id'])
+        self.addCleanup(self.users_client.delete_user, user['id'])
 
         # Get User To validate the user details
-        new_user_get = self.client.show_user(user['id'])['user']
+        new_user_get = self.users_client.show_user(user['id'])['user']
         # Assert response body of GET
         self.assertEqual(u_name, new_user_get['name'])
         self.assertEqual(u_desc, new_user_get['description'])
diff --git a/tempest/api/identity/admin/v3/test_projects_negative.py b/tempest/api/identity/admin/v3/test_projects_negative.py
index 9b60d54..79cfc91 100644
--- a/tempest/api/identity/admin/v3/test_projects_negative.py
+++ b/tempest/api/identity/admin/v3/test_projects_negative.py
@@ -27,18 +27,18 @@
     def test_list_projects_by_unauthorized_user(self):
         # Non-admin user should not be able to list projects
         self.assertRaises(lib_exc.Forbidden,
-                          self.non_admin_client.list_projects)
+                          self.non_admin_projects_client.list_projects)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('874c3e84-d174-4348-a16b-8c01f599561b')
     def test_project_create_duplicate(self):
         # Project names should be unique
         project_name = data_utils.rand_name('project-dup')
-        project = self.client.create_project(project_name)['project']
+        project = self.projects_client.create_project(project_name)['project']
         self.data.projects.append(project)
 
-        self.assertRaises(
-            lib_exc.Conflict, self.client.create_project, project_name)
+        self.assertRaises(lib_exc.Conflict,
+                          self.projects_client.create_project, project_name)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('8fba9de2-3e1f-4e77-812a-60cb68f8df13')
@@ -46,38 +46,39 @@
         # Non-admin user should not be authorized to create a project
         project_name = data_utils.rand_name('project')
         self.assertRaises(
-            lib_exc.Forbidden, self.non_admin_client.create_project,
+            lib_exc.Forbidden, self.non_admin_projects_client.create_project,
             project_name)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('7828db17-95e5-475b-9432-9a51b4aa79a9')
     def test_create_project_with_empty_name(self):
         # Project name should not be empty
-        self.assertRaises(lib_exc.BadRequest, self.client.create_project,
-                          name='')
+        self.assertRaises(lib_exc.BadRequest,
+                          self.projects_client.create_project, name='')
 
     @test.attr(type=['negative'])
     @test.idempotent_id('502b6ceb-b0c8-4422-bf53-f08fdb21e2f0')
     def test_create_projects_name_length_over_64(self):
         # Project name length should not be greater than 64 characters
         project_name = 'a' * 65
-        self.assertRaises(lib_exc.BadRequest, self.client.create_project,
-                          project_name)
+        self.assertRaises(lib_exc.BadRequest,
+                          self.projects_client.create_project, project_name)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('8d68c012-89e0-4394-8d6b-ccd7196def97')
     def test_project_delete_by_unauthorized_user(self):
         # Non-admin user should not be able to delete a project
         project_name = data_utils.rand_name('project')
-        project = self.client.create_project(project_name)['project']
+        project = self.projects_client.create_project(project_name)['project']
         self.data.projects.append(project)
         self.assertRaises(
-            lib_exc.Forbidden, self.non_admin_client.delete_project,
+            lib_exc.Forbidden, self.non_admin_projects_client.delete_project,
             project['id'])
 
     @test.attr(type=['negative'])
     @test.idempotent_id('7965b581-60c1-43b7-8169-95d4ab7fc6fb')
     def test_delete_non_existent_project(self):
         # Attempt to delete a non existent project should fail
-        self.assertRaises(lib_exc.NotFound, self.client.delete_project,
+        self.assertRaises(lib_exc.NotFound,
+                          self.projects_client.delete_project,
                           data_utils.rand_uuid_hex())
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index ae714aa..468f169 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -26,7 +26,7 @@
         for _ in range(3):
             role_name = data_utils.rand_name(name='role')
             role = cls.client.create_role(name=role_name)['role']
-            cls.data.v3_roles.append(role)
+            cls.data.roles.append(role)
         cls.fetched_role_ids = list()
         u_name = data_utils.rand_name('user')
         u_desc = '%s description' % u_name
@@ -35,14 +35,14 @@
         cls.domain = cls.client.create_domain(
             data_utils.rand_name('domain'),
             description=data_utils.rand_name('domain-desc'))['domain']
-        cls.project = cls.client.create_project(
+        cls.project = cls.projects_client.create_project(
             data_utils.rand_name('project'),
             description=data_utils.rand_name('project-desc'),
             domain_id=cls.domain['id'])['project']
         cls.group_body = cls.groups_client.create_group(
             name=data_utils.rand_name('Group'), project_id=cls.project['id'],
             domain_id=cls.domain['id'])['group']
-        cls.user_body = cls.client.create_user(
+        cls.user_body = cls.users_client.create_user(
             u_name, description=u_desc, password=cls.u_password,
             email=u_email, project_id=cls.project['id'],
             domain_id=cls.domain['id'])['user']
@@ -53,8 +53,8 @@
     def resource_cleanup(cls):
         cls.client.delete_role(cls.role['id'])
         cls.groups_client.delete_group(cls.group_body['id'])
-        cls.client.delete_user(cls.user_body['id'])
-        cls.client.delete_project(cls.project['id'])
+        cls.users_client.delete_user(cls.user_body['id'])
+        cls.projects_client.delete_project(cls.project['id'])
         # NOTE(harika-vakadi): It is necessary to disable the domain
         # before deleting,or else it would result in unauthorized error
         cls.client.update_domain(cls.domain['id'], enabled=False)
@@ -103,6 +103,9 @@
         self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
+        self.client.check_user_role_existence_on_project(
+            self.project['id'], self.user_body['id'], self.role['id'])
+
         self.client.delete_role_from_user_on_project(
             self.project['id'], self.user_body['id'], self.role['id'])
 
@@ -120,6 +123,9 @@
         self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
+        self.client.check_user_role_existence_on_domain(
+            self.domain['id'], self.user_body['id'], self.role['id'])
+
         self.client.delete_role_from_user_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
@@ -150,6 +156,10 @@
         roles = body['token']['roles']
         self.assertEqual(len(roles), 1)
         self.assertEqual(roles[0]['id'], self.role['id'])
+
+        self.client.check_role_from_group_on_project_existence(
+            self.project['id'], self.group_body['id'], self.role['id'])
+
         # Revoke role to group on project
         self.client.delete_role_from_group_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
@@ -168,6 +178,9 @@
         self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
+        self.client.check_role_from_group_on_domain_existence(
+            self.domain['id'], self.group_body['id'], self.role['id'])
+
         self.client.delete_role_from_group_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
@@ -175,5 +188,5 @@
     def test_list_roles(self):
         # Return a list of all roles
         body = self.client.list_roles()['roles']
-        found = [role for role in body if role in self.data.v3_roles]
-        self.assertEqual(len(found), len(self.data.v3_roles))
+        found = [role for role in body if role in self.data.roles]
+        self.assertEqual(len(found), len(self.data.roles))
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index b1446cf..531ff56 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -30,10 +30,10 @@
         u_desc = '%s-description' % u_name
         u_email = '%s@testmail.tm' % u_name
         u_password = data_utils.rand_password()
-        user = self.client.create_user(
+        user = self.users_client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email)['user']
-        self.addCleanup(self.client.delete_user, user['id'])
+        self.addCleanup(self.users_client.delete_user, user['id'])
         # Perform Authentication
         resp = self.token.auth(user_id=user['id'],
                                password=u_password).response
@@ -61,18 +61,20 @@
         # Create a user.
         user_name = data_utils.rand_name(name='user')
         user_password = data_utils.rand_password()
-        user = self.client.create_user(user_name,
-                                       password=user_password)['user']
-        self.addCleanup(self.client.delete_user, user['id'])
+        user = self.users_client.create_user(user_name,
+                                             password=user_password)['user']
+        self.addCleanup(self.users_client.delete_user, user['id'])
 
         # Create a couple projects
         project1_name = data_utils.rand_name(name='project')
-        project1 = self.client.create_project(project1_name)['project']
-        self.addCleanup(self.client.delete_project, project1['id'])
+        project1 = self.projects_client.create_project(
+            project1_name)['project']
+        self.addCleanup(self.projects_client.delete_project, project1['id'])
 
         project2_name = data_utils.rand_name(name='project')
-        project2 = self.client.create_project(project2_name)['project']
-        self.addCleanup(self.client.delete_project, project2['id'])
+        project2 = self.projects_client.create_project(
+            project2_name)['project']
+        self.addCleanup(self.projects_client.delete_project, project2['id'])
 
         # Create a role
         role_name = data_utils.rand_name(name='role')
@@ -80,11 +82,11 @@
         self.addCleanup(self.client.delete_role, role['id'])
 
         # Grant the user the role on both projects.
-        self.client.assign_user_role(project1['id'], user['id'],
-                                     role['id'])
+        self.client.assign_user_role_on_project(project1['id'], user['id'],
+                                                role['id'])
 
-        self.client.assign_user_role(project2['id'], user['id'],
-                                     role['id'])
+        self.client.assign_user_role_on_project(project2['id'], user['id'],
+                                                role['id'])
 
         # Get an unscoped token.
         token_auth = self.token.auth(user_id=user['id'],
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 85961b4..180e695 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -46,8 +46,8 @@
     def create_trustor_and_roles(self):
         # create a project that trusts will be granted on
         self.trustor_project_name = data_utils.rand_name(name='project')
-        project = self.client.create_project(self.trustor_project_name,
-                                             domain_id='default')['project']
+        project = self.projects_client.create_project(
+            self.trustor_project_name, domain_id='default')['project']
         self.trustor_project_id = project['id']
         self.assertIsNotNone(self.trustor_project_id)
 
@@ -56,7 +56,7 @@
         u_desc = self.trustor_username + 'description'
         u_email = self.trustor_username + '@testmail.xx'
         self.trustor_password = data_utils.rand_password()
-        user = self.client.create_user(
+        user = self.users_client.create_user(
             self.trustor_username,
             description=u_desc,
             password=self.trustor_password,
@@ -76,12 +76,12 @@
         self.not_delegated_role_id = role['id']
 
         # Assign roles to trustor
-        self.client.assign_user_role(self.trustor_project_id,
-                                     self.trustor_user_id,
-                                     self.delegated_role_id)
-        self.client.assign_user_role(self.trustor_project_id,
-                                     self.trustor_user_id,
-                                     self.not_delegated_role_id)
+        self.client.assign_user_role_on_project(self.trustor_project_id,
+                                                self.trustor_user_id,
+                                                self.delegated_role_id)
+        self.client.assign_user_role_on_project(self.trustor_project_id,
+                                                self.trustor_user_id,
+                                                self.not_delegated_role_id)
 
         # Get trustee user ID, use the demo user
         trustee_username = self.non_admin_client.user
@@ -101,9 +101,9 @@
 
     def cleanup_user_and_roles(self):
         if self.trustor_user_id:
-            self.client.delete_user(self.trustor_user_id)
+            self.users_client.delete_user(self.trustor_user_id)
         if self.trustor_project_id:
-            self.client.delete_project(self.trustor_project_id)
+            self.projects_client.delete_project(self.trustor_project_id)
         if self.delegated_role_id:
             self.client.delete_role(self.delegated_role_id)
         if self.not_delegated_role_id:
@@ -139,8 +139,8 @@
             self.assertEqual(self.delegated_role, trust['roles'][0]['name'])
             self.assertEqual(1, len(trust['roles']))
 
-    def get_trust(self):
-        trust_get = self.trustor_client.get_trust(self.trust_id)['trust']
+    def show_trust(self):
+        trust_get = self.trustor_client.show_trust(self.trust_id)['trust']
         return trust_get
 
     def validate_role(self, role):
@@ -155,12 +155,12 @@
 
     def check_trust_roles(self):
         # Check we find the delegated role
-        roles_get = self.trustor_client.get_trust_roles(
+        roles_get = self.trustor_client.list_trust_roles(
             self.trust_id)['roles']
         self.assertEqual(1, len(roles_get))
         self.validate_role(roles_get[0])
 
-        role_get = self.trustor_client.get_trust_role(
+        role_get = self.trustor_client.show_trust_role(
             self.trust_id, self.delegated_role_id)['role']
         self.validate_role(role_get)
 
@@ -169,7 +169,7 @@
 
         # And that we don't find not_delegated_role
         self.assertRaises(lib_exc.NotFound,
-                          self.trustor_client.get_trust_role,
+                          self.trustor_client.show_trust_role,
                           self.trust_id,
                           self.not_delegated_role_id)
 
@@ -181,7 +181,7 @@
     def delete_trust(self):
         self.trustor_client.delete_trust(self.trust_id)
         self.assertRaises(lib_exc.NotFound,
-                          self.trustor_client.get_trust,
+                          self.trustor_client.show_trust,
                           self.trust_id)
         self.trust_id = None
 
@@ -200,7 +200,7 @@
         trust = self.create_trust()
         self.validate_trust(trust)
 
-        trust_get = self.get_trust()
+        trust_get = self.show_trust()
         self.validate_trust(trust_get)
 
         self.check_trust_roles()
@@ -212,7 +212,7 @@
         trust = self.create_trust(impersonate=False)
         self.validate_trust(trust, impersonate=False)
 
-        trust_get = self.get_trust()
+        trust_get = self.show_trust()
         self.validate_trust(trust_get, impersonate=False)
 
         self.check_trust_roles()
@@ -236,7 +236,7 @@
         trust = self.create_trust(expires=expires_str)
         self.validate_trust(trust, expires=expires_str)
 
-        trust_get = self.get_trust()
+        trust_get = self.show_trust()
 
         self.validate_trust(trust_get, expires=expires_str)
 
@@ -255,7 +255,7 @@
     @test.idempotent_id('6268b345-87ca-47c0-9ce3-37792b43403a')
     def test_get_trusts_query(self):
         self.create_trust()
-        trusts_get = self.trustor_client.get_trusts(
+        trusts_get = self.trustor_client.list_trusts(
             trustor_user_id=self.trustor_user_id)['trusts']
         self.assertEqual(1, len(trusts_get))
         self.validate_trust(trusts_get[0], summary=True)
@@ -264,7 +264,7 @@
     @test.idempotent_id('4773ebd5-ecbf-4255-b8d8-b63e6f72b65d')
     def test_get_trusts_all(self):
         self.create_trust()
-        trusts_get = self.client.get_trusts()['trusts']
+        trusts_get = self.client.list_trusts()['trusts']
         trusts = [t for t in trusts_get
                   if t['id'] == self.trust_id]
         self.assertEqual(1, len(trusts))
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index a402b3f..de659d8 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -30,22 +30,22 @@
         u_desc = u_name + 'description'
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_password()
-        user = self.client.create_user(
+        user = self.users_client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email, enabled=False)['user']
         # Delete the User at the end of this method
-        self.addCleanup(self.client.delete_user, user['id'])
+        self.addCleanup(self.users_client.delete_user, user['id'])
         # Creating second project for updation
-        project = self.client.create_project(
+        project = self.projects_client.create_project(
             data_utils.rand_name('project'),
             description=data_utils.rand_name('project-desc'))['project']
         # Delete the Project at the end of this method
-        self.addCleanup(self.client.delete_project, project['id'])
+        self.addCleanup(self.projects_client.delete_project, project['id'])
         # Updating user details with new values
         u_name2 = data_utils.rand_name('user2')
         u_email2 = u_name2 + '@testmail.tm'
         u_description2 = u_name2 + ' description'
-        update_user = self.client.update_user(
+        update_user = self.users_client.update_user(
             user['id'], name=u_name2, description=u_description2,
             project_id=project['id'],
             email=u_email2, enabled=False)['user']
@@ -56,7 +56,7 @@
         self.assertEqual(u_email2, update_user['email'])
         self.assertEqual(False, update_user['enabled'])
         # GET by id after updation
-        new_user_get = self.client.show_user(user['id'])['user']
+        new_user_get = self.users_client.show_user(user['id'])['user']
         # Assert response body of GET after updation
         self.assertEqual(u_name2, new_user_get['name'])
         self.assertEqual(u_description2, new_user_get['description'])
@@ -70,14 +70,15 @@
         # Creating User to check password updation
         u_name = data_utils.rand_name('user')
         original_password = data_utils.rand_password()
-        user = self.client.create_user(
+        user = self.users_client.create_user(
             u_name, password=original_password)['user']
         # Delete the User at the end all test methods
-        self.addCleanup(self.client.delete_user, user['id'])
+        self.addCleanup(self.users_client.delete_user, user['id'])
         # Update user with new password
         new_password = data_utils.rand_password()
-        self.client.update_user_password(user['id'], password=new_password,
-                                         original_password=original_password)
+        self.users_client.update_user_password(
+            user['id'], password=new_password,
+            original_password=original_password)
         # TODO(lbragstad): Sleeping after the response status has been checked
         # and the body loaded as JSON allows requests to fail-fast. The sleep
         # is necessary because keystone will err on the side of security and
@@ -100,43 +101,45 @@
         # List the projects that a user has access upon
         assigned_project_ids = list()
         fetched_project_ids = list()
-        u_project = self.client.create_project(
+        u_project = self.projects_client.create_project(
             data_utils.rand_name('project'),
             description=data_utils.rand_name('project-desc'))['project']
         # Delete the Project at the end of this method
-        self.addCleanup(self.client.delete_project, u_project['id'])
+        self.addCleanup(self.projects_client.delete_project, u_project['id'])
         # Create a user.
         u_name = data_utils.rand_name('user')
         u_desc = u_name + 'description'
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_password()
-        user_body = self.client.create_user(
+        user_body = self.users_client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email, enabled=False, project_id=u_project['id'])['user']
         # Delete the User at the end of this method
-        self.addCleanup(self.client.delete_user, user_body['id'])
+        self.addCleanup(self.users_client.delete_user, user_body['id'])
         # Creating Role
         role_body = self.client.create_role(
             name=data_utils.rand_name('role'))['role']
         # Delete the Role at the end of this method
         self.addCleanup(self.client.delete_role, role_body['id'])
 
-        user = self.client.show_user(user_body['id'])['user']
+        user = self.users_client.show_user(user_body['id'])['user']
         role = self.client.show_role(role_body['id'])['role']
         for i in range(2):
             # Creating project so as to assign role
-            project_body = self.client.create_project(
+            project_body = self.projects_client.create_project(
                 data_utils.rand_name('project'),
                 description=data_utils.rand_name('project-desc'))['project']
-            project = self.client.get_project(project_body['id'])['project']
+            project = self.projects_client.show_project(
+                project_body['id'])['project']
             # Delete the Project at the end of this method
-            self.addCleanup(self.client.delete_project, project_body['id'])
+            self.addCleanup(
+                self.projects_client.delete_project, project_body['id'])
             # Assigning roles to user on project
-            self.client.assign_user_role(project['id'],
-                                         user['id'],
-                                         role['id'])
+            self.client.assign_user_role_on_project(project['id'],
+                                                    user['id'],
+                                                    role['id'])
             assigned_project_ids.append(project['id'])
-        body = self.client.list_user_projects(user['id'])['projects']
+        body = self.users_client.list_user_projects(user['id'])['projects']
         for i in body:
             fetched_project_ids.append(i['id'])
         # verifying the project ids in list
@@ -151,6 +154,6 @@
     @test.idempotent_id('c10dcd90-461d-4b16-8e23-4eb836c00644')
     def test_get_user(self):
         # Get a user detail
-        self.data.setup_test_v3_user()
-        user = self.client.show_user(self.data.v3_user['id'])['user']
-        self.assertEqual(self.data.v3_user['id'], user['id'])
+        self.data.setup_test_user()
+        user = self.users_client.show_user(self.data.user['id'])['user']
+        self.assertEqual(self.data.user['id'], user['id'])
diff --git a/tempest/api/identity/admin/v3/test_users_negative.py b/tempest/api/identity/admin/v3/test_users_negative.py
index 4c80bda..9dd477b 100644
--- a/tempest/api/identity/admin/v3/test_users_negative.py
+++ b/tempest/api/identity/admin/v3/test_users_negative.py
@@ -29,7 +29,7 @@
         u_name = data_utils.rand_name('user')
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_password()
-        self.assertRaises(lib_exc.NotFound, self.client.create_user,
+        self.assertRaises(lib_exc.NotFound, self.users_client.create_user,
                           u_name, u_password,
                           email=u_email,
                           domain_id=data_utils.rand_uuid_hex())
@@ -38,9 +38,9 @@
     @test.idempotent_id('b3c9fccc-4134-46f5-b600-1da6fb0a3b1f')
     def test_authentication_for_disabled_user(self):
         # Attempt to authenticate for disabled user should fail
-        self.data.setup_test_v3_user()
-        self.disable_user(self.data.test_user)
+        self.data.setup_test_user()
+        self.disable_user(self.data.user['name'])
         self.assertRaises(lib_exc.Unauthorized, self.token.auth,
-                          username=self.data.test_user,
-                          password=self.data.test_password,
+                          username=self.data.user['name'],
+                          password=self.data.user_password,
                           user_domain_id='default')
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 1ad8b92..1025de7 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -16,7 +16,6 @@
 from oslo_log import log as logging
 from tempest_lib import exceptions as lib_exc
 
-from tempest.common import credentials_factory as common_creds
 from tempest.common.utils import data_utils
 from tempest import config
 import tempest.test
@@ -49,7 +48,7 @@
         try:
             tenants = cls.tenants_client.list_tenants()['tenants']
         except AttributeError:
-            tenants = cls.client.list_projects()['projects']
+            tenants = cls.projects_client.list_projects()['projects']
         tenant = [t for t in tenants if t['name'] == name]
         if len(tenant) > 0:
             return tenant[0]
@@ -76,7 +75,6 @@
         cls.non_admin_client = cls.os.identity_public_client
         cls.non_admin_token_client = cls.os.token_client
         cls.non_admin_tenants_client = cls.os.tenants_public_client
-        cls.non_admin_roles_client = cls.os.roles_public_client
         cls.non_admin_users_client = cls.os.users_public_client
 
     @classmethod
@@ -104,12 +102,14 @@
         cls.non_admin_roles_client = cls.os.roles_client
         cls.users_client = cls.os_adm.users_client
         cls.non_admin_users_client = cls.os.users_client
+        cls.services_client = cls.os_adm.services_v2_client
+        cls.endpoints_client = cls.os_adm.endpoints_v2_client
 
     @classmethod
     def resource_setup(cls):
         super(BaseIdentityV2AdminTest, cls).resource_setup()
-        cls.data = DataGenerator(cls.client, cls.tenants_client,
-                                 cls.roles_client, cls.users_client)
+        cls.data = DataGeneratorV2(cls.client, cls.tenants_client,
+                                   cls.users_client, cls.roles_client)
 
     @classmethod
     def resource_cleanup(cls):
@@ -129,7 +129,9 @@
     def setup_clients(cls):
         super(BaseIdentityV3Test, cls).setup_clients()
         cls.non_admin_client = cls.os.identity_v3_client
+        cls.non_admin_users_client = cls.os.users_v3_client
         cls.non_admin_token = cls.os.token_v3_client
+        cls.non_admin_projects_client = cls.os.projects_client
 
     @classmethod
     def resource_cleanup(cls):
@@ -144,6 +146,7 @@
     def setup_clients(cls):
         super(BaseIdentityV3AdminTest, cls).setup_clients()
         cls.client = cls.os_adm.identity_v3_client
+        cls.users_client = cls.os_adm.users_v3_client
         cls.token = cls.os_adm.token_v3_client
         cls.endpoints_client = cls.os_adm.endpoints_client
         cls.regions_client = cls.os_adm.regions_client
@@ -151,8 +154,13 @@
         cls.policies_client = cls.os_adm.policies_client
         cls.creds_client = cls.os_adm.credentials_client
         cls.groups_client = cls.os_adm.groups_client
+        cls.projects_client = cls.os_adm.projects_client
 
-        cls.data = DataGenerator(cls.client)
+    @classmethod
+    def resource_setup(cls):
+        super(BaseIdentityV3AdminTest, cls).resource_setup()
+        cls.data = DataGeneratorV3(cls.client, cls.projects_client,
+                                   cls.users_client)
 
     @classmethod
     def resource_cleanup(cls):
@@ -160,20 +168,6 @@
         super(BaseIdentityV3AdminTest, cls).resource_cleanup()
 
     @classmethod
-    def get_user_by_name(cls, name):
-        users = cls.client.list_users()['users']
-        user = [u for u in users if u['name'] == name]
-        if len(user) > 0:
-            return user[0]
-
-    @classmethod
-    def get_tenant_by_name(cls, name):
-        tenants = cls.client.list_projects()['projects']
-        tenant = [t for t in tenants if t['name'] == name]
-        if len(tenant) > 0:
-            return tenant[0]
-
-    @classmethod
     def get_role_by_name(cls, name):
         roles = cls.client.list_roles()['roles']
         role = [r for r in roles if r['name'] == name]
@@ -183,7 +177,7 @@
     @classmethod
     def disable_user(cls, user_name):
         user = cls.get_user_by_name(user_name)
-        cls.client.update_user(user['id'], user_name, enabled=False)
+        cls.users_client.update_user(user['id'], user_name, enabled=False)
 
     def delete_domain(self, domain_id):
         # NOTE(mpavlase) It is necessary to disable the domain before deleting
@@ -192,127 +186,98 @@
         self.client.delete_domain(domain_id)
 
 
-class DataGenerator(object):
+class BaseDataGenerator(object):
 
-        def __init__(self, client, tenants_client=None, roles_client=None,
-                     users_client=None):
-            self.client = client
-            # TODO(dmellado) split Datagenerator for v2 and v3
-            self.tenants_client = tenants_client
-            self.roles_client = roles_client
-            self.users_client = users_client
-            self.users = []
-            self.tenants = []
-            self.roles = []
-            self.role_name = None
-            self.v3_users = []
-            self.projects = []
-            self.v3_roles = []
-            self.domains = []
+    def __init__(self, client, projects_client,
+                 users_client, roles_client=None):
+        self.client = client
+        self.projects_client = projects_client
+        self.users_client = users_client
+        self.roles_client = roles_client or client
 
-        @property
-        def test_credentials(self):
-            return common_creds.get_credentials(username=self.test_user,
-                                                user_id=self.user['id'],
-                                                password=self.test_password,
-                                                tenant_name=self.test_tenant,
-                                                tenant_id=self.tenant['id'])
+        self.user_password = None
+        self.user = None
+        self.tenant = None
+        self.project = None
+        self.role = None
+        self.domain = None
 
-        def setup_test_user(self):
-            """Set up a test user."""
-            self.setup_test_tenant()
-            self.test_user = data_utils.rand_name('test_user')
-            self.test_password = data_utils.rand_password()
-            self.test_email = self.test_user + '@testmail.tm'
-            self.user = self.users_client.create_user(self.test_user,
-                                                      self.test_password,
-                                                      self.tenant['id'],
-                                                      self.test_email)['user']
-            self.users.append(self.user)
+        self.users = []
+        self.tenants = []
+        self.projects = []
+        self.roles = []
+        self.domains = []
 
-        def setup_test_tenant(self):
-            """Set up a test tenant."""
-            self.test_tenant = data_utils.rand_name('test_tenant')
-            self.test_description = data_utils.rand_name('desc')
-            self.tenant = self.tenants_client.create_tenant(
-                name=self.test_tenant,
-                description=self.test_description)['tenant']
-            self.tenants.append(self.tenant)
+    def _create_test_user(self, **kwargs):
+        username = data_utils.rand_name('test_user')
+        self.user_password = data_utils.rand_password()
+        self.user = self.users_client.create_user(
+            username, password=self.user_password,
+            email=username + '@testmail.tm', **kwargs)['user']
+        self.users.append(self.user)
 
-        def setup_test_role(self):
-            """Set up a test role."""
-            self.test_role = data_utils.rand_name('role')
-            self.role = self.roles_client.create_role(
-                name=self.test_role)['role']
-            self.roles.append(self.role)
+    def setup_test_role(self):
+        """Set up a test role."""
+        self.role = self.roles_client.create_role(
+            name=data_utils.rand_name('test_role'))['role']
+        self.roles.append(self.role)
 
-        def setup_test_v3_user(self):
-            """Set up a test v3 user."""
-            self.setup_test_project()
-            self.test_user = data_utils.rand_name('test_user')
-            self.test_password = data_utils.rand_password()
-            self.test_email = self.test_user + '@testmail.tm'
-            self.v3_user = self.client.create_user(
-                self.test_user,
-                password=self.test_password,
-                project_id=self.project['id'],
-                email=self.test_email)['user']
-            self.v3_users.append(self.v3_user)
+    @staticmethod
+    def _try_wrapper(func, item, **kwargs):
+        try:
+            func(item['id'], **kwargs)
+        except lib_exc.NotFound:
+            pass
+        except Exception:
+            LOG.exception("Unexpected exception occurred in %s deletion. "
+                          "But ignored here." % item['id'])
 
-        def setup_test_project(self):
-            """Set up a test project."""
-            self.test_project = data_utils.rand_name('test_project')
-            self.test_description = data_utils.rand_name('desc')
-            self.project = self.client.create_project(
-                name=self.test_project,
-                description=self.test_description)['project']
-            self.projects.append(self.project)
+    def teardown_all(self):
+        for user in self.users:
+            self._try_wrapper(self.users_client.delete_user, user)
+        for tenant in self.tenants:
+            self._try_wrapper(self.projects_client.delete_tenant, tenant)
+        for project in self.projects:
+            self._try_wrapper(self.projects_client.delete_project, project)
+        for role in self.roles:
+            self._try_wrapper(self.roles_client.delete_role, role)
+        for domain in self.domains:
+            self._try_wrapper(self.client.update_domain, domain, enabled=False)
+            self._try_wrapper(self.client.delete_domain, domain)
 
-        def setup_test_v3_role(self):
-            """Set up a test v3 role."""
-            self.test_role = data_utils.rand_name('role')
-            self.v3_role = self.client.create_role(name=self.test_role)['role']
-            self.v3_roles.append(self.v3_role)
 
-        def setup_test_domain(self):
-            """Set up a test domain."""
-            self.test_domain = data_utils.rand_name('test_domain')
-            self.test_description = data_utils.rand_name('desc')
-            self.domain = self.client.create_domain(
-                name=self.test_domain,
-                description=self.test_description)['domain']
-            self.domains.append(self.domain)
+class DataGeneratorV2(BaseDataGenerator):
 
-        @staticmethod
-        def _try_wrapper(func, item, **kwargs):
-            try:
-                if kwargs:
-                    func(item['id'], **kwargs)
-                else:
-                    func(item['id'])
-            except lib_exc.NotFound:
-                pass
-            except Exception:
-                LOG.exception("Unexpected exception occurred in %s deletion."
-                              " But ignored here." % item['id'])
+    def setup_test_user(self):
+        """Set up a test user."""
+        self.setup_test_tenant()
+        self._create_test_user(tenant_id=self.tenant['id'])
 
-        def teardown_all(self):
-            # NOTE(masayukig): v3 client doesn't have v2 method.
-            # (e.g. delete_tenant) So we need to check resources existence
-            # before using client methods.
-            for user in self.users:
-                self._try_wrapper(self.users_client.delete_user, user)
-            for tenant in self.tenants:
-                self._try_wrapper(self.tenants_client.delete_tenant, tenant)
-            for role in self.roles:
-                self._try_wrapper(self.roles_client.delete_role, role)
-            for v3_user in self.v3_users:
-                self._try_wrapper(self.client.delete_user, v3_user)
-            for v3_project in self.projects:
-                self._try_wrapper(self.client.delete_project, v3_project)
-            for v3_role in self.v3_roles:
-                self._try_wrapper(self.client.delete_role, v3_role)
-            for domain in self.domains:
-                self._try_wrapper(self.client.update_domain, domain,
-                                  enabled=False)
-                self._try_wrapper(self.client.delete_domain, domain)
+    def setup_test_tenant(self):
+        """Set up a test tenant."""
+        self.tenant = self.projects_client.create_tenant(
+            name=data_utils.rand_name('test_tenant'),
+            description=data_utils.rand_name('desc'))['tenant']
+        self.tenants.append(self.tenant)
+
+
+class DataGeneratorV3(BaseDataGenerator):
+
+    def setup_test_user(self):
+        """Set up a test user."""
+        self.setup_test_project()
+        self._create_test_user(project_id=self.project['id'])
+
+    def setup_test_project(self):
+        """Set up a test project."""
+        self.project = self.projects_client.create_project(
+            name=data_utils.rand_name('test_project'),
+            description=data_utils.rand_name('desc'))['project']
+        self.projects.append(self.project)
+
+    def setup_test_domain(self):
+        """Set up a test domain."""
+        self.domain = self.client.create_domain(
+            name=data_utils.rand_name('test_domain'),
+            description=data_utils.rand_name('desc'))['domain']
+        self.domains.append(self.domain)
diff --git a/tempest/api/identity/v3/test_projects.py b/tempest/api/identity/v3/test_projects.py
index a547b06..b42cf43 100644
--- a/tempest/api/identity/v3/test_projects.py
+++ b/tempest/api/identity/v3/test_projects.py
@@ -27,7 +27,7 @@
     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(
+        resp = self.non_admin_users_client.list_user_projects(
             self.os.credentials.user_id)
 
         # check that user can see only that projects that he presents in so
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index 93814d3..29396a8 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -39,23 +39,24 @@
         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
+        # current non_admin_users_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 = (
+        self.non_admin_users_client_for_cleanup = (
+            copy.copy(self.non_admin_users_client))
+        self.non_admin_users_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,
+            self.non_admin_users_client_for_cleanup.update_user_password,
             user_id,
             password=old_pass,
             original_password=new_pass)
 
         # user updates own password
-        self.non_admin_client.update_user_password(
+        self.non_admin_users_client.update_user_password(
             user_id, password=new_pass, original_password=old_pass)
 
         # TODO(lbragstad): Sleeping after the response status has been checked
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 64f3174..1a84d06 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -18,11 +18,27 @@
 from tempest.api.image import base
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
+def get_container_and_disk_format():
+    a_formats = ['ami', 'ari', 'aki']
+
+    container_format = CONF.image.container_formats[0]
+    disk_format = CONF.image.disk_formats[0]
+
+    if container_format in a_formats and container_format != disk_format:
+        msg = ("The container format and the disk format don't match. "
+               "Contaiter format: %(container)s, Disk format: %(disk)s." %
+               {'container': container_format, 'disk': disk_format})
+        raise exceptions.InvalidConfiguration(message=msg)
+
+    return container_format, disk_format
+
+
 class CreateRegisterImagesTest(base.BaseV1ImageTest):
     """Here we test the registration and creation of images."""
 
@@ -30,9 +46,10 @@
     def test_register_then_upload(self):
         # Register, then upload an image
         properties = {'prop1': 'val1'}
+        container_format, disk_format = get_container_and_disk_format()
         body = self.create_image(name='New Name',
-                                 container_format='bare',
-                                 disk_format='raw',
+                                 container_format=container_format,
+                                 disk_format=disk_format,
                                  is_public=False,
                                  properties=properties)
         self.assertIn('id', body)
@@ -52,9 +69,10 @@
     @test.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
     def test_register_remote_image(self):
         # Register a new remote image
+        container_format, disk_format = get_container_and_disk_format()
         body = self.create_image(name='New Remote Image',
-                                 container_format='bare',
-                                 disk_format='raw', is_public=False,
+                                 container_format=container_format,
+                                 disk_format=disk_format, is_public=False,
                                  location=CONF.image.http_image,
                                  properties={'key1': 'value1',
                                              'key2': 'value2'})
@@ -68,9 +86,10 @@
 
     @test.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
     def test_register_http_image(self):
+        container_format, disk_format = get_container_and_disk_format()
         body = self.create_image(name='New Http Image',
-                                 container_format='bare',
-                                 disk_format='raw', is_public=False,
+                                 container_format=container_format,
+                                 disk_format=disk_format, is_public=False,
                                  copy_from=CONF.image.http_image)
         self.assertIn('id', body)
         image_id = body.get('id')
@@ -82,10 +101,11 @@
     @test.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
     def test_register_image_with_min_ram(self):
         # Register an image with min ram
+        container_format, disk_format = get_container_and_disk_format()
         properties = {'prop1': 'val1'}
         body = self.create_image(name='New_image_with_min_ram',
-                                 container_format='bare',
-                                 disk_format='raw',
+                                 container_format=container_format,
+                                 disk_format=disk_format,
                                  is_public=False,
                                  min_ram=40,
                                  properties=properties)
@@ -103,22 +123,51 @@
     """Here we test the listing of image information"""
 
     @classmethod
+    def skip_checks(cls):
+        super(ListImagesTest, cls).skip_checks()
+        if (len(CONF.image.container_formats) < 2
+           or len(CONF.image.disk_formats) < 2):
+            skip_msg = ("%s skipped as multiple container formats "
+                        "or disk formats are not available." % cls.__name__)
+            raise cls.skipException(skip_msg)
+
+    @classmethod
     def resource_setup(cls):
         super(ListImagesTest, cls).resource_setup()
         # We add a few images here to test the listing functionality of
         # the images API
-        img1 = cls._create_remote_image('one', 'bare', 'raw')
-        img2 = cls._create_remote_image('two', 'ami', 'ami')
-        img3 = cls._create_remote_image('dup', 'bare', 'raw')
-        img4 = cls._create_remote_image('dup', 'bare', 'raw')
-        img5 = cls._create_standard_image('1', 'ami', 'ami', 42)
-        img6 = cls._create_standard_image('2', 'ami', 'ami', 142)
-        img7 = cls._create_standard_image('33', 'bare', 'raw', 142)
-        img8 = cls._create_standard_image('33', 'bare', 'raw', 142)
+        a_formats = ['ami', 'ari', 'aki']
+
+        (cls.container_format,
+         cls.container_format_alt) = CONF.image.container_formats[:2]
+        cls.disk_format, cls.disk_format_alt = CONF.image.disk_formats[:2]
+        if cls.container_format in a_formats:
+            cls.disk_format = cls.container_format
+        if cls.container_format_alt in a_formats:
+            cls.disk_format_alt = cls.container_format_alt
+
+        img1 = cls._create_remote_image('one', cls.container_format,
+                                        cls.disk_format)
+        img2 = cls._create_remote_image('two', cls.container_format_alt,
+                                        cls.disk_format_alt)
+        img3 = cls._create_remote_image('dup', cls.container_format,
+                                        cls.disk_format)
+        img4 = cls._create_remote_image('dup', cls.container_format,
+                                        cls.disk_format)
+        img5 = cls._create_standard_image('1', cls.container_format_alt,
+                                          cls.disk_format_alt, 42)
+        img6 = cls._create_standard_image('2', cls.container_format_alt,
+                                          cls.disk_format_alt, 142)
+        img7 = cls._create_standard_image('33', cls.container_format,
+                                          cls.disk_format, 142)
+        img8 = cls._create_standard_image('33', cls.container_format,
+                                          cls.disk_format, 142)
         cls.created_set = set(cls.created_images)
-        # 5x bare, 3x ami
-        cls.bare_set = set((img1, img3, img4, img7, img8))
-        cls.ami_set = set((img2, img5, img6))
+        # same container format
+        cls.same_container_format_set = set((img1, img3, img4, img7, img8))
+        # same disk format
+        cls.same_disk_format_set = set((img2, img5, img6))
+
         # 1x with size 42
         cls.size42_set = set((img5,))
         # 3x with size 142
@@ -167,22 +216,25 @@
 
     @test.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
     def test_index_disk_format(self):
-        images_list = self.client.list_images(disk_format='ami')['images']
+        images_list = self.client.list_images(
+            disk_format=self.disk_format_alt)['images']
         for image in images_list:
-            self.assertEqual(image['disk_format'], 'ami')
+            self.assertEqual(image['disk_format'], self.disk_format_alt)
         result_set = set(map(lambda x: x['id'], images_list))
-        self.assertTrue(self.ami_set <= result_set)
-        self.assertFalse(self.created_set - self.ami_set <= result_set)
+        self.assertTrue(self.same_disk_format_set <= result_set)
+        self.assertFalse(self.created_set - self.same_disk_format_set
+                         <= result_set)
 
     @test.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
     def test_index_container_format(self):
-        images_list = (self.client.list_images(container_format='bare')
-                       ['images'])
+        images_list = self.client.list_images(
+            container_format=self.container_format)['images']
         for image in images_list:
-            self.assertEqual(image['container_format'], 'bare')
+            self.assertEqual(image['container_format'], self.container_format)
         result_set = set(map(lambda x: x['id'], images_list))
-        self.assertTrue(self.bare_set <= result_set)
-        self.assertFalse(self.created_set - self.bare_set <= result_set)
+        self.assertTrue(self.same_container_format_set <= result_set)
+        self.assertFalse(self.created_set - self.same_container_format_set
+                         <= result_set)
 
     @test.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
     def test_index_max_size(self):
@@ -231,7 +283,9 @@
     @classmethod
     def resource_setup(cls):
         super(UpdateImageMetaTest, cls).resource_setup()
-        cls.image_id = cls._create_standard_image('1', 'ami', 'ami', 42)
+        container_format, disk_format = get_container_and_disk_format()
+        cls.image_id = cls._create_standard_image('1', container_format,
+                                                  disk_format, 42)
 
     @classmethod
     def _create_standard_image(cls, name, container_format,
diff --git a/tempest/api/messaging/__init__.py b/tempest/api/messaging/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/messaging/__init__.py
+++ /dev/null
diff --git a/tempest/api/messaging/base.py b/tempest/api/messaging/base.py
deleted file mode 100644
index a324c37..0000000
--- a/tempest/api/messaging/base.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright (c) 2014 Rackspace, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class BaseMessagingTest(test.BaseTestCase):
-
-    """Base class for the Messaging (Zaqar) tests
-
-    It is assumed that the following option is defined in the
-    [service_available] section of etc/tempest.conf
-
-        messaging as True
-    """
-
-    credentials = ['primary']
-
-    @classmethod
-    def skip_checks(cls):
-        super(BaseMessagingTest, cls).skip_checks()
-        if not CONF.service_available.zaqar:
-            raise cls.skipException("Zaqar support is required")
-
-    @classmethod
-    def setup_clients(cls):
-        super(BaseMessagingTest, cls).setup_clients()
-        cls.client = cls.os.messaging_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(BaseMessagingTest, cls).resource_setup()
-        cls.messaging_cfg = CONF.messaging
-
-    @classmethod
-    def create_queue(cls, queue_name):
-        """Wrapper utility that returns a test queue."""
-        resp, body = cls.client.create_queue(queue_name)
-        return resp, body
-
-    @classmethod
-    def delete_queue(cls, queue_name):
-        """Wrapper utility that deletes a test queue."""
-        resp, body = cls.client.delete_queue(queue_name)
-        return resp, body
-
-    @classmethod
-    def check_queue_exists(cls, queue_name):
-        """Wrapper utility that checks the existence of a test queue."""
-        resp, body = cls.client.show_queue(queue_name)
-        return resp, body
-
-    @classmethod
-    def check_queue_exists_head(cls, queue_name):
-        """Wrapper utility checks the head of a queue via http HEAD."""
-        resp, body = cls.client.head_queue(queue_name)
-        return resp, body
-
-    @classmethod
-    def list_queues(cls):
-        """Wrapper utility that lists queues."""
-        resp, body = cls.client.list_queues()
-        return resp, body
-
-    @classmethod
-    def get_queue_stats(cls, queue_name):
-        """Wrapper utility that returns the queue stats."""
-        resp, body = cls.client.show_queue_stats(queue_name)
-        return resp, body
-
-    @classmethod
-    def get_queue_metadata(cls, queue_name):
-        """Wrapper utility that gets a queue metadata."""
-        resp, body = cls.client.show_queue_metadata(queue_name)
-        return resp, body
-
-    @classmethod
-    def set_queue_metadata(cls, queue_name, rbody):
-        """Wrapper utility that sets the metadata of a queue."""
-        resp, body = cls.client.set_queue_metadata(queue_name, rbody)
-        return resp, body
-
-    @classmethod
-    def post_messages(cls, queue_name, rbody):
-        """Wrapper utility that posts messages to a queue."""
-        resp, body = cls.client.post_messages(queue_name, rbody)
-
-        return resp, body
-
-    @classmethod
-    def list_messages(cls, queue_name):
-        """Wrapper utility that lists the messages in a queue."""
-        resp, body = cls.client.list_messages(queue_name)
-
-        return resp, body
-
-    @classmethod
-    def delete_messages(cls, message_uri):
-        """Wrapper utility that deletes messages."""
-        resp, body = cls.client.delete_messages(message_uri)
-
-        return resp, body
-
-    @classmethod
-    def post_claims(cls, queue_name, rbody, url_params=False):
-        """Wrapper utility that claims messages."""
-        resp, body = cls.client.post_claims(
-            queue_name, rbody, url_params=False)
-
-        return resp, body
-
-    @classmethod
-    def query_claim(cls, claim_uri):
-        """Wrapper utility that gets a claim."""
-        resp, body = cls.client.query_claim(claim_uri)
-
-        return resp, body
-
-    @classmethod
-    def update_claim(cls, claim_uri, rbody):
-        """Wrapper utility that updates a claim."""
-        resp, body = cls.client.update_claim(claim_uri, rbody)
-
-        return resp, body
-
-    @classmethod
-    def release_claim(cls, claim_uri):
-        """Wrapper utility that deletes a claim."""
-        resp, body = cls.client.delete_claim(claim_uri)
-
-        return resp, body
-
-    @classmethod
-    def generate_message_body(cls, repeat=1):
-        """Wrapper utility that sets the metadata of a queue."""
-        message_ttl = data_utils.\
-            rand_int_id(start=60, end=CONF.messaging.max_message_ttl)
-
-        key = data_utils.arbitrary_string(size=20, base_text='MessagingKey')
-        value = data_utils.arbitrary_string(size=20,
-                                            base_text='MessagingValue')
-        message_body = {key: value}
-
-        rbody = ([{'body': message_body, 'ttl': message_ttl}] * repeat)
-        return rbody
diff --git a/tempest/api/messaging/test_claims.py b/tempest/api/messaging/test_claims.py
deleted file mode 100644
index 99edde1..0000000
--- a/tempest/api/messaging/test_claims.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (c) 2014 Rackspace, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from six.moves.urllib import parse as urlparse
-from tempest_lib import decorators
-
-from tempest.api.messaging import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import test
-
-
-CONF = config.CONF
-
-
-class TestClaims(base.BaseMessagingTest):
-
-    @classmethod
-    def resource_setup(cls):
-        super(TestClaims, cls).resource_setup()
-        cls.queue_name = data_utils.rand_name('Queues-Test')
-        # Create Queue
-        cls.create_queue(cls.queue_name)
-
-    def _post_and_claim_messages(self, queue_name, repeat=1):
-        # Post Messages
-        message_body = self.generate_message_body(repeat=repeat)
-        self.client.post_messages(queue_name=self.queue_name,
-                                  rbody=message_body)
-
-        # Post Claim
-        claim_ttl = data_utils.rand_int_id(start=60,
-                                           end=CONF.messaging.max_claim_ttl)
-        claim_grace = data_utils.\
-            rand_int_id(start=60, end=CONF.messaging.max_claim_grace)
-        claim_body = {"ttl": claim_ttl, "grace": claim_grace}
-        resp, body = self.client.post_claims(queue_name=self.queue_name,
-                                             rbody=claim_body)
-
-        return resp, body
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('936cb1ca-b7af-44dd-a752-805e8c98156f')
-    def test_post_claim(self):
-        _, body = self._post_and_claim_messages(queue_name=self.queue_name)
-        claimed_message_uri = body[0]['href']
-
-        # Skipping this step till bug-1331517  is fixed
-        # Get posted claim
-        # self.client.query_claim(claimed_message_uri)
-
-        # Delete Claimed message
-        self.client.delete_messages(claimed_message_uri)
-
-    @decorators.skip_because(bug="1331517")
-    @test.attr(type='smoke')
-    @test.idempotent_id('84e491f4-68c6-451f-9846-b8f868eb27c5')
-    def test_query_claim(self):
-        # Post a Claim
-        resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
-
-        # Query Claim
-        claim_uri = resp['location']
-        self.client.query_claim(claim_uri)
-
-        # Delete Claimed message
-        claimed_message_uri = body[0]['href']
-        self.delete_messages(claimed_message_uri)
-
-    @decorators.skip_because(bug="1328111")
-    @test.attr(type='smoke')
-    @test.idempotent_id('420ef0c5-9bd6-4b82-b06d-d9da330fefd3')
-    def test_update_claim(self):
-        # Post a Claim
-        resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
-
-        claim_uri = resp['location']
-        claimed_message_uri = body[0]['href']
-
-        # Update Claim
-        claim_ttl = data_utils.rand_int_id(start=60,
-                                           end=CONF.messaging.max_claim_ttl)
-        update_rbody = {"ttl": claim_ttl}
-
-        self.client.update_claim(claim_uri, rbody=update_rbody)
-
-        # Verify claim ttl >= updated ttl value
-        _, body = self.client.query_claim(claim_uri)
-        updated_claim_ttl = body["ttl"]
-        self.assertTrue(updated_claim_ttl >= claim_ttl)
-
-        # Delete Claimed message
-        self.client.delete_messages(claimed_message_uri)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('fd4c7921-cb3f-4ed8-9ac8-e8f1e74c44aa')
-    def test_release_claim(self):
-        # Post a Claim
-        resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
-        claim_uri = resp['location']
-
-        # Release Claim
-        self.client.delete_claim(claim_uri)
-
-        # Delete Claimed message
-        # This will implicitly verify that the claim is deleted.
-        message_uri = urlparse.urlparse(claim_uri).path
-        self.client.delete_messages(message_uri)
-
-    @classmethod
-    def resource_cleanup(cls):
-        cls.delete_queue(cls.queue_name)
-        super(TestClaims, cls).resource_cleanup()
diff --git a/tempest/api/messaging/test_messages.py b/tempest/api/messaging/test_messages.py
deleted file mode 100644
index 7f4182a..0000000
--- a/tempest/api/messaging/test_messages.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (c) 2014 Rackspace, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-from tempest.api.messaging import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import test
-
-
-CONF = config.CONF
-
-
-class TestMessages(base.BaseMessagingTest):
-
-    @classmethod
-    def resource_setup(cls):
-        super(TestMessages, cls).resource_setup()
-        cls.queue_name = data_utils.rand_name('Queues-Test')
-        # Create Queue
-        cls.client.create_queue(cls.queue_name)
-
-    def _post_messages(self, repeat=CONF.messaging.max_messages_per_page):
-        message_body = self.generate_message_body(repeat=repeat)
-        resp, body = self.post_messages(queue_name=self.queue_name,
-                                        rbody=message_body)
-        return resp, body
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('93867172-a414-4eb3-a639-96e943c516b4')
-    def test_post_messages(self):
-        # Post Messages
-        resp, _ = self._post_messages()
-
-        # Get on the posted messages
-        message_uri = resp['location']
-        resp, _ = self.client.show_multiple_messages(message_uri)
-        # The test has an assertion here, because the response cannot be 204
-        # in this case (the client allows 200 or 204 for this API call).
-        self.assertEqual('200', resp['status'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('c967d59a-e919-41cb-994b-1c4300452c80')
-    def test_list_messages(self):
-        # Post Messages
-        self._post_messages()
-
-        # List Messages
-        resp, _ = self.list_messages(queue_name=self.queue_name)
-        # The test has an assertion here, because the response cannot be 204
-        # in this case (the client allows 200 or 204 for this API call).
-        self.assertEqual('200', resp['status'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('2a68e3de-24df-47c3-9039-ec4156656bf8')
-    def test_get_message(self):
-        # Post Messages
-        _, body = self._post_messages()
-        message_uri = body['resources'][0]
-
-        # Get posted message
-        resp, _ = self.client.show_single_message(message_uri)
-        # The test has an assertion here, because the response cannot be 204
-        # in this case (the client allows 200 or 204 for this API call).
-        self.assertEqual('200', resp['status'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('c4b0a30b-efda-4b87-a395-0c43140df74d')
-    def test_get_multiple_messages(self):
-        # Post Messages
-        resp, _ = self._post_messages()
-        message_uri = resp['location']
-
-        # Get posted messages
-        resp, _ = self.client.show_multiple_messages(message_uri)
-        # The test has an assertion here, because the response cannot be 204
-        # in this case (the client allows 200 or 204 for this API call).
-        self.assertEqual('200', resp['status'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('fc0fca47-dd8b-4ecc-8522-d9c191f9bc9f')
-    def test_delete_single_message(self):
-        # Post Messages
-        _, body = self._post_messages()
-        message_uri = body['resources'][0]
-
-        # Delete posted message & verify the delete operration
-        self.client.delete_messages(message_uri)
-
-        message_uri = message_uri.replace('/messages/', '/messages?ids=')
-        resp, _ = self.client.show_multiple_messages(message_uri)
-        # The test has an assertion here, because the response has to be 204
-        # in this case (the client allows 200 or 204 for this API call).
-        self.assertEqual('204', resp['status'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('00cca069-5c8f-4b42-bff1-c577da2a4546')
-    def test_delete_multiple_messages(self):
-        # Post Messages
-        resp, _ = self._post_messages()
-        message_uri = resp['location']
-
-        # Delete multiple messages
-        self.client.delete_messages(message_uri)
-        resp, _ = self.client.show_multiple_messages(message_uri)
-        # The test has an assertion here, because the response has to be 204
-        # in this case (the client allows 200 or 204 for this API call).
-        self.assertEqual('204', resp['status'])
-
-    @classmethod
-    def resource_cleanup(cls):
-        cls.delete_queue(cls.queue_name)
-        super(TestMessages, cls).resource_cleanup()
diff --git a/tempest/api/messaging/test_queues.py b/tempest/api/messaging/test_queues.py
deleted file mode 100644
index dcb5450..0000000
--- a/tempest/api/messaging/test_queues.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Copyright (c) 2014 Rackspace, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-from six import moves
-from tempest_lib import exceptions as lib_exc
-from testtools import matchers
-
-from tempest.api.messaging import base
-from tempest.common.utils import data_utils
-from tempest import test
-
-
-class TestQueues(base.BaseMessagingTest):
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('9f1c4c72-80c5-4dac-acf3-188cef42e36c')
-    def test_create_delete_queue(self):
-        # Create & Delete Queue
-        queue_name = data_utils.rand_name('test')
-        _, body = self.create_queue(queue_name)
-
-        self.addCleanup(self.client.delete_queue, queue_name)
-        # NOTE(gmann): create_queue returns response status code as 201
-        # so specifically checking the expected empty response body as
-        # this is not going to be checked in response_checker().
-        self.assertEqual('', body)
-
-        self.delete_queue(queue_name)
-        self.assertRaises(lib_exc.NotFound,
-                          self.client.show_queue,
-                          queue_name)
-
-
-class TestManageQueue(base.BaseMessagingTest):
-
-    @classmethod
-    def resource_setup(cls):
-        super(TestManageQueue, cls).resource_setup()
-        cls.queues = list()
-        for _ in moves.xrange(5):
-            queue_name = data_utils.rand_name('Queues-Test')
-            cls.queues.append(queue_name)
-            # Create Queue
-            cls.client.create_queue(queue_name)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('ccd3d69e-f156-4c5f-8a12-b4f24bee44e1')
-    def test_check_queue_existence(self):
-        # Checking Queue Existence
-        for queue_name in self.queues:
-            self.check_queue_exists(queue_name)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('e27634d8-9c8f-47d8-a677-655c47658d3e')
-    def test_check_queue_head(self):
-        # Checking Queue Existence by calling HEAD
-        for queue_name in self.queues:
-            self.check_queue_exists_head(queue_name)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('0a0feeca-7768-4303-806d-82bbbb796ad3')
-    def test_list_queues(self):
-        # Listing queues
-        _, body = self.list_queues()
-        self.assertEqual(len(body['queues']), len(self.queues))
-        for item in body['queues']:
-            self.assertIn(item['name'], self.queues)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('8fb66602-077d-49d6-ae1a-5f2091739178')
-    def test_get_queue_stats(self):
-        # Retrieve random queue
-        queue_name = self.queues[data_utils.rand_int_id(0,
-                                                        len(self.queues) - 1)]
-        # Get Queue Stats for a newly created Queue
-        _, body = self.get_queue_stats(queue_name)
-        msgs = body['messages']
-        for element in ('free', 'claimed', 'total'):
-            self.assertEqual(0, msgs[element])
-        for element in ('oldest', 'newest'):
-            self.assertNotIn(element, msgs)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('0e2441e6-6593-4bdb-a3c0-20e66eeb3fff')
-    def test_set_and_get_queue_metadata(self):
-        # Retrieve random queue
-        queue_name = self.queues[data_utils.rand_int_id(0,
-                                                        len(self.queues) - 1)]
-        # Check the Queue has no metadata
-        _, body = self.get_queue_metadata(queue_name)
-        self.assertThat(body, matchers.HasLength(0))
-        # Create metadata
-        key3 = [0, 1, 2, 3, 4]
-        key2 = data_utils.rand_name('value')
-        req_body1 = dict()
-        req_body1[data_utils.rand_name('key3')] = key3
-        req_body1[data_utils.rand_name('key2')] = key2
-        req_body = dict()
-        req_body[data_utils.rand_name('key1')] = req_body1
-        # Set Queue Metadata
-        self.set_queue_metadata(queue_name, req_body)
-
-        # Get Queue Metadata
-        _, body = self.get_queue_metadata(queue_name)
-        self.assertThat(body, matchers.Equals(req_body))
-
-    @classmethod
-    def resource_cleanup(cls):
-        for queue_name in cls.queues:
-            cls.client.delete_queue(queue_name)
-        super(TestManageQueue, cls).resource_cleanup()
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 5ff465b..fcb6fce 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -84,7 +84,7 @@
             self._remove_network_from_dhcp_agent(network_id, agent)
 
     def _remove_network_from_dhcp_agent(self, network_id, agent):
-        self.admin_agents_client.remove_network_from_dhcp_agent(
+        self.admin_agents_client.delete_network_from_dhcp_agent(
             agent_id=agent['id'],
             network_id=network_id)
         self.assertFalse(self._check_network_in_dhcp_agent(
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index c64cf77..78d6aea 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -80,8 +80,8 @@
                 cls.network = cls.create_network()
                 cls.subnet = cls.create_subnet(cls.network)
                 cls.port = cls.create_port(cls.network)
-                cls.client.add_router_interface_with_port_id(
-                    cls.router['id'], cls.port['id'])
+                cls.client.add_router_interface(cls.router['id'],
+                                                port_id=cls.port['id'])
                 # NOTE: Sometimes we have seen this test fail with dvr in,
                 # multinode tests, since the dhcp port is not created before
                 # the test gets executed and so the router is not scheduled
@@ -99,8 +99,8 @@
     @classmethod
     def resource_cleanup(cls):
         if cls.is_dvr_router:
-            cls.client.remove_router_interface_with_port_id(
-                cls.router['id'], cls.port['id'])
+            cls.client.remove_router_interface(cls.router['id'],
+                                               port_id=cls.port['id'])
         super(L3AgentSchedulerTestJSON, cls).resource_cleanup()
 
     @test.idempotent_id('b7ce6e89-e837-4ded-9b78-9ed3c9c6a45a')
@@ -110,7 +110,7 @@
     @test.idempotent_id('9464e5e7-8625-49c3-8fd1-89c52be59d66')
     def test_add_list_remove_router_on_l3_agent(self):
         l3_agent_ids = list()
-        self.admin_agents_client.add_router_to_l3_agent(
+        self.admin_agents_client.create_router_on_l3_agent(
             self.agent['id'],
             router_id=self.router['id'])
         body = (
@@ -120,7 +120,7 @@
             self.assertIn('agent_type', agent)
             self.assertEqual('L3 agent', agent['agent_type'])
         self.assertIn(self.agent['id'], l3_agent_ids)
-        body = self.admin_agents_client.remove_router_from_l3_agent(
+        body = self.admin_agents_client.delete_router_from_l3_agent(
             self.agent['id'],
             self.router['id'])
         # NOTE(afazekas): The deletion not asserted, because neutron
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 45d35cf..8b32a94 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -18,6 +18,7 @@
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import test
+from tempest_lib import exceptions as lib_exc
 
 
 class QuotasTest(base.BaseAdminNetworkTest):
@@ -59,7 +60,7 @@
         # Change quotas for tenant
         quota_set = self.admin_quotas_client.update_quotas(
             project_id, **new_quotas)['quota']
-        self.addCleanup(self.admin_quotas_client.reset_quotas, project_id)
+        self.addCleanup(self._cleanup_quotas, project_id)
         for key, value in six.iteritems(new_quotas):
             self.assertEqual(value, quota_set[key])
 
@@ -87,3 +88,12 @@
     def test_quotas(self):
         new_quotas = {'network': 0, 'security_group': 0}
         self._check_quotas(new_quotas)
+
+    def _cleanup_quotas(self, project_id):
+        # try to clean up the resources.If it fails, then
+        # assume that everything was already deleted, so
+        # it is OK to continue.
+        try:
+            self.admin_quotas_client.reset_quotas(project_id)
+        except lib_exc.NotFound:
+            pass
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 81337f3..f209f89 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -69,6 +69,7 @@
         super(BaseNetworkTest, cls).setup_clients()
         cls.client = cls.os.network_client
         cls.agents_client = cls.os.network_agents_client
+        cls.network_extensions_client = cls.os.network_extensions_client
         cls.networks_client = cls.os.networks_client
         cls.subnetpools_client = cls.os.subnetpools_client
         cls.subnets_client = cls.os.subnets_client
@@ -76,6 +77,8 @@
         cls.quotas_client = cls.os.network_quotas_client
         cls.floating_ips_client = cls.os.floating_ips_client
         cls.security_groups_client = cls.os.security_groups_client
+        cls.security_group_rules_client = (
+            cls.os.security_group_rules_client)
 
     @classmethod
     def resource_setup(cls):
@@ -247,8 +250,8 @@
     @classmethod
     def create_router_interface(cls, router_id, subnet_id):
         """Wrapper utility that returns a router interface."""
-        interface = cls.client.add_router_interface_with_subnet_id(
-            router_id, subnet_id)
+        interface = cls.client.add_router_interface(router_id,
+                                                    subnet_id=subnet_id)
         return interface
 
     @classmethod
@@ -257,8 +260,9 @@
         interfaces = body['ports']
         for i in interfaces:
             try:
-                cls.client.remove_router_interface_with_subnet_id(
-                    router['id'], i['fixed_ips'][0]['subnet_id'])
+                cls.client.remove_router_interface(
+                    router['id'],
+                    subnet_id=i['fixed_ips'][0]['subnet_id'])
             except lib_exc.NotFound:
                 pass
         cls.client.delete_router(router['id'])
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
index 739e6f9..3495b76f 100644
--- a/tempest/api/network/base_routers.py
+++ b/tempest/api/network/base_routers.py
@@ -45,19 +45,19 @@
         self.assertNotIn(router_id, routers_list)
 
     def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
-        interface = self.client.add_router_interface_with_subnet_id(
-            router_id, subnet_id)
+        interface = self.client.add_router_interface(router_id,
+                                                     subnet_id=subnet_id)
         self.addCleanup(self._remove_router_interface_with_subnet_id,
                         router_id, subnet_id)
         self.assertEqual(subnet_id, interface['subnet_id'])
         return interface
 
     def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
-        body = self.client.remove_router_interface_with_subnet_id(
-            router_id, subnet_id)
+        body = self.client.remove_router_interface(router_id,
+                                                   subnet_id=subnet_id)
         self.assertEqual(subnet_id, body['subnet_id'])
 
     def _remove_router_interface_with_port_id(self, router_id, port_id):
-        body = self.client.remove_router_interface_with_port_id(router_id,
-                                                                port_id)
+        body = self.client.remove_router_interface(router_id,
+                                                   port_id=port_id)
         self.assertEqual(port_id, body['port_id'])
diff --git a/tempest/api/network/base_security_groups.py b/tempest/api/network/base_security_groups.py
index 1525e19..3ea3aea 100644
--- a/tempest/api/network/base_security_groups.py
+++ b/tempest/api/network/base_security_groups.py
@@ -40,10 +40,11 @@
         self.assertNotIn(secgroup_id, secgroup_list)
 
     def _delete_security_group_rule(self, rule_id):
-        self.client.delete_security_group_rule(rule_id)
+        self.security_group_rules_client.delete_security_group_rule(rule_id)
         # Asserting that the security group is not found in the list
         # after deletion
-        list_body = self.client.list_security_group_rules()
+        list_body = (
+            self.security_group_rules_client.list_security_group_rules())
         rules_list = list()
         for rule in list_body['security_group_rules']:
             rules_list.append(rule['id'])
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 74c1d51..dbb0d14 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -68,9 +68,8 @@
         for port in ports:
             if (port['device_owner'].startswith('network:router_interface')
                 and port['device_id'] in [r['id'] for r in self.routers]):
-                self.client.remove_router_interface_with_port_id(
-                    port['device_id'], port['id']
-                )
+                self.client.remove_router_interface(port['device_id'],
+                                                    port_id=port['id'])
             else:
                 if port['id'] in [p['id'] for p in self.ports]:
                     self.ports_client.delete_port(port['id'])
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index b83d2b0..d71d600 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -41,14 +41,15 @@
         expected_alias = [ext for ext in expected_alias if
                           test.is_extension_enabled(ext, 'network')]
         actual_alias = list()
-        extensions = self.client.list_extensions()
+        extensions = self.network_extensions_client.list_extensions()
         list_extensions = extensions['extensions']
         # Show and verify the details of the available extensions
         for ext in list_extensions:
             ext_name = ext['name']
             ext_alias = ext['alias']
             actual_alias.append(ext['alias'])
-            ext_details = self.client.show_extension(ext_alias)
+            ext_details = self.network_extensions_client.show_extension(
+                ext_alias)
             ext_details = ext_details['extension']
 
             self.assertIsNotNone(ext_details)
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 67f2c83..d7b220b 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -22,6 +22,7 @@
 from tempest.common import custom_matchers
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -87,14 +88,16 @@
 
     @classmethod
     def _get_ipaddress_from_tempest_conf(cls):
-        """Return first subnet gateway for configured CIDR """
+        """Return subnet with mask bits for configured CIDR """
         if cls._ip_version == 4:
             cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+            cidr.prefixlen = CONF.network.tenant_network_mask_bits
 
         elif cls._ip_version == 6:
             cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+            cidr.prefixlen = CONF.network.tenant_network_v6_mask_bits
 
-        return netaddr.IPAddress(cidr)
+        return cidr
 
     @test.attr(type='smoke')
     @test.idempotent_id('0435f278-40ae-48cb-a404-b8a087bc09b1')
@@ -102,9 +105,15 @@
         network = self.create_network()
         net_id = network['id']
         address = self._get_ipaddress_from_tempest_conf()
-        allocation_pools = {'allocation_pools': [{'start': str(address + 4),
-                                                  'end': str(address + 6)}]}
-        subnet = self.create_subnet(network, **allocation_pools)
+        if ((address.version == 4 and address.prefixlen >= 30) or
+           (address.version == 6 and address.prefixlen >= 126)):
+            msg = ("Subnet %s isn't large enough for the test" % address.cidr)
+            raise exceptions.InvalidConfiguration(message=msg)
+        allocation_pools = {'allocation_pools': [{'start': str(address[2]),
+                                                  'end': str(address[-2])}]}
+        subnet = self.create_subnet(network, cidr=address,
+                                    mask_bits=address.prefixlen,
+                                    **allocation_pools)
         self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
         body = self.ports_client.create_port(network_id=net_id)
         self.addCleanup(self.ports_client.delete_port, body['port']['id'])
@@ -191,10 +200,10 @@
         self.addCleanup(self.client.delete_router, router['id'])
         port = self.ports_client.create_port(network_id=network['id'])
         # Add router interface to port created above
-        self.client.add_router_interface_with_port_id(
-            router['id'], port['port']['id'])
-        self.addCleanup(self.client.remove_router_interface_with_port_id,
-                        router['id'], port['port']['id'])
+        self.client.add_router_interface(router['id'],
+                                         port_id=port['port']['id'])
+        self.addCleanup(self.client.remove_router_interface, router['id'],
+                        port_id=port['port']['id'])
         # List ports filtered by router_id
         port_list = self.ports_client.list_ports(device_id=router['id'])
         ports = port_list['ports']
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 406ad44..0b64be4 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -137,8 +137,8 @@
         subnet = self.create_subnet(network)
         router = self._create_router(data_utils.rand_name('router-'))
         # Add router interface with subnet id
-        interface = self.client.add_router_interface_with_subnet_id(
-            router['id'], subnet['id'])
+        interface = self.client.add_router_interface(router['id'],
+                                                     subnet_id=subnet['id'])
         self.addCleanup(self._remove_router_interface_with_subnet_id,
                         router['id'], subnet['id'])
         self.assertIn('subnet_id', interface.keys())
@@ -158,8 +158,9 @@
         port_body = self.ports_client.create_port(
             network_id=network['id'])
         # add router interface to port created above
-        interface = self.client.add_router_interface_with_port_id(
-            router['id'], port_body['port']['id'])
+        interface = self.client.add_router_interface(
+            router['id'],
+            port_id=port_body['port']['id'])
         self.addCleanup(self._remove_router_interface_with_port_id,
                         router['id'], port_body['port']['id'])
         self.assertIn('subnet_id', interface.keys())
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 90da6fd..7b07d42 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -84,8 +84,8 @@
     @test.attr(type=['negative'])
     @test.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
     def test_router_remove_interface_in_use_returns_409(self):
-        self.client.add_router_interface_with_subnet_id(
-            self.router['id'], self.subnet['id'])
+        self.client.add_router_interface(self.router['id'],
+                                         subnet_id=self.subnet['id'])
         self.assertRaises(lib_exc.Conflict,
                           self.client.delete_router,
                           self.router['id'])
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index cf45328..7d0765e 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -41,7 +41,8 @@
                                            remote_ip_prefix=None):
         # Create Security Group rule with the input params and validate
         # that SG rule is created with the same parameters.
-        rule_create_body = self.client.create_security_group_rule(
+        sec_group_rules_client = self.security_group_rules_client
+        rule_create_body = sec_group_rules_client.create_security_group_rule(
             security_group_id=sg_id,
             direction=direction,
             ethertype=ethertype,
@@ -116,8 +117,9 @@
 
         # Create rules for each protocol
         protocols = ['tcp', 'udp', 'icmp']
+        client = self.security_group_rules_client
         for protocol in protocols:
-            rule_create_body = self.client.create_security_group_rule(
+            rule_create_body = client.create_security_group_rule(
                 security_group_id=group_create_body['security_group']['id'],
                 protocol=protocol,
                 direction='ingress',
@@ -125,7 +127,7 @@
             )
 
             # Show details of the created security rule
-            show_rule_body = self.client.show_security_group_rule(
+            show_rule_body = client.show_security_group_rule(
                 rule_create_body['security_group_rule']['id']
             )
             create_dict = rule_create_body['security_group_rule']
@@ -135,7 +137,8 @@
                                  "%s does not match." % key)
 
             # List rules and verify created rule is in response
-            rule_list_body = self.client.list_security_group_rules()
+            rule_list_body = (
+                self.security_group_rules_client.list_security_group_rules())
             rule_list = [rule['id']
                          for rule in rule_list_body['security_group_rules']]
             self.assertIn(rule_create_body['security_group_rule']['id'],
@@ -223,7 +226,8 @@
         direction = 'ingress'
         protocol = 17
         security_group_id = group_create_body['security_group']['id']
-        rule_create_body = self.client.create_security_group_rule(
+        client = self.security_group_rules_client
+        rule_create_body = client.create_security_group_rule(
             security_group_id=security_group_id,
             direction=direction,
             protocol=protocol
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index 58e39e9..ff38e9e 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -46,9 +46,10 @@
     @test.idempotent_id('4c094c09-000b-4e41-8100-9617600c02a6')
     def test_show_non_existent_security_group_rule(self):
         non_exist_id = str(uuid.uuid4())
-        self.assertRaises(lib_exc.NotFound,
-                          self.client.show_security_group_rule,
-                          non_exist_id)
+        self.assertRaises(
+            lib_exc.NotFound,
+            self.security_group_rules_client.show_security_group_rule,
+            non_exist_id)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('1f1bb89d-5664-4956-9fcd-83ee0fa603df')
@@ -67,7 +68,8 @@
         # Create rule with bad protocol name
         pname = 'bad_protocol_name'
         self.assertRaises(
-            lib_exc.BadRequest, self.client.create_security_group_rule,
+            lib_exc.BadRequest,
+            self.security_group_rules_client.create_security_group_rule,
             security_group_id=group_create_body['security_group']['id'],
             protocol=pname, direction='ingress', ethertype=self.ethertype)
 
@@ -80,7 +82,8 @@
         prefix = ['192.168.1./24', '192.168.1.1/33', 'bad_prefix', '256']
         for remote_ip_prefix in prefix:
             self.assertRaises(
-                lib_exc.BadRequest, self.client.create_security_group_rule,
+                lib_exc.BadRequest,
+                self.security_group_rules_client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='tcp', direction='ingress', ethertype=self.ethertype,
                 remote_ip_prefix=remote_ip_prefix)
@@ -95,7 +98,8 @@
         group_ids = ['bad_group_id', non_exist_id]
         for remote_group_id in group_ids:
             self.assertRaises(
-                lib_exc.NotFound, self.client.create_security_group_rule,
+                lib_exc.NotFound,
+                self.security_group_rules_client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='tcp', direction='ingress', ethertype=self.ethertype,
                 remote_group_id=remote_group_id)
@@ -109,7 +113,8 @@
         # Create rule specifying both remote_ip_prefix and remote_group_id
         prefix = self._tenant_network_cidr
         self.assertRaises(
-            lib_exc.BadRequest, self.client.create_security_group_rule,
+            lib_exc.BadRequest,
+            self.security_group_rules_client.create_security_group_rule,
             security_group_id=sg1_body['security_group']['id'],
             protocol='tcp', direction='ingress',
             ethertype=self.ethertype, remote_ip_prefix=prefix,
@@ -123,7 +128,8 @@
         # Create rule with bad ethertype
         ethertype = 'bad_ethertype'
         self.assertRaises(
-            lib_exc.BadRequest, self.client.create_security_group_rule,
+            lib_exc.BadRequest,
+            self.security_group_rules_client.create_security_group_rule,
             security_group_id=group_create_body['security_group']['id'],
             protocol='udp', direction='ingress', ethertype=ethertype)
 
@@ -140,7 +146,8 @@
                   (-16, 65536, 'Invalid value for port')]
         for pmin, pmax, msg in states:
             ex = self.assertRaises(
-                lib_exc.BadRequest, self.client.create_security_group_rule,
+                lib_exc.BadRequest,
+                self.security_group_rules_client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='tcp', port_range_min=pmin, port_range_max=pmax,
                 direction='ingress', ethertype=self.ethertype)
@@ -152,7 +159,8 @@
                   (300, 1, 'Invalid value for ICMP type')]
         for pmin, pmax, msg in states:
             ex = self.assertRaises(
-                lib_exc.BadRequest, self.client.create_security_group_rule,
+                lib_exc.BadRequest,
+                self.security_group_rules_client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='icmp', port_range_min=pmin, port_range_max=pmax,
                 direction='ingress', ethertype=self.ethertype)
@@ -176,7 +184,7 @@
         min_port = 66
         max_port = 67
         # Create a rule with valid params
-        self.client.create_security_group_rule(
+        self.security_group_rules_client.create_security_group_rule(
             security_group_id=body['security_group']['id'],
             direction='ingress',
             ethertype=self.ethertype,
@@ -187,7 +195,8 @@
 
         # Try creating the same security group rule, it should fail
         self.assertRaises(
-            lib_exc.Conflict, self.client.create_security_group_rule,
+            lib_exc.Conflict,
+            self.security_group_rules_client.create_security_group_rule,
             security_group_id=body['security_group']['id'],
             protocol='tcp', direction='ingress', ethertype=self.ethertype,
             port_range_min=min_port, port_range_max=max_port)
@@ -197,10 +206,11 @@
     def test_create_security_group_rule_with_non_existent_security_group(self):
         # Create security group rules with not existing security group.
         non_existent_sg = str(uuid.uuid4())
-        self.assertRaises(lib_exc.NotFound,
-                          self.client.create_security_group_rule,
-                          security_group_id=non_existent_sg,
-                          direction='ingress', ethertype=self.ethertype)
+        self.assertRaises(
+            lib_exc.NotFound,
+            self.security_group_rules_client.create_security_group_rule,
+            security_group_id=non_existent_sg,
+            direction='ingress', ethertype=self.ethertype)
 
 
 class NegativeSecGroupIPv6Test(NegativeSecGroupTest):
@@ -221,7 +231,7 @@
             self.assertRaisesRegexp(
                 lib_exc.BadRequest,
                 "Conflicting value ethertype",
-                self.client.create_security_group_rule,
+                self.security_group_rules_client.create_security_group_rule,
                 security_group_id=group_create_body['security_group']['id'],
                 protocol='tcp', direction='ingress',
                 ethertype=pair['ethertype'],
diff --git a/tempest/api/orchestration/stacks/test_limits.py b/tempest/api/orchestration/stacks/test_limits.py
index 2acf97b..315b3e0 100644
--- a/tempest/api/orchestration/stacks/test_limits.py
+++ b/tempest/api/orchestration/stacks/test_limits.py
@@ -33,7 +33,7 @@
   Foo: bar''' % fill
         ex = self.assertRaises(lib_exc.BadRequest, self.create_stack,
                                stack_name, template)
-        self.assertIn('Template exceeds maximum allowed size', str(ex))
+        self.assertIn('exceeds maximum allowed size', str(ex))
 
     @test.idempotent_id('d1b83e73-7cad-4a22-9839-036548c5387c')
     def test_exceed_max_resources_per_stack(self):
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 8466e11..09e863e 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -16,7 +16,6 @@
 import netaddr
 
 from tempest.api.orchestration import base
-from tempest.common import credentials_factory as credentials
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -37,8 +36,8 @@
 
     @classmethod
     def setup_credentials(cls):
+        cls.set_network_resources()
         super(NeutronResourcesTestJSON, cls).setup_credentials()
-        cls.os = credentials.ConfiguredUserManager()
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index bbf6db2..ff06810 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -17,6 +17,7 @@
 
 from tempest.common import compute
 from tempest.common.utils import data_utils
+from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
 import tempest.test
@@ -97,8 +98,14 @@
                 pass
 
     @classmethod
+    def wait_for_server_termination(cls, server_id):
+        waiters.wait_for_server_termination(cls.servers_client,
+                                            server_id)
+
+    @classmethod
     def resource_cleanup(cls):
         cls.cleanup_resources(cls.servers_client.delete_server, cls.server_ids)
+        cls.cleanup_resources(cls.wait_for_server_termination, cls.server_ids)
         cls.cleanup_resources(cls.image_client.delete_image, cls.image_ids)
         super(BaseTelemetryTest, cls).resource_cleanup()
 
diff --git a/tempest/api_schema/response/messaging/__init__.py b/tempest/api_schema/response/compute/v2_2/__init__.py
similarity index 100%
rename from tempest/api_schema/response/messaging/__init__.py
rename to tempest/api_schema/response/compute/v2_2/__init__.py
diff --git a/tempest/api_schema/response/compute/v2_2/keypairs.py b/tempest/api_schema/response/compute/v2_2/keypairs.py
new file mode 100644
index 0000000..5d8d24d
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_2/keypairs.py
@@ -0,0 +1,41 @@
+# Copyright 2016 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import copy
+
+from tempest.api_schema.response.compute.v2_1 import keypairs
+
+get_keypair = copy.deepcopy(keypairs.get_keypair)
+get_keypair['response_body']['properties']['keypair'][
+    'properties'].update({'type': {'type': 'string'}})
+get_keypair['response_body']['properties']['keypair'][
+    'required'].append('type')
+
+create_keypair = copy.deepcopy(keypairs.create_keypair)
+create_keypair['status_code'] = [201]
+create_keypair['response_body']['properties']['keypair'][
+    'properties'].update({'type': {'type': 'string'}})
+create_keypair['response_body']['properties']['keypair'][
+    'required'].append('type')
+
+delete_keypair = {
+    'status_code': [204],
+}
+
+list_keypairs = copy.deepcopy(keypairs.list_keypairs)
+list_keypairs['response_body']['properties']['keypairs'][
+    'items']['properties']['keypair'][
+    'properties'].update({'type': {'type': 'string'}})
+list_keypairs['response_body']['properties']['keypairs'][
+    'items']['properties']['keypair']['required'].append('type')
diff --git a/tempest/api_schema/response/messaging/v1/__init__.py b/tempest/api_schema/response/messaging/v1/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api_schema/response/messaging/v1/__init__.py
+++ /dev/null
diff --git a/tempest/api_schema/response/messaging/v1/queues.py b/tempest/api_schema/response/messaging/v1/queues.py
deleted file mode 100644
index 09e0147..0000000
--- a/tempest/api_schema/response/messaging/v1/queues.py
+++ /dev/null
@@ -1,239 +0,0 @@
-
-# Copyright (c) 2014 Rackspace, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-list_link = {
-    'type': 'object',
-    'properties': {
-        'rel': {'type': 'string'},
-        'href': {
-            'type': 'string',
-            'format': 'uri'
-        }
-    },
-    'required': ['href', 'rel']
-}
-
-list_queue = {
-    'type': 'object',
-    'properties': {
-        'name': {'type': 'string'},
-        'href': {
-            'type': 'string',
-            'format': 'uri'
-        },
-        'metadata': {'type': 'object'}
-    },
-    'required': ['name', 'href']
-}
-
-list_queues = {
-    'status_code': [200, 204],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'links': {
-                'type': 'array',
-                'items': list_link,
-                'maxItems': 1
-            },
-            'queues': {
-                'type': 'array',
-                'items': list_queue
-            }
-        },
-        'required': ['links', 'queues']
-    }
-}
-
-age = {
-    'type': 'number',
-    'minimum': 0
-}
-
-message_link = {
-    'type': 'object',
-    'properties': {
-        'href': {
-            'type': 'string',
-            'format': 'uri'
-        },
-        'age': age,
-        'created': {
-            'type': 'string',
-            'format': 'date-time'
-        }
-    },
-    'required': ['href', 'age', 'created']
-}
-
-messages = {
-    'type': 'object',
-    'properties': {
-        'free': {'type': 'number'},
-        'claimed': {'type': 'number'},
-        'total': {'type': 'number'},
-        'oldest': message_link,
-        'newest': message_link
-    },
-    'required': ['free', 'claimed', 'total']
-}
-
-queue_stats = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'messages': messages
-        },
-        'required': ['messages']
-    }
-}
-
-resource_schema = {
-    'type': 'array',
-    'items': {
-        'type': 'string'
-    },
-    'minItems': 1
-}
-
-post_messages = {
-    'status_code': [201],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'resources': resource_schema,
-            'partial': {'type': 'boolean'}
-        }
-    },
-    'required': ['resources', 'partial']
-}
-
-message_ttl = {
-    'type': 'number',
-    'minimum': 1
-}
-
-list_messages_links = {
-    'type': 'array',
-    'maxItems': 1,
-    'minItems': 1,
-    'items': {
-        'type': 'object',
-        'properties': {
-            'rel': {'type': 'string'},
-            'href': {'type': 'string'}
-        },
-        'required': ['rel', 'href']
-    }
-}
-
-list_messages_response = {
-    'type': 'array',
-    'minItems': 1,
-    'items': {
-        'type': 'object',
-        'properties': {
-            'href': {'type': 'string'},
-            'ttl': message_ttl,
-            'age': age,
-            'body': {'type': 'object'}
-        },
-        'required': ['href', 'ttl', 'age', 'body']
-    }
-}
-
-list_messages = {
-    'status_code': [200, 204],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'links': list_messages_links,
-            'messages': list_messages_response
-        }
-    },
-    'required': ['links', 'messages']
-}
-
-single_message = {
-    'type': 'object',
-    'properties': {
-        'href': {'type': 'string'},
-        'ttl': message_ttl,
-        'age': age,
-        'body': {'type': 'object'}
-    },
-    'required': ['href', 'ttl', 'age', 'body']
-}
-
-get_single_message = {
-    'status_code': [200],
-    'response_body': single_message
-}
-
-get_multiple_messages = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'array',
-        'items': single_message,
-        'minItems': 1
-    }
-}
-
-messages_claimed = {
-    'type': 'object',
-    'properties': {
-        'href': {
-            'type': 'string',
-            'format': 'uri'
-        },
-        'ttl': message_ttl,
-        'age': {'type': 'number'},
-        'body': {'type': 'object'}
-    },
-    'required': ['href', 'ttl', 'age', 'body']
-}
-
-claim_messages = {
-    'status_code': [201, 204],
-    'response_body': {
-        'type': 'array',
-        'items': messages_claimed,
-        'minItems': 1
-    }
-}
-
-claim_ttl = {
-    'type': 'number',
-    'minimum': 1
-}
-
-query_claim = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'age': {'type': 'number'},
-            'ttl': claim_ttl,
-            'messages': {
-                'type': 'array',
-                'minItems': 1
-            }
-        },
-        'required': ['ttl', 'age', 'messages']
-    }
-}
diff --git a/tempest/clients.py b/tempest/clients.py
index cae90b0..2a8a4ae 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -70,7 +70,23 @@
     VolumesClient as ComputeVolumesClient
 from tempest_lib.services.identity.v2.token_client import TokenClient
 from tempest_lib.services.identity.v3.token_client import V3TokenClient
+from tempest_lib.services.network.agents_client import AgentsClient \
+    as NetworkAgentsClient
+from tempest_lib.services.network.extensions_client import \
+    ExtensionsClient as NetworkExtensionsClient
 from tempest_lib.services.network.floating_ips_client import FloatingIPsClient
+from tempest_lib.services.network.metering_label_rules_client import \
+    MeteringLabelRulesClient
+from tempest_lib.services.network.metering_labels_client import \
+    MeteringLabelsClient
+from tempest_lib.services.network.networks_client import NetworksClient
+from tempest_lib.services.network.ports_client import PortsClient
+from tempest_lib.services.network.quotas_client import QuotasClient \
+    as NetworkQuotasClient
+from tempest_lib.services.network.security_groups_client import \
+    SecurityGroupsClient
+from tempest_lib.services.network.subnetpools_client import SubnetpoolsClient
+from tempest_lib.services.network.subnets_client import SubnetsClient
 
 from tempest.common import negative_rest_client
 from tempest import config
@@ -87,10 +103,14 @@
     DatabaseLimitsClient
 from tempest.services.database.json.versions_client import \
     DatabaseVersionsClient
+from tempest.services.identity.v2.json.endpoints_client import \
+    EndpointsClient as EndpointsV2Client
 from tempest.services.identity.v2.json.identity_client import \
     IdentityClient
 from tempest.services.identity.v2.json.roles_client import \
     RolesClient
+from tempest.services.identity.v2.json.services_client import \
+    ServicesClient as ServicesV2Client
 from tempest.services.identity.v2.json.tenants_client import \
     TenantsClient
 from tempest.services.identity.v2.json.users_client import \
@@ -104,29 +124,17 @@
 from tempest.services.identity.v3.json.identity_client import IdentityV3Client
 from tempest.services.identity.v3.json.policies_client import \
     PoliciesClient as PoliciesV3Client
+from tempest.services.identity.v3.json.projects_client import ProjectsClient
 from tempest.services.identity.v3.json.regions_client import \
     RegionsClient as RegionsV3Client
 from tempest.services.identity.v3.json.services_client import \
     ServicesClient as IdentityServicesV3Client
+from tempest.services.identity.v3.json.users_clients import UsersV3Client
 from tempest.services.image.v1.json.images_client import ImagesClient
 from tempest.services.image.v2.json.images_client import ImagesClientV2
-from tempest.services.messaging.json.messaging_client import \
-    MessagingClient
-from tempest.services.network.json.agents_client import AgentsClient \
-    as NetworkAgentsClient
-from tempest.services.network.json.metering_label_rules_client import \
-    MeteringLabelRulesClient
-from tempest.services.network.json.metering_labels_client import \
-    MeteringLabelsClient
 from tempest.services.network.json.network_client import NetworkClient
-from tempest.services.network.json.networks_client import NetworksClient
-from tempest.services.network.json.ports_client import PortsClient
-from tempest.services.network.json.quotas_client import QuotasClient \
-    as NetworkQuotasClient
-from tempest.services.network.json.security_groups_client import \
-    SecurityGroupsClient
-from tempest.services.network.json.subnetpools_client import SubnetpoolsClient
-from tempest.services.network.json.subnets_client import SubnetsClient
+from tempest.services.network.json.security_group_rules_client import \
+    SecurityGroupRulesClient
 from tempest.services.object_storage.account_client import AccountClient
 from tempest.services.object_storage.container_client import ContainerClient
 from tempest.services.object_storage.object_client import ObjectClient
@@ -238,6 +246,14 @@
             build_interval=CONF.network.build_interval,
             build_timeout=CONF.network.build_timeout,
             **self.default_params)
+        self.network_extensions_client = NetworkExtensionsClient(
+            self.auth_provider,
+            CONF.network.catalog_type,
+            CONF.network.region or CONF.identity.region,
+            endpoint_type=CONF.network.endpoint_type,
+            build_interval=CONF.network.build_interval,
+            build_timeout=CONF.network.build_timeout,
+            **self.default_params)
         self.network_client = NetworkClient(
             self.auth_provider,
             CONF.network.catalog_type,
@@ -310,6 +326,14 @@
             build_interval=CONF.network.build_interval,
             build_timeout=CONF.network.build_timeout,
             **self.default_params)
+        self.security_group_rules_client = SecurityGroupRulesClient(
+            self.auth_provider,
+            CONF.network.catalog_type,
+            CONF.network.region or CONF.identity.region,
+            endpoint_type=CONF.network.endpoint_type,
+            build_interval=CONF.network.build_interval,
+            build_timeout=CONF.network.build_timeout,
+            **self.default_params)
         self.security_groups_client = SecurityGroupsClient(
             self.auth_provider,
             CONF.network.catalog_type,
@@ -318,11 +342,6 @@
             build_interval=CONF.network.build_interval,
             build_timeout=CONF.network.build_timeout,
             **self.default_params)
-        self.messaging_client = MessagingClient(
-            self.auth_provider,
-            CONF.messaging.catalog_type,
-            CONF.identity.region,
-            **self.default_params_with_timeout_values)
         if CONF.service_available.ceilometer:
             self.telemetry_client = TelemetryClient(
                 self.auth_provider,
@@ -477,9 +496,12 @@
             'region': CONF.identity.region
         }
         params.update(self.default_params_with_timeout_values)
+
+        # Clients below use the admin endpoint type of Keystone API v2
         params_v2_admin = params.copy()
         params_v2_admin['endpoint_type'] = CONF.identity.v2_admin_endpoint_type
-        # Client uses admin endpoint type of Keystone API v2
+        self.endpoints_v2_client = EndpointsV2Client(self.auth_provider,
+                                                     **params_v2_admin)
         self.identity_client = IdentityClient(self.auth_provider,
                                               **params_v2_admin)
         self.tenants_client = TenantsClient(self.auth_provider,
@@ -488,33 +510,38 @@
                                         **params_v2_admin)
         self.users_client = UsersClient(self.auth_provider,
                                         **params_v2_admin)
+        self.services_v2_client = ServicesV2Client(self.auth_provider,
+                                                   **params_v2_admin)
+
+        # Clients below use the public endpoint type of Keystone API v2
         params_v2_public = params.copy()
         params_v2_public['endpoint_type'] = (
             CONF.identity.v2_public_endpoint_type)
-        # Client uses public endpoint type of Keystone API v2
         self.identity_public_client = IdentityClient(self.auth_provider,
                                                      **params_v2_public)
         self.tenants_public_client = TenantsClient(self.auth_provider,
                                                    **params_v2_public)
-        self.roles_public_client = RolesClient(self.auth_provider,
-                                               **params_v2_public)
         self.users_public_client = UsersClient(self.auth_provider,
                                                **params_v2_public)
+
+        # Clients below use the endpoint type of Keystone API v3
         params_v3 = params.copy()
         params_v3['endpoint_type'] = CONF.identity.v3_endpoint_type
-        # Clients below use the endpoint type of Keystone API v3
         self.identity_v3_client = IdentityV3Client(self.auth_provider,
                                                    **params_v3)
+        self.users_v3_client = UsersV3Client(self.auth_provider, **params_v3)
         self.endpoints_client = EndPointV3Client(self.auth_provider,
                                                  **params_v3)
         self.identity_services_client = IdentityServicesV3Client(
             self.auth_provider, **params_v3)
         self.policies_client = PoliciesV3Client(self.auth_provider,
                                                 **params_v3)
+        self.projects_client = ProjectsClient(self.auth_provider, **params_v3)
         self.regions_client = RegionsV3Client(self.auth_provider, **params_v3)
         self.credentials_client = CredentialsV3Client(self.auth_provider,
                                                       **params_v3)
         self.groups_client = GroupsV3Client(self.auth_provider, **params_v3)
+
         # Token clients do not use the catalog. They only need default_params.
         # They read auth_url, so they should only be set if the corresponding
         # API version is marked as enabled
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 6f74578..9e98d90 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -85,11 +85,15 @@
 import argparse
 import netaddr
 import os
+import traceback
 
+from cliff import command
 from oslo_log import log as logging
 import tempest_lib.auth
 from tempest_lib.common.utils import data_utils
 import tempest_lib.exceptions
+from tempest_lib.services.network import networks_client
+from tempest_lib.services.network import subnets_client
 import yaml
 
 from tempest.common import identity
@@ -100,11 +104,14 @@
 from tempest.services.identity.v2.json import tenants_client
 from tempest.services.identity.v2.json import users_client
 from tempest.services.network.json import network_client
-from tempest.services.network.json import networks_client
-from tempest.services.network.json import subnets_client
 
 LOG = None
 CONF = config.CONF
+DESCRIPTION = ('Create accounts.yaml file for concurrent test runs.%s'
+               'One primary user, one alt user, '
+               'one swift admin, one stack owner '
+               'and one admin (optionally) will be created '
+               'for each concurrent thread.' % os.linesep)
 
 
 def setup_logging():
@@ -305,8 +312,8 @@
         return resp_body['router']
 
     def _add_router_interface(router_id, subnet_id):
-        network_admin_client.add_router_interface_with_subnet_id(
-            router_id, subnet_id)
+        network_admin_client.add_router_interface(router_id,
+                                                  subnet_id=subnet_id)
 
     network_name = name + "-network"
     network = _create_network(network_name)
@@ -383,7 +390,7 @@
             'password': user['pass'],
             'roles': user['roles']
         }
-        if 'network' or 'router' in user:
+        if 'network' in user or 'router' in user:
             account['resources'] = {}
         if 'network' in user:
             account['resources']['network'] = user['network']
@@ -397,20 +404,7 @@
     LOG.info('%s generated successfully!' % opts.accounts)
 
 
-def get_options():
-    usage_string = ('tempest-account-generator [-h] <ARG> ...\n\n'
-                    'To see help on specific argument, do:\n'
-                    'tempest-account-generator <ARG> -h')
-    parser = argparse.ArgumentParser(
-        description='Create accounts.yaml file for concurrent test runs. '
-                    'One primary user, one alt user, '
-                    'one swift admin, one stack owner '
-                    'and one admin (optionally) will be created '
-                    'for each concurrent thread.',
-        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
-        usage=usage_string
-    )
-
+def _parser_add_args(parser):
     parser.add_argument('-c', '--config-file',
                         metavar='/etc/tempest.conf',
                         help='path to tempest config file')
@@ -447,16 +441,50 @@
                         metavar='accounts_file.yaml',
                         help='Output accounts yaml file')
 
+
+def get_options():
+    usage_string = ('tempest-account-generator [-h] <ARG> ...\n\n'
+                    'To see help on specific argument, do:\n'
+                    'tempest-account-generator <ARG> -h')
+    parser = argparse.ArgumentParser(
+        description=DESCRIPTION,
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+        usage=usage_string
+    )
+
+    _parser_add_args(parser)
     opts = parser.parse_args()
-    if opts.config_file:
-        config.CONF.set_config_path(opts.config_file)
     return opts
 
 
+class TempestAccountGenerator(command.Command):
+
+    def get_parser(self, prog_name):
+        parser = super(TempestAccountGenerator, self).get_parser(prog_name)
+        _parser_add_args(parser)
+        return parser
+
+    def take_action(self, parsed_args):
+        try:
+            return main(parsed_args)
+        except Exception:
+            LOG.exception("Failure generating test accounts.")
+            traceback.print_exc()
+            raise
+        return 0
+
+    def get_description(self):
+        return DESCRIPTION
+
+
 def main(opts=None):
-    if not opts:
-        opts = get_options()
     setup_logging()
+    if not opts:
+        LOG.warn("Use of: 'tempest-account-generator' is deprecated, "
+                 "please use: 'tempest account-generator'")
+        opts = get_options()
+    if opts.config_file:
+        config.CONF.set_config_path(opts.config_file)
     resources = generate_resources(opts)
     create_resources(opts, resources)
     dump_accounts(opts, resources)
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index 7b73a61..5a52043 100644
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -77,7 +77,8 @@
     def take_action(self, parsed_args):
         try:
             self.init(parsed_args)
-            self._cleanup()
+            if not parsed_args.init_saved_state:
+                self._cleanup()
         except Exception:
             LOG.exception("Failure during cleanup")
             traceback.print_exc()
@@ -231,7 +232,6 @@
         return 'Cleanup after tempest run'
 
     def _add_admin(self, tenant_id):
-        id_cl = self.admin_mgr.identity_client
         rl_cl = self.admin_mgr.roles_client
         needs_role = True
         roles = rl_cl.list_user_roles(tenant_id, self.admin_id)['roles']
@@ -241,7 +241,7 @@
                 LOG.debug("User already had admin privilege for this tenant")
         if needs_role:
             LOG.debug("Adding admin privilege for : %s" % tenant_id)
-            id_cl.assign_user_role(tenant_id, self.admin_id,
+            rl_cl.assign_user_role(tenant_id, self.admin_id,
                                    self.admin_role_id)
             self.admin_role_added.append(tenant_id)
 
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 8a47406..5ec8008 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -78,7 +78,7 @@
 
     if IS_NEUTRON:
         CONF_PRIV_NETWORK = _get_network_id(CONF.compute.fixed_network_name,
-                                            CONF.identity.tenant_name)
+                                            CONF.auth.admin_tenant_name)
         CONF_NETWORKS = [CONF_PUB_NETWORK, CONF_PRIV_NETWORK]
 
 
@@ -469,8 +469,7 @@
                          in client.list_router_interfaces(rid)['ports']
                          if port["device_owner"] == "network:router_interface"]
                 for port in ports:
-                    client.remove_router_interface_with_port_id(rid,
-                                                                port['id'])
+                    client.remove_router_interface(rid, port_id=port['id'])
                 client.delete_router(rid)
             except Exception:
                 LOG.exception("Delete Router exception.")
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index a703e8c..e26a014 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -122,6 +122,7 @@
 from tempest_lib.services.compute import security_group_rules_client
 from tempest_lib.services.compute import security_groups_client
 from tempest_lib.services.compute import servers_client
+from tempest_lib.services.network import subnets_client
 import yaml
 
 from tempest.common import identity
@@ -133,7 +134,6 @@
 from tempest.services.identity.v2.json import users_client
 from tempest.services.image.v2.json import images_client
 from tempest.services.network.json import network_client
-from tempest.services.network.json import subnets_client
 from tempest.services.object_storage import container_client
 from tempest.services.object_storage import object_client
 from tempest.services.telemetry.json import alarming_client
@@ -841,8 +841,8 @@
         for subnet in router['subnet']:
             subnet_id = _get_resource_by_name(client.networks,
                                               'subnets', subnet)['id']
-            client.networks.remove_router_interface_with_subnet_id(router_id,
-                                                                   subnet_id)
+            client.networks.remove_router_interface(router_id,
+                                                    subnet_id=subnet_id)
         client.networks.delete_router(router_id)
 
 
@@ -856,8 +856,8 @@
             subnet_id = _get_resource_by_name(client.networks,
                                               'subnets', subnet)['id']
             # connect routers to their subnets
-            client.networks.add_router_interface_with_subnet_id(router_id,
-                                                                subnet_id)
+            client.networks.add_router_interface(router_id,
+                                                 subnet_id=subnet_id)
         # connect routers to external network if set to "gateway"
         if router['gateway']:
             if CONF.network.public_network_id:
diff --git a/tempest/cmd/main.py b/tempest/cmd/main.py
index 577df9b..acd97a8 100644
--- a/tempest/cmd/main.py
+++ b/tempest/cmd/main.py
@@ -28,6 +28,7 @@
             description='Tempest cli application',
             version=version.VersionInfo('tempest').version_string(),
             command_manager=commandmanager.CommandManager('tempest.cm'),
+            deferred_help=True,
             )
 
     def initialize_app(self, argv):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
old mode 100755
new mode 100644
index 9c8e2a0..5e5e127
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -15,10 +15,13 @@
 #    under the License.
 
 import argparse
+import httplib2
 import os
 import sys
+import traceback
 
-import httplib2
+from cliff import command
+from oslo_log import log as logging
 from oslo_serialization import jsonutils as json
 from six import moves
 from six.moves.urllib import parse as urlparse
@@ -31,6 +34,8 @@
 CONF = config.CONF
 CONF_PARSER = None
 
+LOG = logging.getLogger(__name__)
+
 
 def _get_config_file():
     default_config_dir = os.path.join(os.path.abspath(
@@ -141,7 +146,7 @@
     extensions_client = {
         'nova': os.extensions_client,
         'cinder': os.volumes_extension_client,
-        'neutron': os.network_client,
+        'neutron': os.network_extensions_client,
         'swift': os.account_client,
     }
     # NOTE (e0ne): Use Cinder API v2 by default because v1 is deprecated
@@ -152,7 +157,7 @@
 
     if service not in extensions_client:
         print('No tempest extensions client for %s' % service)
-        exit(1)
+        sys.exit(1)
     return extensions_client[service]
 
 
@@ -165,7 +170,7 @@
     }
     if service not in extensions_options:
         print('No supported extensions list option for %s' % service)
-        exit(1)
+        sys.exit(1)
     return extensions_options[service]
 
 
@@ -264,7 +269,6 @@
         'data_processing': 'sahara',
         'baremetal': 'ironic',
         'identity': 'keystone',
-        'messaging': 'zaqar',
         'database': 'trove'
     }
     # Get catalog list for endpoints to use for validation
@@ -310,8 +314,7 @@
     return avail_services
 
 
-def parse_args():
-    parser = argparse.ArgumentParser()
+def _parser_add_args(parser):
     parser.add_argument('-u', '--update', action='store_true',
                         help='Update the config file with results from api '
                              'queries. This assumes whatever is set in the '
@@ -329,13 +332,21 @@
     parser.add_argument('-r', '--replace-ext', action='store_true',
                         help="If specified the all option will be replaced "
                              "with a full list of extensions")
-    args = parser.parse_args()
-    return args
 
 
-def main():
+def parse_args():
+    parser = argparse.ArgumentParser()
+    _parser_add_args(parser)
+    opts = parser.parse_args()
+    return opts
+
+
+def main(opts=None):
     print('Running config verification...')
-    opts = parse_args()
+    if opts is None:
+        print("Use of: 'verify-tempest-config' is deprecated, "
+              "please use: 'tempest verify-config'")
+        opts = parse_args()
     update = opts.update
     replace = opts.replace_ext
     global CONF_PARSER
@@ -373,5 +384,22 @@
         icreds.clear_creds()
 
 
+class TempestVerifyConfig(command.Command):
+    """Verify your current tempest configuration"""
+
+    def get_parser(self, prog_name):
+        parser = super(TempestVerifyConfig, self).get_parser(prog_name)
+        _parser_add_args(parser)
+        return parser
+
+    def take_action(self, parsed_args):
+        try:
+            return main(parsed_args)
+        except Exception:
+            LOG.exception("Failure verifying configuration.")
+            traceback.print_exc()
+            raise
+        return 0
+
 if __name__ == "__main__":
     main()
diff --git a/tempest/common/api_version_utils.py b/tempest/common/api_version_utils.py
index ac3322e..c3d977f 100644
--- a/tempest/common/api_version_utils.py
+++ b/tempest/common/api_version_utils.py
@@ -38,13 +38,13 @@
     config_max_version = api_version_request.APIVersionRequest(cfg_max_version)
     if ((min_version > max_version) or
        (config_min_version > config_max_version)):
-        msg = ("Min version is greater than Max version. Test Class versions "
-               "[%s - %s]. configuration versions [%s - %s]."
+        msg = ("Test Class versions [%s - %s]. "
+               "Configuration versions [%s - %s]."
                % (min_version.get_string(),
                   max_version.get_string(),
                   config_min_version.get_string(),
                   config_max_version.get_string()))
-        raise exceptions.InvalidConfiguration(msg)
+        raise exceptions.InvalidAPIVersionRange(msg)
 
     # NOTE: Select tests which are in range of configuration like
     #               config min           config max
@@ -69,3 +69,27 @@
     cfg_version = api_version_request.APIVersionRequest(cfg_min_version)
     max_version = cfg_version if cfg_version >= test_version else test_version
     return max_version.get_string()
+
+
+def assert_version_header_matches_request(api_microversion_header_name,
+                                          api_microversion,
+                                          response_header):
+    """Checks API microversion in resposne header
+
+    Verify whether microversion is present in response header
+    and with specified 'api_microversion' value.
+
+    @param: api_microversion_header_name: Microversion header name
+            Example- "X-OpenStack-Nova-API-Version"
+    @param: api_microversion: Microversion number like "2.10"
+    @param: response_header: Response header where microversion is
+            expected to be present.
+    """
+    api_microversion_header_name = api_microversion_header_name.lower()
+    if (api_microversion_header_name not in response_header or
+        api_microversion != response_header[api_microversion_header_name]):
+        msg = ("Microversion header '%s' with value '%s' does not match in "
+               "response - %s. " % (api_microversion_header_name,
+                                    api_microversion,
+                                    response_header))
+        raise exceptions.InvalidHTTPResponseHeader(msg)
diff --git a/tempest/common/commands.py b/tempest/common/commands.py
deleted file mode 100644
index 392c9d0..0000000
--- a/tempest/common/commands.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# 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 shlex
-import subprocess
-
-from oslo_log import log as logging
-
-LOG = logging.getLogger(__name__)
-
-
-def copy_file_to_host(file_from, dest, host, username, pkey):
-    dest = "%s@%s:%s" % (username, host, dest)
-    cmd = "scp -v -o UserKnownHostsFile=/dev/null " \
-          "-o StrictHostKeyChecking=no " \
-          "-i %(pkey)s %(file1)s %(dest)s" % {'pkey': pkey,
-                                              'file1': file_from,
-                                              'dest': dest}
-    args = shlex.split(cmd.encode('utf-8'))
-    subprocess_args = {'stdout': subprocess.PIPE,
-                       'stderr': subprocess.STDOUT}
-    proc = subprocess.Popen(args, **subprocess_args)
-    stdout, stderr = proc.communicate()
-    if proc.returncode != 0:
-        LOG.error(("Command {0} returned with exit status {1},"
-                  "output {2}, error {3}").format(cmd, proc.returncode,
-                                                  stdout, stderr))
-    return stdout
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 6e6ada8..73505e6 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -29,7 +29,8 @@
 
 def create_test_server(clients, validatable=False, validation_resources=None,
                        tenant_network=None, wait_until=None,
-                       volume_backed=False, **kwargs):
+                       volume_backed=False, name=None, flavor=None,
+                       image_id=None, **kwargs):
     """Common wrapper utility returning a test server.
 
     This method is a common wrapper returning a test server that can be
@@ -48,17 +49,27 @@
 
     # TODO(jlanoux) add support of wait_until PINGABLE/SSHABLE
 
-    name = kwargs.pop('name', data_utils.rand_name(__name__ + "-instance"))
-    flavor = kwargs.pop('flavor', CONF.compute.flavor_ref)
-    image_id = kwargs.pop('image_id', CONF.compute.image_ref)
+    name = name
+    flavor = flavor
+    image_id = image_id
+
+    if name is None:
+        name = data_utils.rand_name(__name__ + "-instance")
+    if flavor is None:
+        flavor = CONF.compute.flavor_ref
+    if image_id is None:
+        image_id = CONF.compute.image_ref
 
     kwargs = fixed_network.set_networks_kwarg(
         tenant_network, kwargs) or {}
 
+    multiple_create_request = (max(kwargs.get('min_count', 0),
+                                   kwargs.get('max_count', 0)) > 1)
+
     if CONF.validation.run_validation and validatable:
         # As a first implementation, multiple pingable or sshable servers will
         # not be supported
-        if 'min_count' in kwargs or 'max_count' in kwargs:
+        if multiple_create_request:
             msg = ("Multiple pingable or sshable servers not supported at "
                    "this stage.")
             raise ValueError(msg)
@@ -112,7 +123,7 @@
 
     # handle the case of multiple servers
     servers = []
-    if 'min_count' in kwargs or 'max_count' in kwargs:
+    if multiple_create_request:
         # Get servers created which name match with name param.
         body_servers = clients.servers_client.list_servers()
         servers = \
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index 6df7eb2..5aa794c 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -31,15 +31,15 @@
      admin credentials used for generating credentials.
     """
 
-    def __init__(self, identity_client, projects_client=None,
-                 roles_client=None, users_client=None):
+    def __init__(self, identity_client, projects_client, users_client,
+                 roles_client=None):
         # The client implies version and credentials
         self.identity_client = identity_client
-        # this is temporary until the v3 project client is
-        # separated, then projects_client will become mandatory
-        self.projects_client = projects_client or identity_client
+        self.users_client = users_client
+        self.projects_client = projects_client
+        # this is temporary until the v3 clients are
+        # separated, then using *only* each client will become mandatory
         self.roles_client = roles_client or identity_client
-        self.users_client = users_client or identity_client
 
     def create_user(self, username, password, project, email):
         user = self.users_client.create_user(
@@ -48,6 +48,9 @@
             user = user['user']
         return user
 
+    def delete_user(self, user_id):
+        self.users_client.delete_user(user_id)
+
     @abc.abstractmethod
     def create_project(self, name, description):
         pass
@@ -70,8 +73,7 @@
             msg = 'No "%s" role found' % role_name
             raise lib_exc.NotFound(msg)
         try:
-            self.roles_client.assign_user_role(project['id'], user['id'],
-                                               role['id'])
+            self._assign_user_role(project, user, role)
         except lib_exc.Conflict:
             LOG.debug("Role %s already assigned on project %s for user %s" % (
                 role['id'], project['id'], user['id']))
@@ -87,9 +89,6 @@
         """
         pass
 
-    def delete_user(self, user_id):
-        self.users_client.delete_user(user_id)
-
     def _list_roles(self):
         roles = self.roles_client.list_roles()['roles']
         return roles
@@ -97,18 +96,21 @@
 
 class V2CredsClient(CredsClient):
 
-    def __init__(self, identity_client, projects_client, roles_client,
-                 users_client):
+    def __init__(self, identity_client, projects_client, users_client,
+                 roles_client):
         super(V2CredsClient, self).__init__(identity_client,
                                             projects_client,
-                                            roles_client,
-                                            users_client)
+                                            users_client,
+                                            roles_client)
 
     def create_project(self, name, description):
         tenant = self.projects_client.create_tenant(
             name=name, description=description)['tenant']
         return tenant
 
+    def delete_project(self, project_id):
+        self.projects_client.delete_tenant(project_id)
+
     def get_credentials(self, user, project, password):
         # User and project already include both ID and name here,
         # so there's no need to use the fill_in mode
@@ -120,14 +122,17 @@
             tenant_name=project['name'], tenant_id=project['id'],
             password=password)
 
-    def delete_project(self, project_id):
-        self.projects_client.delete_tenant(project_id)
+    def _assign_user_role(self, project, user, role):
+        self.roles_client.assign_user_role(project['id'], user['id'],
+                                           role['id'])
 
 
 class V3CredsClient(CredsClient):
 
-    def __init__(self, identity_client, domain_name):
-        super(V3CredsClient, self).__init__(identity_client)
+    def __init__(self, identity_client, projects_client, users_client,
+                 domain_name):
+        super(V3CredsClient, self).__init__(identity_client,
+                                            projects_client, users_client)
         try:
             # Domain names must be unique, in any case a list is returned,
             # selecting the first (and only) element
@@ -139,11 +144,14 @@
             raise lib_exc.InvalidCredentials(msg)
 
     def create_project(self, name, description):
-        project = self.identity_client.create_project(
+        project = self.projects_client.create_project(
             name=name, description=description,
             domain_id=self.creds_domain['id'])['project']
         return project
 
+    def delete_project(self, project_id):
+        self.projects_client.delete_project(project_id)
+
     def get_credentials(self, user, project, password):
         # User, project and domain already include both ID and name here,
         # so there's no need to use the fill_in mode.
@@ -157,21 +165,24 @@
             project_domain_id=self.creds_domain['id'],
             project_domain_name=self.creds_domain['name'])
 
-    def delete_project(self, project_id):
-        self.identity_client.delete_project(project_id)
-
     def _list_roles(self):
         roles = self.identity_client.list_roles()['roles']
         return roles
 
+    def _assign_user_role(self, project, user, role):
+        self.roles_client.assign_user_role_on_project(project['id'],
+                                                      user['id'],
+                                                      role['id'])
+
 
 def get_creds_client(identity_client,
-                     projects_client=None,
+                     projects_client,
+                     users_client,
                      roles_client=None,
-                     users_client=None,
                      project_domain_name=None):
     if isinstance(identity_client, v2_identity.IdentityClient):
-        return V2CredsClient(identity_client, projects_client, roles_client,
-                             users_client)
+        return V2CredsClient(identity_client, projects_client, users_client,
+                             roles_client)
     else:
-        return V3CredsClient(identity_client, project_domain_name)
+        return V3CredsClient(identity_client, projects_client, users_client,
+                             project_domain_name)
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 95ad229..1810c57 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -57,9 +57,10 @@
         self._creds = {}
         self.ports = []
         self.default_admin_creds = admin_creds
-        (self.identity_admin_client, self.tenants_admin_client,
-         self.roles_admin_client,
+        (self.identity_admin_client,
+         self.tenants_admin_client,
          self.users_admin_client,
+         self.roles_admin_client,
          self.network_admin_client,
          self.networks_admin_client,
          self.subnets_admin_client,
@@ -75,8 +76,8 @@
         self.creds_client = cred_client.get_creds_client(
             self.identity_admin_client,
             self.tenants_admin_client,
-            self.roles_admin_client,
             self.users_admin_client,
+            self.roles_admin_client,
             self.creds_domain_name)
 
     def _get_admin_clients(self):
@@ -88,12 +89,13 @@
         """
         os = clients.Manager(self.default_admin_creds)
         if self.identity_version == 'v2':
-            return (os.identity_client, os.tenants_client, os.roles_client,
-                    os.users_client, os.network_client, os.networks_client,
+            return (os.identity_client, os.tenants_client, os.users_client,
+                    os.roles_client, os.network_client, os.networks_client,
                     os.subnets_client, os.ports_client,
                     os.security_groups_client)
         else:
-            return (os.identity_v3_client, None, None, None, os.network_client,
+            return (os.identity_v3_client, os.projects_client,
+                    os.users_v3_client, None, os.network_client,
                     os.networks_client, os.subnets_client, os.ports_client,
                     os.security_groups_client)
 
@@ -233,8 +235,8 @@
         return resp_body['router']
 
     def _add_router_interface(self, router_id, subnet_id):
-        self.network_admin_client.add_router_interface_with_subnet_id(
-            router_id, subnet_id)
+        self.network_admin_client.add_router_interface(router_id,
+                                                       subnet_id=subnet_id)
 
     def get_credentials(self, credential_type):
         if self._creds.get(str(credential_type)):
@@ -333,8 +335,9 @@
             if (not self.network_resources or
                     (self.network_resources.get('router') and creds.subnet)):
                 try:
-                    net_client.remove_router_interface_with_subnet_id(
-                        creds.router['id'], creds.subnet['id'])
+                    net_client.remove_router_interface(
+                        creds.router['id'],
+                        subnet_id=creds.subnet['id'])
                 except lib_exc.NotFound:
                     LOG.warning('router with name: %s not found for delete' %
                                 creds.router['name'])
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index 800e977..baf796d 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -47,7 +47,6 @@
         self.endpoint_scheme = endpoint_parts.scheme
         self.endpoint_hostname = endpoint_parts.hostname
         self.endpoint_port = endpoint_parts.port
-        self.endpoint_path = endpoint_parts.path
 
         self.connection_class = self._get_connection_class(
             self.endpoint_scheme)
diff --git a/tempest/common/utils/__init__.py b/tempest/common/utils/__init__.py
index 81b8110..aad6373 100644
--- a/tempest/common/utils/__init__.py
+++ b/tempest/common/utils/__init__.py
@@ -27,8 +27,6 @@
 
 class DataUtils(object):
     def __getattr__(self, attr):
-        if attr in self.__dict__:
-            return self.__dict__[attr]
 
         if attr == 'rand_name':
             # NOTE(flwang): This is a proxy to generate a random name that
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index b76c356..8f5faef 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -15,8 +15,8 @@
 import time
 
 from oslo_log import log as logging
-import six
 from tempest_lib.common import ssh
+import tempest_lib.exceptions
 
 from tempest import config
 from tempest import exceptions
@@ -28,22 +28,10 @@
 
 class RemoteClient(object):
 
-    # NOTE(afazekas): It should always get an address instead of server
-    def __init__(self, server, username, password=None, pkey=None):
+    def __init__(self, ip_address, username, password=None, pkey=None):
         ssh_timeout = CONF.validation.ssh_timeout
-        network = CONF.validation.network_for_ssh
-        ip_version = CONF.validation.ip_version_for_ssh
         connect_timeout = CONF.validation.connect_timeout
-        if isinstance(server, six.string_types):
-            ip_address = server
-        else:
-            addresses = server['addresses'][network]
-            for address in addresses:
-                if address['version'] == ip_version:
-                    ip_address = address['addr']
-                    break
-            else:
-                raise exceptions.ServerUnreachable()
+
         self.ssh_client = ssh.Client(ip_address, username, password,
                                      ssh_timeout, pkey=pkey,
                                      channel_timeout=connect_timeout)
@@ -191,4 +179,10 @@
 
     def make_fs(self, dev_name, fs='ext4'):
         cmd_mkfs = 'sudo /usr/sbin/mke2fs -t %s /dev/%s' % (fs, dev_name)
-        self.exec_command(cmd_mkfs)
+        try:
+            self.exec_command(cmd_mkfs)
+        except tempest_lib.exceptions.SSHExecCommandFailed:
+            LOG.error("Couldn't mke2fs")
+            cmd_why = 'sudo ls -lR /dev'
+            LOG.info("Contents of /dev: %s" % self.exec_command(cmd_why))
+            raise
diff --git a/tempest/config.py b/tempest/config.py
index 43e715f..4fe7163 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -352,13 +352,6 @@
                 help="Does the test environment block migration support "
                 "cinder iSCSI volumes. Note, libvirt doesn't support this, "
                 "see https://bugs.launchpad.net/nova/+bug/1398999"),
-    # TODO(gilliard): Remove live_migrate_paused_instances at juno-eol.
-    cfg.BoolOpt('live_migrate_paused_instances',
-                default=False,
-                help="Does the test system allow live-migration of paused "
-                "instances? Note, this is more than just the ANDing of "
-                "paused and live_migrate, but all 3 should be set to True "
-                "to run those tests"),
     cfg.BoolOpt('vnc_console',
                 default=False,
                 help='Enable VNC console. This configuration value should '
@@ -394,12 +387,6 @@
     cfg.BoolOpt('personality',
                 default=True,
                 help='Does the test environment support server personality'),
-    # TODO(mriedem): Remove preserve_ports once juno-eol happens.
-    cfg.BoolOpt('preserve_ports',
-                default=False,
-                help='Does Nova preserve preexisting ports from Neutron '
-                     'when deleting an instance? This should be set to True '
-                     'if testing Kilo+ Nova.'),
     cfg.BoolOpt('attach_encrypted_volume',
                 default=True,
                 help='Does the test environment support attaching an '
@@ -574,41 +561,6 @@
                      " port admin state"),
 ]
 
-messaging_group = cfg.OptGroup(name='messaging',
-                               title='Messaging Service')
-
-MessagingGroup = [
-    cfg.StrOpt('catalog_type',
-               default='messaging',
-               help='Catalog type of the Messaging service.'),
-    cfg.IntOpt('max_queues_per_page',
-               default=20,
-               help='The maximum number of queue records per page when '
-                    'listing queues'),
-    cfg.IntOpt('max_queue_metadata',
-               default=65536,
-               help='The maximum metadata size for a queue'),
-    cfg.IntOpt('max_messages_per_page',
-               default=20,
-               help='The maximum number of queue message per page when '
-                    'listing (or) posting messages'),
-    cfg.IntOpt('max_message_size',
-               default=262144,
-               help='The maximum size of a message body'),
-    cfg.IntOpt('max_messages_per_claim',
-               default=20,
-               help='The maximum number of messages per claim'),
-    cfg.IntOpt('max_message_ttl',
-               default=1209600,
-               help='The maximum ttl for a message'),
-    cfg.IntOpt('max_claim_ttl',
-               default=43200,
-               help='The maximum ttl for a claim'),
-    cfg.IntOpt('max_claim_grace',
-               default=43200,
-               help='The maximum grace period for a claim'),
-]
-
 validation_group = cfg.OptGroup(name='validation',
                                 title='SSH Validation options')
 
@@ -1050,7 +1002,8 @@
     cfg.StrOpt('img_dir',
                default='/opt/stack/new/devstack/files/images/'
                'cirros-0.3.1-x86_64-uec',
-               help='Directory containing image files'),
+               help='Directory containing image files',
+               deprecated_for_removal=True),
     cfg.StrOpt('img_file', deprecated_name='qcow2_img_file',
                default='cirros-0.3.1-x86_64-disk.img',
                help='Image file name'),
@@ -1064,13 +1017,16 @@
                 'Use for custom images which require them'),
     cfg.StrOpt('ami_img_file',
                default='cirros-0.3.1-x86_64-blank.img',
-               help='AMI image file name'),
+               help='AMI image file name',
+               deprecated_for_removal=True),
     cfg.StrOpt('ari_img_file',
                default='cirros-0.3.1-x86_64-initrd',
-               help='ARI image file name'),
+               help='ARI image file name',
+               deprecated_for_removal=True),
     cfg.StrOpt('aki_img_file',
                default='cirros-0.3.1-x86_64-vmlinuz',
-               help='AKI image file name'),
+               help='AKI image file name',
+               deprecated_for_removal=True),
     cfg.IntOpt(
         'large_ops_number',
         default=0,
@@ -1126,9 +1082,6 @@
     cfg.BoolOpt('trove',
                 default=False,
                 help="Whether or not Trove is expected to be available"),
-    cfg.BoolOpt('zaqar',
-                default=False,
-                help="Whether or not Zaqar is expected to be available"),
 ]
 
 debug_group = cfg.OptGroup(name="debug",
@@ -1189,6 +1142,11 @@
                                     'live_migration, pause, rescue, resize '
                                     'shelve, snapshot, and suspend')
 
+
+# NOTE(deva): Ironic tests have been ported to tempest-lib. New config options
+#             should be added to ironic/ironic_tempest_plugin/config.py.
+#             However, these options need to remain here for testing stable
+#             branches until Liberty release reaches EOL.
 BaremetalGroup = [
     cfg.StrOpt('catalog_type',
                default='baremetal',
@@ -1250,7 +1208,6 @@
     (image_feature_group, ImageFeaturesGroup),
     (network_group, NetworkGroup),
     (network_feature_group, NetworkFeaturesGroup),
-    (messaging_group, MessagingGroup),
     (validation_group, ValidationGroup),
     (volume_group, VolumeGroup),
     (volume_feature_group, VolumeFeaturesGroup),
@@ -1326,7 +1283,6 @@
             'object-storage-feature-enabled']
         self.database = _CONF.database
         self.orchestration = _CONF.orchestration
-        self.messaging = _CONF.messaging
         self.telemetry = _CONF.telemetry
         self.telemetry_feature_enabled = _CONF['telemetry-feature-enabled']
         self.dashboard = _CONF.dashboard
@@ -1379,7 +1335,8 @@
             _CONF([], project='tempest')
 
         logging_cfg_path = "%s/logging.conf" % os.path.dirname(path)
-        if (not hasattr(_CONF, 'log_config_append') and
+        if ((not hasattr(_CONF, 'log_config_append') or
+            _CONF.log_config_append is None) and
             os.path.isfile(logging_cfg_path)):
             # if logging conf is in place we need to set log_config_append
             _CONF.log_config_append = logging_cfg_path
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 931737d..86e8460 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -186,6 +186,10 @@
                " %(schema_versions_info)s")
 
 
+class InvalidAPIVersionRange(TempestException):
+    message = ("API Min Version is greater than Max version")
+
+
 class CommandFailed(Exception):
     def __init__(self, returncode, cmd, output, stderr):
         super(CommandFailed, self).__init__()
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index 1dad3ba..cd4f50d 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -20,7 +20,7 @@
 
 PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron',
                   'trove', 'ironic', 'savanna', 'heat', 'ceilometer',
-                  'zaqar', 'sahara']
+                  'sahara']
 
 PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
 TEST_DEFINITION = re.compile(r'^\s*def test.*')
@@ -185,7 +185,8 @@
             # the end of a method
             return
 
-        if 'self.get(' not in line:
+        if 'self.get(' not in line and ('self.show_resource(' not in line and
+                                        'self.list_resources(' not in line):
             continue
 
         if METHOD_GET_RESOURCE.match(logical_line):
@@ -211,7 +212,7 @@
             # the end of a method
             return
 
-        if 'self.delete(' not in line:
+        if 'self.delete(' not in line and 'self.delete_resource(' not in line:
             continue
 
         if METHOD_DELETE_RESOURCE.match(logical_line):
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
index 8de3151..50a5477 100644
--- a/tempest/hacking/ignored_list_T110.txt
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -1,8 +1,7 @@
-./tempest/services/identity/v3/json/identity_client.py
-./tempest/services/messaging/json/messaging_client.py
 ./tempest/services/object_storage/object_client.py
 ./tempest/services/telemetry/json/alarming_client.py
 ./tempest/services/telemetry/json/telemetry_client.py
 ./tempest/services/volume/base/base_qos_client.py
 ./tempest/services/volume/base/base_backups_client.py
 ./tempest/services/baremetal/base.py
+./tempest/services/network/json/network_client.py
diff --git a/tempest/manager.py b/tempest/manager.py
index 9904aa6..6e86c78 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -50,8 +50,6 @@
             creds = self.credentials
         # Creates an auth provider for the credentials
         self.auth_provider = get_auth_provider(creds, pre_auth=True)
-        # FIXME(andreaf) unused
-        self.client_attr_names = []
 
 
 def get_auth_provider_class(credentials):
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index bb4e521..a996ffe 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -69,6 +69,8 @@
         cls.subnets_client = cls.manager.subnets_client
         cls.floating_ips_client = cls.manager.floating_ips_client
         cls.security_groups_client = cls.manager.security_groups_client
+        cls.security_group_rules_client = (
+            cls.manager.security_group_rules_client)
         # Heat client
         cls.orchestration_client = cls.manager.orchestration_client
 
@@ -160,7 +162,7 @@
         self.addCleanup(client.delete_keypair, name)
         return body['keypair']
 
-    def create_server(self, name=None, image=None, flavor=None,
+    def create_server(self, name=None, image_id=None, flavor=None,
                       validatable=False, wait_until=None,
                       wait_on_delete=True, clients=None, **kwargs):
         """Wrapper utility that returns a test server.
@@ -240,7 +242,8 @@
             clients,
             tenant_network=tenant_network,
             wait_until=wait_until,
-            **kwargs)
+            name=name, flavor=flavor,
+            image_id=image_id, **kwargs)
 
         # TODO(jlanoux) Move wait_on_delete in compute.py
         if wait_on_delete:
@@ -325,9 +328,6 @@
         for ruleset in rulesets:
             sg_rule = _client_rules.create_security_group_rule(
                 parent_group_id=secgroup_id, **ruleset)['security_group_rule']
-            self.addCleanup(self.delete_wrapper,
-                            _client_rules.delete_security_group_rule,
-                            sg_rule['id'])
             rules.append(sg_rule)
         return rules
 
@@ -349,25 +349,15 @@
 
         return secgroup
 
-    def get_remote_client(self, server_or_ip, username=None, private_key=None):
+    def get_remote_client(self, ip_address, username=None, private_key=None):
         """Get a SSH client to a remote server
 
-        @param server_or_ip a server object as returned by Tempest compute
-            client or an IP address to connect to
+        @param ip_address the server floating or fixed IP address to use
+                          for ssh validation
         @param username name of the Linux account on the remote server
         @param private_key the SSH private key to use
         @return a RemoteClient object
         """
-        if isinstance(server_or_ip, six.string_types):
-            ip = server_or_ip
-        else:
-            addrs = server_or_ip['addresses'][CONF.validation.network_for_ssh]
-            try:
-                ip = (addr['addr'] for addr in addrs if
-                      netaddr.valid_ipv4(addr['addr'])).next()
-            except StopIteration:
-                raise lib_exc.NotFound("No IPv4 addresses to use for SSH to "
-                                       "remote server.")
 
         if username is None:
             username = CONF.validation.image_ssh_user
@@ -380,14 +370,15 @@
         else:
             password = CONF.validation.image_ssh_password
             private_key = None
-        linux_client = remote_client.RemoteClient(ip, username,
+        linux_client = remote_client.RemoteClient(ip_address, username,
                                                   pkey=private_key,
                                                   password=password)
         try:
             linux_client.validate_authentication()
         except Exception as e:
             message = ('Initializing SSH connection to %(ip)s failed. '
-                       'Error: %(error)s' % {'ip': ip, 'error': e})
+                       'Error: %(error)s' % {'ip': ip_address,
+                                             'error': e})
             caller = misc_utils.find_test_caller()
             if caller:
                 message = '(%s) %s' % (caller, message)
@@ -625,9 +616,9 @@
             floating_ip['ip'], thing['id'])
         return floating_ip
 
-    def create_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt',
+    def create_timestamp(self, ip_address, dev_name=None, mount_path='/mnt',
                          private_key=None):
-        ssh_client = self.get_remote_client(server_or_ip,
+        ssh_client = self.get_remote_client(ip_address,
                                             private_key=private_key)
         if dev_name is not None:
             ssh_client.make_fs(dev_name)
@@ -640,9 +631,9 @@
             ssh_client.umount(mount_path)
         return timestamp
 
-    def get_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt',
+    def get_timestamp(self, ip_address, dev_name=None, mount_path='/mnt',
                       private_key=None):
-        ssh_client = self.get_remote_client(server_or_ip,
+        ssh_client = self.get_remote_client(ip_address,
                                             private_key=private_key)
         if dev_name is not None:
             ssh_client.mount(dev_name, mount_path)
@@ -652,12 +643,25 @@
             ssh_client.umount(mount_path)
         return timestamp
 
-    def get_server_or_ip(self, server):
+    def get_server_ip(self, server):
+        """Get the server fixed or floating IP.
+
+        Based on the configuration we're in, return a correct ip
+        address for validating that a guest is up.
+        """
         if CONF.validation.connect_method == 'floating':
-            ip = self.create_floating_ip(server)['ip']
+            # The tests calling this method don't have a floating IP
+            # and can't make use of the validattion resources. So the
+            # method is creating the floating IP there.
+            return self.create_floating_ip(server)['ip']
+        elif CONF.validation.connect_method == 'fixed':
+            addresses = server['addresses'][CONF.validation.network_for_ssh]
+            for address in addresses:
+                if address['version'] == CONF.validation.ip_version_for_ssh:
+                    return address['addr']
+            raise exceptions.ServerUnreachable()
         else:
-            ip = server
-        return ip
+            raise exceptions.InvalidConfiguration()
 
 
 class NetworkScenarioTest(ScenarioTest):
@@ -809,15 +813,18 @@
         return port
 
     def _get_server_port_id_and_ip4(self, server, ip_addr=None):
-        ports = self._list_ports(device_id=server['id'], status='ACTIVE',
-                                 fixed_ip=ip_addr)
+        ports = self._list_ports(device_id=server['id'], fixed_ip=ip_addr)
         # A port can have more then one IP address in some cases.
         # If the network is dual-stack (IPv4 + IPv6), this port is associated
         # with 2 subnets
         port_map = [(p["id"], fxip["ip_address"])
                     for p in ports
                     for fxip in p["fixed_ips"]
-                    if netaddr.valid_ipv4(fxip["ip_address"])]
+                    if netaddr.valid_ipv4(fxip["ip_address"])
+                    and p['status'] == 'ACTIVE']
+        inactive = [p for p in ports if p['status'] != 'ACTIVE']
+        if inactive:
+            LOG.warning("Instance has ports that are not ACTIVE: %s", inactive)
 
         self.assertNotEqual(0, len(port_map),
                             "No IPv4 addresses found in: %s" % ports)
@@ -939,11 +946,12 @@
                                             CONF.validation.ping_timeout,
                                             1)
 
-    def _create_security_group(self, client=None, tenant_id=None,
+    def _create_security_group(self, security_group_rules_client=None,
+                               tenant_id=None,
                                namestart='secgroup-smoke',
                                security_groups_client=None):
-        if client is None:
-            client = self.network_client
+        if security_group_rules_client is None:
+            security_group_rules_client = self.security_group_rules_client
         if security_groups_client is None:
             security_groups_client = self.security_groups_client
         if tenant_id is None:
@@ -954,7 +962,8 @@
 
         # Add rules to the security group
         rules = self._create_loginable_secgroup_rule(
-            client=client, secgroup=secgroup,
+            security_group_rules_client=security_group_rules_client,
+            secgroup=secgroup,
             security_groups_client=security_groups_client)
         for rule in rules:
             self.assertEqual(tenant_id, rule.tenant_id)
@@ -1010,7 +1019,8 @@
         return net_resources.DeletableSecurityGroup(client=client,
                                                     **sgs[0])
 
-    def _create_security_group_rule(self, secgroup=None, client=None,
+    def _create_security_group_rule(self, secgroup=None,
+                                    sec_group_rules_client=None,
                                     tenant_id=None,
                                     security_groups_client=None, **kwargs):
         """Create a rule from a dictionary of rule parameters.
@@ -1030,8 +1040,8 @@
                     port_range_max: 22
                     }
         """
-        if client is None:
-            client = self.network_client
+        if sec_group_rules_client is None:
+            sec_group_rules_client = self.security_group_rules_client
         if security_groups_client is None:
             security_groups_client = self.security_groups_client
         if not tenant_id:
@@ -1044,18 +1054,18 @@
                        tenant_id=secgroup.tenant_id)
         ruleset.update(kwargs)
 
-        sg_rule = client.create_security_group_rule(**ruleset)
+        sg_rule = sec_group_rules_client.create_security_group_rule(**ruleset)
         sg_rule = net_resources.DeletableSecurityGroupRule(
-            client=client,
+            client=sec_group_rules_client,
             **sg_rule['security_group_rule']
         )
-        self.addCleanup(self.delete_wrapper, sg_rule.delete)
         self.assertEqual(secgroup.tenant_id, sg_rule.tenant_id)
         self.assertEqual(secgroup.id, sg_rule.security_group_id)
 
         return sg_rule
 
-    def _create_loginable_secgroup_rule(self, client=None, secgroup=None,
+    def _create_loginable_secgroup_rule(self, security_group_rules_client=None,
+                                        secgroup=None,
                                         security_groups_client=None):
         """Create loginable security group rule
 
@@ -1065,8 +1075,8 @@
         belonging to the same security group.
         """
 
-        if client is None:
-            client = self.network_client
+        if security_group_rules_client is None:
+            security_group_rules_client = self.security_group_rules_client
         if security_groups_client is None:
             security_groups_client = self.security_groups_client
         rules = []
@@ -1087,12 +1097,14 @@
                 ethertype='IPv6',
             )
         ]
+        sec_group_rules_client = security_group_rules_client
         for ruleset in rulesets:
             for r_direction in ['ingress', 'egress']:
                 ruleset['direction'] = r_direction
                 try:
                     sg_rule = self._create_security_group_rule(
-                        client=client, secgroup=secgroup,
+                        sec_group_rules_client=sec_group_rules_client,
+                        secgroup=secgroup,
                         security_groups_client=security_groups_client,
                         **ruleset)
                 except lib_exc.Conflict as ex:
@@ -1106,12 +1118,6 @@
 
         return rules
 
-    def _ssh_to_server(self, server, private_key):
-        ssh_login = CONF.validation.image_ssh_user
-        return self.get_remote_client(server,
-                                      username=ssh_login,
-                                      private_key=private_key)
-
     def _get_router(self, client=None, tenant_id=None):
         """Retrieve a router for the given tenant id.
 
@@ -1313,13 +1319,6 @@
     def add_keypair(self):
         self.keypair = self.create_keypair()
 
-    def verify_connectivity(self, ip=None):
-        if ip:
-            dest = self.get_remote_client(ip)
-        else:
-            dest = self.get_remote_client(self.instance)
-        dest.validate_authentication()
-
     def boot_instance(self):
         self.instance = self.create_server(
             key_name=self.keypair['name'])
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 97a755d..cace90b 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -43,16 +43,14 @@
     def _create_aggregate(self, **kwargs):
         aggregate = (self.aggregates_client.create_aggregate(**kwargs)
                      ['aggregate'])
-        self.addCleanup(self._delete_aggregate, aggregate)
+        self.addCleanup(self.aggregates_client.delete_aggregate,
+                        aggregate['id'])
         aggregate_name = kwargs['name']
         availability_zone = kwargs['availability_zone']
         self.assertEqual(aggregate['name'], aggregate_name)
         self.assertEqual(aggregate['availability_zone'], availability_zone)
         return aggregate
 
-    def _delete_aggregate(self, aggregate):
-        self.aggregates_client.delete_aggregate(aggregate['id'])
-
     def _get_host_name(self):
         hosts = self.hosts_client.list_hosts()['hosts']
         self.assertTrue(len(hosts) >= 1)
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index 93b32f7..655d19d 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -15,7 +15,6 @@
 
 from oslo_log import log as logging
 
-from tempest.common import waiters
 from tempest import config
 from tempest.scenario import manager
 from tempest import test
@@ -37,32 +36,10 @@
         * Verifies SSH connectivity using created keypair via fixed IP
         * Associates a floating ip
         * Verifies SSH connectivity using created keypair via floating IP
-        * Verifies instance rebuild with ephemeral partition preservation
         * Deletes instance
         * Monitors the associated Ironic node for power and
           expected state transitions
     """
-    def rebuild_instance(self, preserve_ephemeral=False):
-        self.rebuild_server(server_id=self.instance['id'],
-                            preserve_ephemeral=preserve_ephemeral,
-                            wait=False)
-
-        node = self.get_node(instance_id=self.instance['id'])
-
-        # We should remain on the same node
-        self.assertEqual(self.node['uuid'], node['uuid'])
-        self.node = node
-
-        waiters.wait_for_server_status(
-            self.servers_client,
-            server_id=self.instance['id'],
-            status='REBUILD',
-            ready_wait=False)
-        waiters.wait_for_server_status(
-            self.servers_client,
-            server_id=self.instance['id'],
-            status='ACTIVE')
-
     def verify_partition(self, client, label, mount, gib_size):
         """Verify a labeled partition's mount point and size."""
         LOG.info("Looking for partition %s mounted on %s" % (label, mount))
@@ -112,12 +89,9 @@
         self.add_keypair()
         self.boot_instance()
         self.validate_ports()
-        self.verify_connectivity()
-        if CONF.validation.connect_method == 'floating':
-            floating_ip = self.create_floating_ip(self.instance)['ip']
-            self.verify_connectivity(ip=floating_ip)
-
-        vm_client = self.get_remote_client(self.instance)
+        ip_address = self.get_server_ip(self.instance)
+        self.get_remote_client(ip_address).validate_authentication()
+        vm_client = self.get_remote_client(ip_address)
 
         # We expect the ephemeral partition to be mounted on /mnt and to have
         # the same size as our flavor definition.
@@ -126,6 +100,6 @@
             self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
             # Create the test file
             self.create_timestamp(
-                floating_ip, private_key=self.keypair['private_key'])
+                ip_address, private_key=self.keypair['private_key'])
 
         self.terminate_instance()
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index cb6b968..5d4f7b3 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -97,9 +97,13 @@
         req = request.Request(login_url)
         req.add_header('Content-type', 'application/x-www-form-urlencoded')
         req.add_header('Referer', CONF.dashboard.dashboard_url)
+
+        # Pass the default domain name regardless of the auth version in order
+        # to test the scenario of when horizon is running with keystone v3
         params = {'username': username,
                   'password': password,
                   'region': parser.region,
+                  'domain': CONF.auth.default_credentials_domain_name,
                   'csrfmiddlewaretoken': parser.csrf_token}
         self.opener.open(req, parse.urlencode(params))
 
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index ff9dabf..f7c7434 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -47,13 +47,6 @@
 
     """
 
-    def _wait_for_server_status(self, server, status):
-        server_id = server['id']
-        # Raise on error defaults to True, which is consistent with the
-        # original function from scenario tests here
-        waiters.wait_for_server_status(self.servers_client,
-                                       server_id, status)
-
     def nova_list(self):
         servers = self.servers_client.list_servers()
         # The list servers in the compute client is inconsistent...
@@ -69,19 +62,14 @@
             server, custom_matchers.MatchesDictExceptForKeys(
                 got_server, excluded_keys=excluded_keys))
 
-    def cinder_create(self):
-        return self.create_volume()
-
-    def cinder_list(self):
-        return self.volumes_client.list_volumes()['volumes']
-
     def cinder_show(self, volume):
         got_volume = self.volumes_client.show_volume(volume['id'])['volume']
         self.assertEqual(volume, got_volume)
 
     def nova_reboot(self, server):
         self.servers_client.reboot_server(server['id'], type='SOFT')
-        self._wait_for_server_status(server, 'ACTIVE')
+        waiters.wait_for_server_status(self.servers_client,
+                                       server['id'], 'ACTIVE')
 
     def check_partitions(self):
         # NOTE(andreaf) The device name may be different on different guest OS
@@ -121,8 +109,8 @@
 
         self.nova_show(server)
 
-        volume = self.cinder_create()
-        volumes = self.cinder_list()
+        volume = self.create_volume()
+        volumes = self.volumes_client.list_volumes()['volumes']
         self.assertIn(volume['id'], [x['id'] for x in volumes])
 
         self.cinder_show(volume)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index b8bec16..4d03ed7 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -240,8 +240,8 @@
         old_floating_ip, server = self.floating_ip_tuple
         ip_address = old_floating_ip.floating_ip_address
         private_key = self._get_server_key(server)
-        ssh_client = self.get_remote_client(ip_address,
-                                            private_key=private_key)
+        ssh_client = self.get_remote_client(
+            ip_address, private_key=private_key)
         old_nic_list = self._get_server_nics(ssh_client)
         # get a port from a list of one item
         port_list = self._list_ports(device_id=server['id'])
@@ -336,7 +336,8 @@
                                    should_connect=True):
         ip_address = floating_ip.floating_ip_address
         private_key = self._get_server_key(self.floating_ip_tuple.server)
-        ssh_source = self._ssh_to_server(ip_address, private_key)
+        ssh_source = self.get_remote_client(
+            ip_address, private_key=private_key)
 
         for remote_ip in address_list:
             if should_connect:
@@ -553,7 +554,8 @@
         floating_ip, server = self.floating_ip_tuple
         ip_address = floating_ip.floating_ip_address
         private_key = self._get_server_key(server)
-        ssh_client = self._ssh_to_server(ip_address, private_key)
+        ssh_client = self.get_remote_client(
+            ip_address, private_key=private_key)
 
         dns_servers = [initial_dns_server]
         servers = ssh_client.get_dns_servers()
@@ -624,9 +626,6 @@
             "admin_state_up of instance port to True")
 
     @test.idempotent_id('759462e1-8535-46b0-ab3a-33aa45c55aaa')
-    @testtools.skipUnless(CONF.compute_feature_enabled.preserve_ports,
-                          'Preserving ports on instance delete may not be '
-                          'supported in the version of Nova being tested.')
     @test.services('compute', 'network')
     def test_preserve_preexisting_port(self):
         """Test preserve pre-existing port
@@ -684,9 +683,9 @@
         list_hosts = (self.admin_manager.network_client.
                       list_l3_agents_hosting_router)
         schedule_router = (self.admin_manager.network_agents_client.
-                           add_router_to_l3_agent)
+                           create_router_on_l3_agent)
         unschedule_router = (self.admin_manager.network_agents_client.
-                             remove_router_from_l3_agent)
+                             delete_router_from_l3_agent)
 
         agent_list = set(a["id"] for a in
                          self._list_agents(agent_type="L3 agent"))
@@ -739,6 +738,8 @@
             msg='After router rescheduling')
 
     @test.requires_ext(service='network', extension='port-security')
+    @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
+                          'NIC hotplug not available')
     @test.idempotent_id('7c0bb1a2-d053-49a4-98f9-ca1a1d849f63')
     @test.services('compute', 'network')
     def test_port_security_macspoofing_port(self):
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index cc28873..fc33dd9 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -124,7 +124,7 @@
         fip = self.create_floating_ip(thing=srv)
         ips = self.define_server_ips(srv=srv)
         ssh = self.get_remote_client(
-            server_or_ip=fip.floating_ip_address,
+            ip_address=fip.floating_ip_address,
             username=username)
         return ssh, ips, srv["id"]
 
@@ -203,31 +203,37 @@
             (dest, source.ssh_client.host)
         )
 
+    @test.attr(type='slow')
     @test.idempotent_id('2c92df61-29f0-4eaa-bee3-7c65bef62a43')
     @test.services('compute', 'network')
     def test_slaac_from_os(self):
         self._prepare_and_test(address6_mode='slaac')
 
+    @test.attr(type='slow')
     @test.idempotent_id('d7e1f858-187c-45a6-89c9-bdafde619a9f')
     @test.services('compute', 'network')
     def test_dhcp6_stateless_from_os(self):
         self._prepare_and_test(address6_mode='dhcpv6-stateless')
 
+    @test.attr(type='slow')
     @test.idempotent_id('7ab23f41-833b-4a16-a7c9-5b42fe6d4123')
     @test.services('compute', 'network')
     def test_multi_prefix_dhcpv6_stateless(self):
         self._prepare_and_test(address6_mode='dhcpv6-stateless', n_subnets6=2)
 
+    @test.attr(type='slow')
     @test.idempotent_id('dec222b1-180c-4098-b8c5-cc1b8342d611')
     @test.services('compute', 'network')
     def test_multi_prefix_slaac(self):
         self._prepare_and_test(address6_mode='slaac', n_subnets6=2)
 
+    @test.attr(type='slow')
     @test.idempotent_id('b6399d76-4438-4658-bcf5-0d6c8584fde2')
     @test.services('compute', 'network')
     def test_dualnet_slaac_from_os(self):
         self._prepare_and_test(address6_mode='slaac', dualnet=True)
 
+    @test.attr(type='slow')
     @test.idempotent_id('76f26acd-9688-42b4-bc3e-cd134c4cb09e')
     @test.services('compute', 'network')
     def test_dualnet_dhcp6_stateless_from_os(self):
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 0185899..18bd764 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -133,6 +133,9 @@
             msg = ('Either tenant_networks_reachable must be "true", or '
                    'public_network_id must be defined.')
             raise cls.skipException(msg)
+        if not test.is_extension_enabled('security-group', 'network'):
+            msg = "security-group extension not enabled."
+            raise cls.skipException(msg)
 
     @classmethod
     def setup_credentials(cls):
@@ -188,9 +191,11 @@
             port_range_max=22,
             direction='ingress',
         )
-        self._create_security_group_rule(secgroup=access_sg,
-                                         client=tenant.manager.network_client,
-                                         **ssh_rule)
+        sec_group_rules_client = tenant.manager.security_group_rules_client
+        self._create_security_group_rule(
+            secgroup=access_sg,
+            sec_group_rules_client=sec_group_rules_client,
+            **ssh_rule)
 
     def _verify_network_details(self, tenant):
         # Checks that we see the newly created network/subnet/router via
@@ -316,8 +321,8 @@
         access_point_ssh = \
             self.floating_ips[tenant.access_point['id']].floating_ip_address
         private_key = tenant.keypair['private_key']
-        access_point_ssh = self._ssh_to_server(access_point_ssh,
-                                               private_key=private_key)
+        access_point_ssh = self.get_remote_client(
+            access_point_ssh, private_key=private_key)
         return access_point_ssh
 
     def _check_connectivity(self, access_point, ip, should_succeed=True):
@@ -368,9 +373,11 @@
             protocol='icmp',
             direction='ingress'
         )
+        sec_group_rules_client = (
+            dest_tenant.manager.security_group_rules_client)
         self._create_security_group_rule(
             secgroup=dest_tenant.security_groups['default'],
-            client=dest_tenant.manager.network_client,
+            sec_group_rules_client=sec_group_rules_client,
             **ruleset
         )
         access_point_ssh = self._connect_to_access_point(source_tenant)
@@ -382,9 +389,11 @@
         self._test_cross_tenant_block(dest_tenant, source_tenant)
 
         # allow reverse traffic and check
+        sec_group_rules_client = (
+            source_tenant.manager.security_group_rules_client)
         self._create_security_group_rule(
             secgroup=source_tenant.security_groups['default'],
-            client=source_tenant.manager.network_client,
+            sec_group_rules_client=sec_group_rules_client,
             **ruleset
         )
 
@@ -465,9 +474,10 @@
             protocol='icmp',
             direction='ingress',
         )
+        sec_group_rules_client = new_tenant.manager.security_group_rules_client
         self._create_security_group_rule(
             secgroup=new_sg,
-            client=new_tenant.manager.network_client,
+            sec_group_rules_client=sec_group_rules_client,
             **icmp_rule)
         new_tenant.security_groups.update(new_sg=new_sg)
 
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 239e120..dcb095b 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -69,18 +69,15 @@
                       image=self.image_ref, flavor=self.flavor_ref,
                       ssh=self.run_ssh, ssh_user=self.ssh_user))
 
-    def add_keypair(self):
-        self.keypair = self.create_keypair()
-
-    def verify_ssh(self):
+    def verify_ssh(self, keypair):
         if self.run_ssh:
             # Obtain a floating IP
             self.fip = self.create_floating_ip(self.instance)['ip']
             # Check ssh
             self.ssh_client = self.get_remote_client(
-                server_or_ip=self.fip,
+                ip_address=self.fip,
                 username=self.image_utils.ssh_user(self.image_ref),
-                private_key=self.keypair['private_key'])
+                private_key=keypair['private_key'])
 
     def verify_metadata(self):
         if self.run_ssh and CONF.compute_feature_enabled.metadata_service:
@@ -123,19 +120,19 @@
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_server_basicops(self):
-        self.add_keypair()
+        keypair = self.create_keypair()
         self.security_group = self._create_security_group()
         security_groups = [{'name': self.security_group['name']}]
         self.md = {'meta1': 'data1', 'meta2': 'data2', 'metaN': 'dataN'}
         self.instance = self.create_server(
             image_id=self.image_ref,
             flavor=self.flavor_ref,
-            key_name=self.keypair['name'],
+            key_name=keypair['name'],
             security_groups=security_groups,
             config_drive=CONF.compute_feature_enabled.config_drive,
             metadata=self.md,
             wait_until='ACTIVE')
-        self.verify_ssh()
+        self.verify_ssh(keypair)
         self.verify_metadata()
         self.verify_metadata_on_config_drive()
         self.servers_client.delete_server(self.instance['id'])
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index 378ae9d..77de47e 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -13,7 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_log import log
 import testtools
 
 from tempest.common import waiters
@@ -23,8 +22,6 @@
 
 CONF = config.CONF
 
-LOG = log.getLogger(__name__)
-
 
 class TestShelveInstance(manager.ScenarioTest):
     """This test shelves then unshelves a Nova instance
@@ -80,7 +77,7 @@
                 security_groups=security_groups,
                 wait_until='ACTIVE')
 
-        instance_ip = self.get_server_or_ip(server)
+        instance_ip = self.get_server_ip(server)
         timestamp = self.create_timestamp(instance_ip,
                                           private_key=keypair['private_key'])
 
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index f3b6558..d6528a3 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -13,7 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_log import log
 import testtools
 
 from tempest import config
@@ -22,8 +21,6 @@
 
 CONF = config.CONF
 
-LOG = log.getLogger(__name__)
-
 
 class TestSnapshotPattern(manager.ScenarioTest):
     """This test is for snapshotting an instance and booting with it.
@@ -52,7 +49,7 @@
             security_groups=[{'name': security_group['name']}],
             wait_until='ACTIVE')
 
-        instance_ip = self.get_server_or_ip(server)
+        instance_ip = self.get_server_ip(server)
         timestamp = self.create_timestamp(instance_ip,
                                           private_key=keypair['private_key'])
 
@@ -67,7 +64,7 @@
             wait_until='ACTIVE')
 
         # check the existence of the timestamp file in the second instance
-        server_from_snapshot_ip = self.get_server_or_ip(server_from_snapshot)
+        server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
         timestamp2 = self.get_timestamp(server_from_snapshot_ip,
                                         private_key=keypair['private_key'])
         self.assertEqual(timestamp, timestamp2)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 8183ce3..1d09fe7 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -25,10 +25,8 @@
 from tempest import exceptions
 from tempest.scenario import manager
 from tempest import test
-import tempest.test
 
 CONF = config.CONF
-
 LOG = logging.getLogger(__name__)
 
 
@@ -60,10 +58,6 @@
         if not CONF.volume_feature_enabled.snapshot:
             raise cls.skipException("Cinder volume snapshots are disabled")
 
-    def _wait_for_volume_snapshot_status(self, volume_snapshot, status):
-        self.snapshots_client.wait_for_snapshot_status(volume_snapshot['id'],
-                                                       status)
-
     def _create_volume_snapshot(self, volume):
         snapshot_name = data_utils.rand_name('scenario-snapshot')
         snapshot = self.snapshots_client.create_snapshot(
@@ -78,55 +72,38 @@
             except lib_exc.NotFound:
                 pass
         self.addCleanup(cleaner)
-        self._wait_for_volume_status(volume, 'available')
+        self.volumes_client.wait_for_volume_status(volume['id'], 'available')
         self.snapshots_client.wait_for_snapshot_status(snapshot['id'],
                                                        'available')
         self.assertEqual(snapshot_name, snapshot['display_name'])
         return snapshot
 
-    def _wait_for_volume_status(self, volume, status):
-        self.volumes_client.wait_for_volume_status(volume['id'], status)
-
-    def _create_volume(self, snapshot_id=None):
-        return self.create_volume(snapshot_id=snapshot_id)
-
-    def _attach_volume(self, server, volume):
-        attached_volume = self.servers_client.attach_volume(
-            server['id'], volumeId=volume['id'], device='/dev/%s'
-            % CONF.compute.volume_device_name)['volumeAttachment']
-        self.assertEqual(volume['id'], attached_volume['id'])
-        self._wait_for_volume_status(attached_volume, 'in-use')
-
-    def _detach_volume(self, server, volume):
-        self.servers_client.detach_volume(server['id'], volume['id'])
-        self._wait_for_volume_status(volume, 'available')
-
-    def _wait_for_volume_available_on_the_system(self, server_or_ip,
+    def _wait_for_volume_available_on_the_system(self, ip_address,
                                                  private_key):
-        ssh = self.get_remote_client(server_or_ip, private_key=private_key)
+        ssh = self.get_remote_client(ip_address, private_key=private_key)
 
         def _func():
             part = ssh.get_partitions()
             LOG.debug("Partitions:%s" % part)
             return CONF.compute.volume_device_name in part
 
-        if not tempest.test.call_until_true(_func,
-                                            CONF.compute.build_timeout,
-                                            CONF.compute.build_interval):
+        if not test.call_until_true(_func,
+                                    CONF.compute.build_timeout,
+                                    CONF.compute.build_interval):
             raise exceptions.TimeoutException
 
     @decorators.skip_because(bug="1205344")
     @test.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
-    @tempest.test.services('compute', 'network', 'volume', 'image')
+    @test.services('compute', 'network', 'volume', 'image')
     def test_stamp_pattern(self):
         # prepare for booting an instance
         keypair = self.create_keypair()
         security_group = self._create_security_group()
 
         # boot an instance and create a timestamp file in it
-        volume = self._create_volume()
+        volume = self.create_volume()
         server = self.create_server(
             image_id=CONF.compute.image_ref,
             key_name=keypair['name'],
@@ -134,15 +111,15 @@
             wait_until='ACTIVE')
 
         # create and add floating IP to server1
-        ip_for_server = self.get_server_or_ip(server)
+        ip_for_server = self.get_server_ip(server)
 
-        self._attach_volume(server, volume)
+        self.nova_volume_attach(server, volume)
         self._wait_for_volume_available_on_the_system(ip_for_server,
                                                       keypair['private_key'])
         timestamp = self.create_timestamp(ip_for_server,
                                           CONF.compute.volume_device_name,
                                           private_key=keypair['private_key'])
-        self._detach_volume(server, volume)
+        self.nova_volume_detach(server, volume)
 
         # snapshot the volume
         volume_snapshot = self._create_volume_snapshot(volume)
@@ -151,7 +128,7 @@
         snapshot_image = self.create_server_snapshot(server=server)
 
         # create second volume from the snapshot(volume2)
-        volume_from_snapshot = self._create_volume(
+        volume_from_snapshot = self.create_volume(
             snapshot_id=volume_snapshot['id'])
 
         # boot second instance from the snapshot(instance2)
@@ -161,10 +138,10 @@
             security_groups=security_group)
 
         # create and add floating IP to server_from_snapshot
-        ip_for_snapshot = self.get_server_or_ip(server_from_snapshot)
+        ip_for_snapshot = self.get_server_ip(server_from_snapshot)
 
         # attach volume2 to instance2
-        self._attach_volume(server_from_snapshot, volume_from_snapshot)
+        self.nova_volume_attach(server_from_snapshot, volume_from_snapshot)
         self._wait_for_volume_available_on_the_system(ip_for_snapshot,
                                                       keypair['private_key'])
 
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 81ecda0..4ce57db 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -10,8 +10,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_log import log
-
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
@@ -20,8 +18,6 @@
 
 CONF = config.CONF
 
-LOG = log.getLogger(__name__)
-
 
 class TestVolumeBootPattern(manager.ScenarioTest):
 
@@ -70,7 +66,7 @@
         create_kwargs.update(self._get_bdm(
             vol_id, delete_on_termination=delete_on_termination))
         return self.create_server(
-            image='',
+            image_id='',
             wait_until='ACTIVE',
             **create_kwargs)
 
@@ -114,7 +110,7 @@
                                                        keypair, security_group)
 
         # write content to volume on instance
-        ip_instance_1st = self.get_server_or_ip(instance_1st)
+        ip_instance_1st = self.get_server_ip(instance_1st)
         timestamp = self.create_timestamp(ip_instance_1st,
                                           private_key=keypair['private_key'])
 
@@ -126,7 +122,7 @@
                                                        keypair, security_group)
 
         # check the content of written file
-        ip_instance_2nd = self.get_server_or_ip(instance_2nd)
+        ip_instance_2nd = self.get_server_ip(instance_2nd)
         timestamp2 = self.get_timestamp(ip_instance_2nd,
                                         private_key=keypair['private_key'])
         self.assertEqual(timestamp, timestamp2)
@@ -141,7 +137,7 @@
                                             keypair, security_group))
 
         # check the content of written file
-        server_from_snapshot_ip = self.get_server_or_ip(server_from_snapshot)
+        server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
         timestamp3 = self.get_timestamp(server_from_snapshot_ip,
                                         private_key=keypair['private_key'])
         self.assertEqual(timestamp, timestamp3)
diff --git a/tempest/services/base_microversion_client.py b/tempest/services/base_microversion_client.py
new file mode 100644
index 0000000..4c750f5
--- /dev/null
+++ b/tempest/services/base_microversion_client.py
@@ -0,0 +1,54 @@
+# Copyright 2016 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest_lib.common import rest_client
+
+
+class BaseMicroversionClient(rest_client.RestClient):
+    """Base class to support microversion in service clients
+
+    This class is used to support microversion in service clients.
+    This provides feature to make API request with microversion.
+    Service clients derived from this class will be able to send API
+    request to server with or without microversion.
+    If api_microversion is not set on service client then API request will be
+    normal request without microversion.
+
+    """
+    def __init__(self, auth_provider, service, region,
+                 api_microversion_header_name, **kwargs):
+        """Base Microversion Client __init__
+
+        :param auth_provider: an auth provider object used to wrap requests in
+                              auth
+        :param str service: The service name to use for the catalog lookup
+        :param str region: The region to use for the catalog lookup
+        :param str api_microversion_header_name: The microversion header name
+                                                 to use for sending API
+                                                 request with microversion
+        :param kwargs: kwargs required by rest_client.RestClient
+        """
+        super(BaseMicroversionClient, self).__init__(
+            auth_provider, service, region, **kwargs)
+        self.api_microversion_header_name = api_microversion_header_name
+        self.api_microversion = None
+
+    def get_headers(self):
+        headers = super(BaseMicroversionClient, self).get_headers()
+        if self.api_microversion:
+            headers[self.api_microversion_header_name] = self.api_microversion
+        return headers
+
+    def set_api_microversion(self, microversion):
+        self.api_microversion = microversion
diff --git a/tempest/services/compute/json/base.py b/tempest/services/compute/json/base_compute_client.py
similarity index 69%
rename from tempest/services/compute/json/base.py
rename to tempest/services/compute/json/base_compute_client.py
index 40d3056..5349af6 100644
--- a/tempest/services/compute/json/base.py
+++ b/tempest/services/compute/json/base_compute_client.py
@@ -12,23 +12,31 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest_lib.common import rest_client
-
 from tempest.common import api_version_request
+from tempest.common import api_version_utils
 from tempest import exceptions
+from tempest.services import base_microversion_client
 
 
-class BaseComputeClient(rest_client.RestClient):
-    api_microversion = None
+class BaseComputeClient(base_microversion_client.BaseMicroversionClient):
 
-    def get_headers(self):
-        headers = super(BaseComputeClient, self).get_headers()
-        if self.api_microversion:
-            headers['X-OpenStack-Nova-API-Version'] = self.api_microversion
-        return headers
+    def __init__(self, auth_provider, service, region,
+                 api_microversion_header_name='X-OpenStack-Nova-API-Version',
+                 **kwargs):
+        super(BaseComputeClient, self).__init__(
+            auth_provider, service, region,
+            api_microversion_header_name, **kwargs)
 
-    def set_api_microversion(self, microversion):
-        self.api_microversion = microversion
+    def request(self, method, url, extra_headers=False, headers=None,
+                body=None):
+        resp, resp_body = super(BaseComputeClient, self).request(
+            method, url, extra_headers, headers, body)
+        if self.api_microversion and self.api_microversion != 'latest':
+            api_version_utils.assert_version_header_matches_request(
+                self.api_microversion_header_name,
+                self.api_microversion,
+                resp)
+        return resp, resp_body
 
     def get_schema(self, schema_versions_info):
         """Get JSON schema
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 2e22bc6..ec9b1e0 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -15,21 +15,28 @@
 
 from oslo_serialization import jsonutils as json
 
-from tempest.api_schema.response.compute.v2_1 import keypairs as schema
+from tempest.api_schema.response.compute.v2_1 import keypairs as schemav21
+from tempest.api_schema.response.compute.v2_2 import keypairs as schemav22
 from tempest.common import service_client
+from tempest.services.compute.json import base_compute_client
 
 
-class KeyPairsClient(service_client.ServiceClient):
+class KeyPairsClient(base_compute_client.BaseComputeClient):
+
+    schema_versions_info = [{'min': None, 'max': '2.1', 'schema': schemav21},
+                            {'min': '2.2', 'max': None, 'schema': schemav22}]
 
     def list_keypairs(self):
         resp, body = self.get("os-keypairs")
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.list_keypairs, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def show_keypair(self, keypair_name):
         resp, body = self.get("os-keypairs/%s" % keypair_name)
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.get_keypair, resp, body)
         return service_client.ResponseBody(resp, body)
 
@@ -37,10 +44,12 @@
         post_body = json.dumps({'keypair': kwargs})
         resp, body = self.post("os-keypairs", body=post_body)
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.create_keypair, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def delete_keypair(self, keypair_name):
         resp, body = self.delete("os-keypairs/%s" % keypair_name)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.delete_keypair, resp, body)
         return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v2/json/endpoints_client.py b/tempest/services/identity/v2/json/endpoints_client.py
new file mode 100644
index 0000000..ff9907d
--- /dev/null
+++ b/tempest/services/identity/v2/json/endpoints_client.py
@@ -0,0 +1,50 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.common import service_client
+
+
+class EndpointsClient(service_client.ServiceClient):
+    api_version = "v2.0"
+
+    def create_endpoint(self, service_id, region_id, **kwargs):
+        """Create an endpoint for service."""
+        post_body = {
+            'service_id': service_id,
+            'region': region_id,
+            'publicurl': kwargs.get('publicurl'),
+            'adminurl': kwargs.get('adminurl'),
+            'internalurl': kwargs.get('internalurl')
+        }
+        post_body = json.dumps({'endpoint': post_body})
+        resp, body = self.post('/endpoints', post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def list_endpoints(self):
+        """List Endpoints - Returns Endpoints."""
+        resp, body = self.get('/endpoints')
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_endpoint(self, endpoint_id):
+        """Delete an endpoint."""
+        url = '/endpoints/%s' % endpoint_id
+        resp, body = self.delete(url)
+        self.expected_success(204, resp.status)
+        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 0ff59d5..f045bb7 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -39,70 +39,6 @@
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
 
-    def create_service(self, name, type, **kwargs):
-        """Create a service."""
-        post_body = {
-            'name': name,
-            'type': type,
-            'description': kwargs.get('description')
-        }
-        post_body = json.dumps({'OS-KSADM:service': post_body})
-        resp, body = self.post('/OS-KSADM/services', post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def show_service(self, service_id):
-        """Get Service."""
-        url = '/OS-KSADM/services/%s' % service_id
-        resp, body = self.get(url)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_services(self):
-        """List Service - Returns Services."""
-        resp, body = self.get('/OS-KSADM/services')
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_service(self, service_id):
-        """Delete Service."""
-        url = '/OS-KSADM/services/%s' % service_id
-        resp, body = self.delete(url)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def create_endpoint(self, service_id, region_id, **kwargs):
-        """Create an endpoint for service."""
-        post_body = {
-            'service_id': service_id,
-            'region': region_id,
-            'publicurl': kwargs.get('publicurl'),
-            'adminurl': kwargs.get('adminurl'),
-            'internalurl': kwargs.get('internalurl')
-        }
-        post_body = json.dumps({'endpoint': post_body})
-        resp, body = self.post('/endpoints', post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_endpoints(self):
-        """List Endpoints - Returns Endpoints."""
-        resp, body = self.get('/endpoints')
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_endpoint(self, endpoint_id):
-        """Delete an endpoint."""
-        url = '/endpoints/%s' % endpoint_id
-        resp, body = self.delete(url)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
     def list_extensions(self):
         """List all the extensions."""
         resp, body = self.get('/extensions')
diff --git a/tempest/services/identity/v2/json/services_client.py b/tempest/services/identity/v2/json/services_client.py
new file mode 100644
index 0000000..436d00d
--- /dev/null
+++ b/tempest/services/identity/v2/json/services_client.py
@@ -0,0 +1,56 @@
+# Copyright 2015 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.common import service_client
+
+
+class ServicesClient(service_client.ServiceClient):
+    api_version = "v2.0"
+
+    def create_service(self, name, type, **kwargs):
+        """Create a service."""
+        post_body = {
+            'name': name,
+            'type': type,
+            'description': kwargs.get('description')
+        }
+        post_body = json.dumps({'OS-KSADM:service': post_body})
+        resp, body = self.post('/OS-KSADM/services', post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def show_service(self, service_id):
+        """Get Service."""
+        url = '/OS-KSADM/services/%s' % service_id
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def list_services(self):
+        """List Service - Returns Services."""
+        resp, body = self.get('/OS-KSADM/services')
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_service(self, service_id):
+        """Delete Service."""
+        url = '/OS-KSADM/services/%s' % service_id
+        resp, body = self.delete(url)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
index ede5edb..8ab7464 100644
--- a/tempest/services/identity/v3/json/endpoints_client.py
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -61,3 +61,10 @@
         resp_header, resp_body = self.delete('endpoints/%s' % endpoint_id)
         self.expected_success(204, resp_header.status)
         return service_client.ResponseBody(resp_header, resp_body)
+
+    def show_endpoint(self, endpoint_id):
+        """Get endpoint."""
+        resp_header, resp_body = self.get('endpoints/%s' % endpoint_id)
+        self.expected_success(200, resp_header.status)
+        resp_body = json.loads(resp_body)
+        return service_client.ResponseBody(resp_header, resp_body)
diff --git a/tempest/services/identity/v3/json/groups_client.py b/tempest/services/identity/v3/json/groups_client.py
index 70edd23..6ed85cf 100644
--- a/tempest/services/identity/v3/json/groups_client.py
+++ b/tempest/services/identity/v3/json/groups_client.py
@@ -88,3 +88,9 @@
         resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
+
+    def check_group_user_existence(self, group_id, user_id):
+        """Check user in group."""
+        resp, body = self.head('groups/%s/users/%s' % (group_id, user_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index ab8ba2a..809d0b5 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -30,156 +30,6 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def create_user(self, user_name, password=None, project_id=None,
-                    email=None, domain_id='default', **kwargs):
-        """Creates a user."""
-        en = kwargs.get('enabled', True)
-        description = kwargs.get('description', None)
-        default_project_id = kwargs.get('default_project_id')
-        post_body = {
-            'project_id': project_id,
-            'default_project_id': default_project_id,
-            'description': description,
-            'domain_id': domain_id,
-            'email': email,
-            'enabled': en,
-            'name': user_name,
-            'password': password
-        }
-        post_body = json.dumps({'user': post_body})
-        resp, body = self.post('users', post_body)
-        self.expected_success(201, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def update_user(self, user_id, name, **kwargs):
-        """Updates a user."""
-        body = self.show_user(user_id)['user']
-        email = kwargs.get('email', body['email'])
-        en = kwargs.get('enabled', body['enabled'])
-        project_id = kwargs.get('project_id', body['project_id'])
-        if 'default_project_id' in body.keys():
-            default_project_id = kwargs.get('default_project_id',
-                                            body['default_project_id'])
-        else:
-            default_project_id = kwargs.get('default_project_id')
-        description = kwargs.get('description', body['description'])
-        domain_id = kwargs.get('domain_id', body['domain_id'])
-        post_body = {
-            'name': name,
-            'email': email,
-            'enabled': en,
-            'project_id': project_id,
-            'default_project_id': default_project_id,
-            'id': user_id,
-            'domain_id': domain_id,
-            'description': description
-        }
-        post_body = json.dumps({'user': post_body})
-        resp, body = self.patch('users/%s' % user_id, post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def update_user_password(self, user_id, **kwargs):
-        """Update a user password
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#changeUserPassword
-        """
-        update_user = json.dumps({'user': kwargs})
-        resp, _ = self.post('users/%s/password' % user_id, update_user)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp)
-
-    def list_user_projects(self, user_id):
-        """Lists the projects on which a user has roles assigned."""
-        resp, body = self.get('users/%s/projects' % user_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_users(self, params=None):
-        """Get the list of users."""
-        url = 'users'
-        if params:
-            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)
-
-    def show_user(self, user_id):
-        """GET a user."""
-        resp, body = self.get("users/%s" % user_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_user(self, user_id):
-        """Deletes a User."""
-        resp, body = self.delete("users/%s" % user_id)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def create_project(self, name, **kwargs):
-        """Creates a project."""
-        description = kwargs.get('description', None)
-        en = kwargs.get('enabled', True)
-        domain_id = kwargs.get('domain_id', 'default')
-        post_body = {
-            'description': description,
-            'domain_id': domain_id,
-            'enabled': en,
-            'name': name
-        }
-        post_body = json.dumps({'project': post_body})
-        resp, body = self.post('projects', post_body)
-        self.expected_success(201, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_projects(self, params=None):
-        url = "projects"
-        if params:
-            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)
-
-    def update_project(self, project_id, **kwargs):
-        body = self.get_project(project_id)['project']
-        name = kwargs.get('name', body['name'])
-        desc = kwargs.get('description', body['description'])
-        en = kwargs.get('enabled', body['enabled'])
-        domain_id = kwargs.get('domain_id', body['domain_id'])
-        post_body = {
-            'id': project_id,
-            'name': name,
-            'description': desc,
-            'enabled': en,
-            'domain_id': domain_id,
-        }
-        post_body = json.dumps({'project': post_body})
-        resp, body = self.patch('projects/%s' % project_id, post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def get_project(self, project_id):
-        """GET a Project."""
-        resp, body = self.get("projects/%s" % project_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_project(self, project_id):
-        """Delete a project."""
-        resp, body = self.delete('projects/%s' % str(project_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
     def create_role(self, **kwargs):
         """Create a Role.
 
@@ -224,13 +74,6 @@
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
 
-    def assign_user_role(self, project_id, user_id, role_id):
-        """Add roles to a user on a project."""
-        resp, body = self.put('projects/%s/users/%s/roles/%s' %
-                              (project_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
     def create_domain(self, name, **kwargs):
         """Creates a domain."""
         description = kwargs.get('description', None)
@@ -264,7 +107,7 @@
 
     def update_domain(self, domain_id, **kwargs):
         """Updates a domain."""
-        body = self.get_domain(domain_id)['domain']
+        body = self.show_domain(domain_id)['domain']
         description = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
         name = kwargs.get('name', body['name'])
@@ -279,7 +122,7 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def get_domain(self, domain_id):
+    def show_domain(self, domain_id):
         """Get Domain details."""
         resp, body = self.get('domains/%s' % domain_id)
         self.expected_success(200, resp.status)
@@ -301,13 +144,6 @@
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
 
-    def list_user_groups(self, user_id):
-        """Lists groups which a user belongs to."""
-        resp, body = self.get('users/%s/groups' % user_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
     def assign_user_role_on_project(self, project_id, user_id, role_id):
         """Add roles to a user on a project."""
         resp, body = self.put('projects/%s/users/%s/roles/%s' %
@@ -352,6 +188,22 @@
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
 
+    def check_user_role_existence_on_project(self, project_id,
+                                             user_id, role_id):
+        """Check role of a user on a project."""
+        resp, body = self.head('projects/%s/users/%s/roles/%s' %
+                               (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
+
+    def check_user_role_existence_on_domain(self, domain_id,
+                                            user_id, role_id):
+        """Check role of a user on a domain."""
+        resp, body = self.head('domains/%s/users/%s/roles/%s' %
+                               (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
+
     def assign_group_role_on_project(self, project_id, group_id, role_id):
         """Add roles to a user on a project."""
         resp, body = self.put('projects/%s/groups/%s/roles/%s' %
@@ -396,6 +248,22 @@
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
 
+    def check_role_from_group_on_project_existence(self, project_id,
+                                                   group_id, role_id):
+        """Check role of a user on a project."""
+        resp, body = self.head('projects/%s/groups/%s/roles/%s' %
+                               (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
+
+    def check_role_from_group_on_domain_existence(self, domain_id,
+                                                  group_id, role_id):
+        """Check role of a user on a domain."""
+        resp, body = self.head('domains/%s/groups/%s/roles/%s' %
+                               (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
+
     def create_trust(self, **kwargs):
         """Creates a trust.
 
@@ -414,7 +282,7 @@
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
 
-    def get_trusts(self, trustor_user_id=None, trustee_user_id=None):
+    def list_trusts(self, trustor_user_id=None, trustee_user_id=None):
         """GET trusts."""
         if trustor_user_id:
             resp, body = self.get("OS-TRUST/trusts?trustor_user_id=%s"
@@ -428,21 +296,21 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def get_trust(self, trust_id):
+    def show_trust(self, trust_id):
         """GET trust."""
         resp, body = self.get("OS-TRUST/trusts/%s" % trust_id)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def get_trust_roles(self, trust_id):
+    def list_trust_roles(self, trust_id):
         """GET roles delegated by a trust."""
         resp, body = self.get("OS-TRUST/trusts/%s/roles" % trust_id)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def get_trust_role(self, trust_id, role_id):
+    def show_trust_role(self, trust_id, role_id):
         """GET role delegated by a trust."""
         resp, body = self.get("OS-TRUST/trusts/%s/roles/%s"
                               % (trust_id, role_id))
diff --git a/tempest/services/identity/v3/json/projects_client.py b/tempest/services/identity/v3/json/projects_client.py
new file mode 100644
index 0000000..2fa822f
--- /dev/null
+++ b/tempest/services/identity/v3/json/projects_client.py
@@ -0,0 +1,81 @@
+# Copyright 2013 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest.common import service_client
+
+
+class ProjectsClient(service_client.ServiceClient):
+    api_version = "v3"
+
+    def create_project(self, name, **kwargs):
+        """Creates a project."""
+        description = kwargs.get('description', None)
+        en = kwargs.get('enabled', True)
+        domain_id = kwargs.get('domain_id', 'default')
+        post_body = {
+            'description': description,
+            'domain_id': domain_id,
+            'enabled': en,
+            'name': name
+        }
+        post_body = json.dumps({'project': post_body})
+        resp, body = self.post('projects', post_body)
+        self.expected_success(201, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def list_projects(self, params=None):
+        url = "projects"
+        if params:
+            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)
+
+    def update_project(self, project_id, **kwargs):
+        body = self.show_project(project_id)['project']
+        name = kwargs.get('name', body['name'])
+        desc = kwargs.get('description', body['description'])
+        en = kwargs.get('enabled', body['enabled'])
+        domain_id = kwargs.get('domain_id', body['domain_id'])
+        post_body = {
+            'id': project_id,
+            'name': name,
+            'description': desc,
+            'enabled': en,
+            'domain_id': domain_id,
+        }
+        post_body = json.dumps({'project': post_body})
+        resp, body = self.patch('projects/%s' % project_id, post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def show_project(self, project_id):
+        """GET a Project."""
+        resp, body = self.get("projects/%s" % project_id)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_project(self, project_id):
+        """Delete a project."""
+        resp, body = self.delete('projects/%s' % str(project_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/users_clients.py b/tempest/services/identity/v3/json/users_clients.py
new file mode 100644
index 0000000..85c2e79
--- /dev/null
+++ b/tempest/services/identity/v3/json/users_clients.py
@@ -0,0 +1,121 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest.common import service_client
+
+
+class UsersV3Client(service_client.ServiceClient):
+    api_version = "v3"
+
+    def create_user(self, user_name, password=None, project_id=None,
+                    email=None, domain_id='default', **kwargs):
+        """Creates a user."""
+        en = kwargs.get('enabled', True)
+        description = kwargs.get('description', None)
+        default_project_id = kwargs.get('default_project_id')
+        post_body = {
+            'project_id': project_id,
+            'default_project_id': default_project_id,
+            'description': description,
+            'domain_id': domain_id,
+            'email': email,
+            'enabled': en,
+            'name': user_name,
+            'password': password
+        }
+        post_body = json.dumps({'user': post_body})
+        resp, body = self.post('users', post_body)
+        self.expected_success(201, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def update_user(self, user_id, name, **kwargs):
+        """Updates a user."""
+        body = self.show_user(user_id)['user']
+        email = kwargs.get('email', body['email'])
+        en = kwargs.get('enabled', body['enabled'])
+        project_id = kwargs.get('project_id', body['project_id'])
+        if 'default_project_id' in body.keys():
+            default_project_id = kwargs.get('default_project_id',
+                                            body['default_project_id'])
+        else:
+            default_project_id = kwargs.get('default_project_id')
+        description = kwargs.get('description', body['description'])
+        domain_id = kwargs.get('domain_id', body['domain_id'])
+        post_body = {
+            'name': name,
+            'email': email,
+            'enabled': en,
+            'project_id': project_id,
+            'default_project_id': default_project_id,
+            'id': user_id,
+            'domain_id': domain_id,
+            'description': description
+        }
+        post_body = json.dumps({'user': post_body})
+        resp, body = self.patch('users/%s' % user_id, post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def update_user_password(self, user_id, **kwargs):
+        """Update a user password
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#changeUserPassword
+        """
+        update_user = json.dumps({'user': kwargs})
+        resp, _ = self.post('users/%s/password' % user_id, update_user)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
+
+    def list_user_projects(self, user_id):
+        """Lists the projects on which a user has roles assigned."""
+        resp, body = self.get('users/%s/projects' % user_id)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def list_users(self, params=None):
+        """Get the list of users."""
+        url = 'users'
+        if params:
+            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)
+
+    def show_user(self, user_id):
+        """GET a user."""
+        resp, body = self.get("users/%s" % user_id)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_user(self, user_id):
+        """Deletes a User."""
+        resp, body = self.delete("users/%s" % user_id)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def list_user_groups(self, user_id):
+        """Lists groups which a user belongs to."""
+        resp, body = self.get('users/%s/groups' % user_id)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/image/v1/json/images_client.py b/tempest/services/image/v1/json/images_client.py
index 5b6a394..af2e68c 100644
--- a/tempest/services/image/v1/json/images_client.py
+++ b/tempest/services/image/v1/json/images_client.py
@@ -180,21 +180,27 @@
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, body)
 
-    def list_images(self, detail=False, properties=dict(),
-                    changes_since=None, **kwargs):
+    def list_images(self, detail=False, **kwargs):
+        """Return a list of all images filtered by input parameters.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-image-v1.html#listImage-v1
+
+        Most parameters except the following are passed to the API without
+        any changes.
+        :param changes_since: The name is changed to changes-since
+        """
         url = 'v1/images'
 
         if detail:
             url += '/detail'
 
-        params = {}
-        for key, value in properties.items():
-            params['property-%s' % key] = value
+        properties = kwargs.pop('properties', {})
+        for key, value in six.iteritems(properties):
+            kwargs['property-%s' % key] = value
 
-        kwargs.update(params)
-
-        if changes_since is not None:
-            kwargs['changes-since'] = changes_since
+        if kwargs.get('changes_since'):
+            kwargs['changes-since'] = kwargs.pop('changes_since')
 
         if len(kwargs) > 0:
             url += '?%s' % urllib.urlencode(kwargs)
diff --git a/tempest/services/messaging/__init__.py b/tempest/services/messaging/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/messaging/__init__.py
+++ /dev/null
diff --git a/tempest/services/messaging/json/__init__.py b/tempest/services/messaging/json/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/messaging/json/__init__.py
+++ /dev/null
diff --git a/tempest/services/messaging/json/messaging_client.py b/tempest/services/messaging/json/messaging_client.py
deleted file mode 100644
index 5a43841..0000000
--- a/tempest/services/messaging/json/messaging_client.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# Copyright (c) 2014 Rackspace, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import uuid
-
-from oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.api_schema.response.messaging.v1 import queues as queues_schema
-from tempest.common import service_client
-
-
-class MessagingClient(service_client.ServiceClient):
-
-    def __init__(self, auth_provider, service, region,
-                 endpoint_type=None, build_interval=None, build_timeout=None,
-                 disable_ssl_certificate_validation=None, ca_certs=None,
-                 trace_requests=None):
-        dscv = disable_ssl_certificate_validation
-        super(MessagingClient, self).__init__(
-            auth_provider, service, region,
-            endpoint_type=endpoint_type,
-            build_interval=build_interval,
-            build_timeout=build_timeout,
-            disable_ssl_certificate_validation=dscv,
-            ca_certs=ca_certs,
-            trace_requests=trace_requests)
-
-        self.version = '1'
-        self.uri_prefix = 'v{0}'.format(self.version)
-
-        client_id = uuid.uuid4().hex
-        self.headers = {'Client-ID': client_id}
-
-    def list_queues(self):
-        uri = '{0}/queues'.format(self.uri_prefix)
-        resp, body = self.get(uri)
-
-        if resp['status'] != '204':
-            body = json.loads(body)
-            self.validate_response(queues_schema.list_queues, resp, body)
-        return resp, body
-
-    def create_queue(self, queue_name):
-        uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
-        resp, body = self.put(uri, body=None)
-        self.expected_success(201, resp.status)
-        return resp, body
-
-    def show_queue(self, queue_name):
-        uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
-        resp, body = self.get(uri)
-        self.expected_success(204, resp.status)
-        return resp, body
-
-    def head_queue(self, queue_name):
-        uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
-        resp, body = self.head(uri)
-        self.expected_success(204, resp.status)
-        return resp, body
-
-    def delete_queue(self, queue_name):
-        uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
-        resp, body = self.delete(uri)
-        self.expected_success(204, resp.status)
-        return resp, body
-
-    def show_queue_stats(self, queue_name):
-        uri = '{0}/queues/{1}/stats'.format(self.uri_prefix, queue_name)
-        resp, body = self.get(uri)
-        body = json.loads(body)
-        self.validate_response(queues_schema.queue_stats, resp, body)
-        return resp, body
-
-    def show_queue_metadata(self, queue_name):
-        uri = '{0}/queues/{1}/metadata'.format(self.uri_prefix, queue_name)
-        resp, body = self.get(uri)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return resp, body
-
-    def set_queue_metadata(self, queue_name, rbody):
-        uri = '{0}/queues/{1}/metadata'.format(self.uri_prefix, queue_name)
-        resp, body = self.put(uri, body=json.dumps(rbody))
-        self.expected_success(204, resp.status)
-        return resp, body
-
-    def post_messages(self, queue_name, rbody):
-        uri = '{0}/queues/{1}/messages'.format(self.uri_prefix, queue_name)
-        resp, body = self.post(uri, body=json.dumps(rbody),
-                               extra_headers=True,
-                               headers=self.headers)
-
-        body = json.loads(body)
-        self.validate_response(queues_schema.post_messages, resp, body)
-        return resp, body
-
-    def list_messages(self, queue_name):
-        uri = '{0}/queues/{1}/messages?echo=True'.format(self.uri_prefix,
-                                                         queue_name)
-        resp, body = self.get(uri, extra_headers=True, headers=self.headers)
-
-        if resp['status'] != '204':
-            body = json.loads(body)
-            self.validate_response(queues_schema.list_messages, resp, body)
-
-        return resp, body
-
-    def show_single_message(self, message_uri):
-        resp, body = self.get(message_uri, extra_headers=True,
-                              headers=self.headers)
-        if resp['status'] != '204':
-            body = json.loads(body)
-            self.validate_response(queues_schema.get_single_message, resp,
-                                   body)
-        return resp, body
-
-    def show_multiple_messages(self, message_uri):
-        resp, body = self.get(message_uri, extra_headers=True,
-                              headers=self.headers)
-
-        if resp['status'] != '204':
-            body = json.loads(body)
-            self.validate_response(queues_schema.get_multiple_messages,
-                                   resp,
-                                   body)
-
-        return resp, body
-
-    def delete_messages(self, message_uri):
-        resp, body = self.delete(message_uri)
-        self.expected_success(204, resp.status)
-        return resp, body
-
-    def post_claims(self, queue_name, rbody, url_params=False):
-        uri = '{0}/queues/{1}/claims'.format(self.uri_prefix, queue_name)
-        if url_params:
-            uri += '?%s' % urllib.urlencode(url_params)
-
-        resp, body = self.post(uri, body=json.dumps(rbody),
-                               extra_headers=True,
-                               headers=self.headers)
-
-        body = json.loads(body)
-        self.validate_response(queues_schema.claim_messages, resp, body)
-        return resp, body
-
-    def query_claim(self, claim_uri):
-        resp, body = self.get(claim_uri)
-
-        if resp['status'] != '204':
-            body = json.loads(body)
-            self.validate_response(queues_schema.query_claim, resp, body)
-        return resp, body
-
-    def update_claim(self, claim_uri, rbody):
-        resp, body = self.patch(claim_uri, body=json.dumps(rbody))
-        self.expected_success(204, resp.status)
-        return resp, body
-
-    def delete_claim(self, claim_uri):
-        resp, body = self.delete(claim_uri)
-        self.expected_success(204, resp.status)
-        return resp, body
diff --git a/tempest/services/network/json/agents_client.py b/tempest/services/network/json/agents_client.py
deleted file mode 100644
index 07f93b2..0000000
--- a/tempest/services/network/json/agents_client.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2015 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from tempest.services.network.json import base
-
-
-class AgentsClient(base.BaseNetworkClient):
-
-    def update_agent(self, agent_id, **kwargs):
-        """Update agent."""
-        # TODO(piyush): Current api-site doesn't contain this API description.
-        # After fixing the api-site, we need to fix here also for putting the
-        # link to api-site.
-        # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526673
-        uri = '/agents/%s' % agent_id
-        return self.update_resource(uri, kwargs)
-
-    def show_agent(self, agent_id, **fields):
-        uri = '/agents/%s' % agent_id
-        return self.show_resource(uri, **fields)
-
-    def list_agents(self, **filters):
-        uri = '/agents'
-        return self.list_resources(uri, **filters)
-
-    def list_routers_on_l3_agent(self, agent_id):
-        uri = '/agents/%s/l3-routers' % agent_id
-        return self.list_resources(uri)
-
-    def add_router_to_l3_agent(self, agent_id, **kwargs):
-        # TODO(piyush): Current api-site doesn't contain this API description.
-        # After fixing the api-site, we need to fix here also for putting the
-        # link to api-site.
-        # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526670
-        uri = '/agents/%s/l3-routers' % agent_id
-        return self.create_resource(uri, kwargs)
-
-    def remove_router_from_l3_agent(self, agent_id, router_id):
-        uri = '/agents/%s/l3-routers/%s' % (agent_id, router_id)
-        return self.delete_resource(uri)
-
-    def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
-        uri = '/agents/%s/dhcp-networks' % agent_id
-        return self.list_resources(uri)
-
-    def remove_network_from_dhcp_agent(self, agent_id, network_id):
-        uri = '/agents/%s/dhcp-networks/%s' % (agent_id,
-                                               network_id)
-        return self.delete_resource(uri)
-
-    def add_dhcp_agent_to_network(self, agent_id, **kwargs):
-        # TODO(piyush): Current api-site doesn't contain this API description.
-        # After fixing the api-site, we need to fix here also for putting the
-        # link to api-site.
-        # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526212
-        uri = '/agents/%s/dhcp-networks' % agent_id
-        return self.create_resource(uri, kwargs)
diff --git a/tempest/services/network/json/metering_label_rules_client.py b/tempest/services/network/json/metering_label_rules_client.py
deleted file mode 100644
index 374a89c..0000000
--- a/tempest/services/network/json/metering_label_rules_client.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#    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.network.json import base
-
-
-class MeteringLabelRulesClient(base.BaseNetworkClient):
-
-    def create_metering_label_rule(self, **kwargs):
-        uri = '/metering/metering-label-rules'
-        post_data = {'metering_label_rule': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def show_metering_label_rule(self, metering_label_rule_id, **fields):
-        uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
-        return self.show_resource(uri, **fields)
-
-    def delete_metering_label_rule(self, metering_label_rule_id):
-        uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
-        return self.delete_resource(uri)
-
-    def list_metering_label_rules(self, **filters):
-        uri = '/metering/metering-label-rules'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/metering_labels_client.py b/tempest/services/network/json/metering_labels_client.py
deleted file mode 100644
index 2e5cdae..0000000
--- a/tempest/services/network/json/metering_labels_client.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#    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.network.json import base
-
-
-class MeteringLabelsClient(base.BaseNetworkClient):
-
-    def create_metering_label(self, **kwargs):
-        uri = '/metering/metering-labels'
-        post_data = {'metering_label': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def show_metering_label(self, metering_label_id, **fields):
-        uri = '/metering/metering-labels/%s' % metering_label_id
-        return self.show_resource(uri, **fields)
-
-    def delete_metering_label(self, metering_label_id):
-        uri = '/metering/metering-labels/%s' % metering_label_id
-        return self.delete_resource(uri)
-
-    def list_metering_labels(self, **filters):
-        uri = '/metering/metering-labels'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index e8e21d2..c6b22df 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -35,31 +35,6 @@
     quotas
     """
 
-    def create_security_group_rule(self, **kwargs):
-        uri = '/security-group-rules'
-        post_data = {'security_group_rule': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def show_security_group_rule(self, security_group_rule_id, **fields):
-        uri = '/security-group-rules/%s' % security_group_rule_id
-        return self.show_resource(uri, **fields)
-
-    def delete_security_group_rule(self, security_group_rule_id):
-        uri = '/security-group-rules/%s' % security_group_rule_id
-        return self.delete_resource(uri)
-
-    def list_security_group_rules(self, **filters):
-        uri = '/security-group-rules'
-        return self.list_resources(uri, **filters)
-
-    def show_extension(self, ext_alias, **fields):
-        uri = '/extensions/%s' % ext_alias
-        return self.show_resource(uri, **fields)
-
-    def list_extensions(self, **filters):
-        uri = '/extensions'
-        return self.list_resources(uri, **filters)
-
     def create_bulk_network(self, **kwargs):
         """create bulk network
 
@@ -205,25 +180,23 @@
         """
         return self._update_router(router_id, set_enable_snat=True, **kwargs)
 
-    def add_router_interface_with_subnet_id(self, router_id, subnet_id):
+    def add_router_interface(self, router_id, **kwargs):
+        """Add router interface.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-networking-v2-ext.html#addRouterInterface
+        """
         uri = '/routers/%s/add_router_interface' % router_id
-        update_body = {"subnet_id": subnet_id}
-        return self.update_resource(uri, update_body)
+        return self.update_resource(uri, kwargs)
 
-    def add_router_interface_with_port_id(self, router_id, port_id):
-        uri = '/routers/%s/add_router_interface' % router_id
-        update_body = {"port_id": port_id}
-        return self.update_resource(uri, update_body)
+    def remove_router_interface(self, router_id, **kwargs):
+        """Remove router interface.
 
-    def remove_router_interface_with_subnet_id(self, router_id, subnet_id):
+        Available params: see http://developer.openstack.org/
+                              api-ref-networking-v2-ext.html#removeRouterInterface
+        """
         uri = '/routers/%s/remove_router_interface' % router_id
-        update_body = {"subnet_id": subnet_id}
-        return self.update_resource(uri, update_body)
-
-    def remove_router_interface_with_port_id(self, router_id, port_id):
-        uri = '/routers/%s/remove_router_interface' % router_id
-        update_body = {"port_id": port_id}
-        return self.update_resource(uri, update_body)
+        return self.update_resource(uri, kwargs)
 
     def list_router_interfaces(self, uuid):
         uri = '/ports?device_id=%s' % uuid
diff --git a/tempest/services/network/json/networks_client.py b/tempest/services/network/json/networks_client.py
deleted file mode 100644
index 2907d44..0000000
--- a/tempest/services/network/json/networks_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#    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.network.json import base
-
-
-class NetworksClient(base.BaseNetworkClient):
-
-    def create_network(self, **kwargs):
-        uri = '/networks'
-        post_data = {'network': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_network(self, network_id, **kwargs):
-        uri = '/networks/%s' % network_id
-        post_data = {'network': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_network(self, network_id, **fields):
-        uri = '/networks/%s' % network_id
-        return self.show_resource(uri, **fields)
-
-    def delete_network(self, network_id):
-        uri = '/networks/%s' % network_id
-        return self.delete_resource(uri)
-
-    def list_networks(self, **filters):
-        uri = '/networks'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/ports_client.py b/tempest/services/network/json/ports_client.py
deleted file mode 100644
index d52d65e..0000000
--- a/tempest/services/network/json/ports_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#    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.network.json import base
-
-
-class PortsClient(base.BaseNetworkClient):
-
-    def create_port(self, **kwargs):
-        uri = '/ports'
-        post_data = {'port': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_port(self, port_id, **kwargs):
-        uri = '/ports/%s' % port_id
-        post_data = {'port': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_port(self, port_id, **fields):
-        uri = '/ports/%s' % port_id
-        return self.show_resource(uri, **fields)
-
-    def delete_port(self, port_id):
-        uri = '/ports/%s' % port_id
-        return self.delete_resource(uri)
-
-    def list_ports(self, **filters):
-        uri = '/ports'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/quotas_client.py b/tempest/services/network/json/quotas_client.py
deleted file mode 100644
index 9b65a54..0000000
--- a/tempest/services/network/json/quotas_client.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2015 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from tempest.services.network.json import base
-
-
-class QuotasClient(base.BaseNetworkClient):
-
-    def update_quotas(self, tenant_id, **kwargs):
-        put_body = {'quota': kwargs}
-        uri = '/quotas/%s' % tenant_id
-        return self.update_resource(uri, put_body)
-
-    def reset_quotas(self, tenant_id):
-        uri = '/quotas/%s' % tenant_id
-        return self.delete_resource(uri)
-
-    def show_quotas(self, tenant_id, **fields):
-        uri = '/quotas/%s' % tenant_id
-        return self.show_resource(uri, **fields)
-
-    def list_quotas(self, **filters):
-        uri = '/quotas'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/security_group_rules_client.py b/tempest/services/network/json/security_group_rules_client.py
new file mode 100644
index 0000000..b2ba5b2
--- /dev/null
+++ b/tempest/services/network/json/security_group_rules_client.py
@@ -0,0 +1,33 @@
+#    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.network.json import base
+
+
+class SecurityGroupRulesClient(base.BaseNetworkClient):
+
+    def create_security_group_rule(self, **kwargs):
+        uri = '/security-group-rules'
+        post_data = {'security_group_rule': kwargs}
+        return self.create_resource(uri, post_data)
+
+    def show_security_group_rule(self, security_group_rule_id, **fields):
+        uri = '/security-group-rules/%s' % security_group_rule_id
+        return self.show_resource(uri, **fields)
+
+    def delete_security_group_rule(self, security_group_rule_id):
+        uri = '/security-group-rules/%s' % security_group_rule_id
+        return self.delete_resource(uri)
+
+    def list_security_group_rules(self, **filters):
+        uri = '/security-group-rules'
+        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/security_groups_client.py b/tempest/services/network/json/security_groups_client.py
deleted file mode 100644
index a60d2a6..0000000
--- a/tempest/services/network/json/security_groups_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#    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.network.json import base
-
-
-class SecurityGroupsClient(base.BaseNetworkClient):
-
-    def create_security_group(self, **kwargs):
-        uri = '/security-groups'
-        post_data = {'security_group': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_security_group(self, security_group_id, **kwargs):
-        uri = '/security-groups/%s' % security_group_id
-        post_data = {'security_group': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_security_group(self, security_group_id, **fields):
-        uri = '/security-groups/%s' % security_group_id
-        return self.show_resource(uri, **fields)
-
-    def delete_security_group(self, security_group_id):
-        uri = '/security-groups/%s' % security_group_id
-        return self.delete_resource(uri)
-
-    def list_security_groups(self, **filters):
-        uri = '/security-groups'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/subnetpools_client.py b/tempest/services/network/json/subnetpools_client.py
deleted file mode 100644
index f921bb0..0000000
--- a/tempest/services/network/json/subnetpools_client.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2015 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from tempest.services.network.json import base
-
-
-class SubnetpoolsClient(base.BaseNetworkClient):
-
-    def list_subnetpools(self, **filters):
-        uri = '/subnetpools'
-        return self.list_resources(uri, **filters)
-
-    def create_subnetpool(self, **kwargs):
-        uri = '/subnetpools'
-        post_data = {'subnetpool': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def show_subnetpool(self, subnetpool_id, **fields):
-        uri = '/subnetpools/%s' % subnetpool_id
-        return self.show_resource(uri, **fields)
-
-    def update_subnetpool(self, subnetpool_id, **kwargs):
-        uri = '/subnetpools/%s' % subnetpool_id
-        post_data = {'subnetpool': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def delete_subnetpool(self, subnetpool_id):
-        uri = '/subnetpools/%s' % subnetpool_id
-        return self.delete_resource(uri)
diff --git a/tempest/services/network/json/subnets_client.py b/tempest/services/network/json/subnets_client.py
deleted file mode 100644
index 957b606..0000000
--- a/tempest/services/network/json/subnets_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#    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.network.json import base
-
-
-class SubnetsClient(base.BaseNetworkClient):
-
-    def create_subnet(self, **kwargs):
-        uri = '/subnets'
-        post_data = {'subnet': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_subnet(self, subnet_id, **kwargs):
-        uri = '/subnets/%s' % subnet_id
-        post_data = {'subnet': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_subnet(self, subnet_id, **fields):
-        uri = '/subnets/%s' % subnet_id
-        return self.show_resource(uri, **fields)
-
-    def delete_subnet(self, subnet_id):
-        uri = '/subnets/%s' % subnet_id
-        return self.delete_resource(uri)
-
-    def list_subnets(self, **filters):
-        uri = '/subnets'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index 10911f7..0a7da92 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -89,14 +89,13 @@
 
     def add_to_router(self, router_id):
         self._router_ids.add(router_id)
-        self.network_client.add_router_interface_with_subnet_id(
-            router_id, subnet_id=self.id)
+        self.network_client.add_router_interface(router_id,
+                                                 subnet_id=self.id)
 
     def delete(self):
         for router_id in self._router_ids.copy():
-            self.network_client.remove_router_interface_with_subnet_id(
-                router_id,
-                subnet_id=self.id)
+            self.network_client.remove_router_interface(router_id,
+                                                        subnet_id=self.id)
             self._router_ids.remove(router_id)
         self.subnets_client.delete_subnet(self.id)
 
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 6531059..3c69a8b 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -151,12 +151,14 @@
                     users_client = admin_manager.users_client
                 else:
                     identity_client = admin_manager.identity_v3_client
-                    projects_client = None
+                    projects_client = admin_manager.projects_client
                     roles_client = None
-                    users_client = None
+                    users_client = admin_manager.users_v3_client
+                domain = (identity_client.auth_provider.credentials.
+                          get('project_domain_name', 'Default'))
                 credentials_client = cred_client.get_creds_client(
-                    identity_client, projects_client, roles_client,
-                    users_client)
+                    identity_client, projects_client, users_client,
+                    roles_client, project_domain_name=domain)
                 project = credentials_client.create_project(
                     name=tenant_name, description=tenant_name)
                 user = credentials_client.create_user(username, password,
diff --git a/tempest/stress/etc/sample-unit-test.json b/tempest/stress/etc/sample-unit-test.json
index b388bfe..54433d5 100644
--- a/tempest/stress/etc/sample-unit-test.json
+++ b/tempest/stress/etc/sample-unit-test.json
@@ -1,7 +1,7 @@
 [{"action": "tempest.stress.actions.unit_test.UnitTest",
   "threads": 8,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {"test_method": "tempest.cli.simple_read_only.test_glance.SimpleReadOnlyGlanceClientTest.test_glance_fake_action",
              "class_setup_per": "process"}
   }
diff --git a/tempest/stress/etc/server-create-destroy-test.json b/tempest/stress/etc/server-create-destroy-test.json
index 17d5e1a..bbb5352 100644
--- a/tempest/stress/etc/server-create-destroy-test.json
+++ b/tempest/stress/etc/server-create-destroy-test.json
@@ -1,7 +1,7 @@
 [{"action": "tempest.stress.actions.server_create_destroy.ServerCreateDestroyTest",
   "threads": 8,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {}
   }
 ]
diff --git a/tempest/stress/etc/ssh_floating.json b/tempest/stress/etc/ssh_floating.json
index e03fd4f..c502e96 100644
--- a/tempest/stress/etc/ssh_floating.json
+++ b/tempest/stress/etc/ssh_floating.json
@@ -1,7 +1,7 @@
 [{"action": "tempest.stress.actions.ssh_floating.FloatingStress",
   "threads": 8,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {"vm_extra_args": {},
              "new_vm": true,
              "new_sec_group": true,
diff --git a/tempest/stress/etc/stress-tox-job.json b/tempest/stress/etc/stress-tox-job.json
index 9cee316..bfa448d 100644
--- a/tempest/stress/etc/stress-tox-job.json
+++ b/tempest/stress/etc/stress-tox-job.json
@@ -1,25 +1,25 @@
 [{"action": "tempest.stress.actions.server_create_destroy.ServerCreateDestroyTest",
   "threads": 8,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {}
   },
   {"action": "tempest.stress.actions.volume_create_delete.VolumeCreateDeleteTest",
   "threads": 4,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {}
   },
   {"action": "tempest.stress.actions.volume_attach_delete.VolumeAttachDeleteTest",
   "threads": 2,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {}
   },
   {"action": "tempest.stress.actions.unit_test.UnitTest",
   "threads": 4,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "required_services": ["neutron"],
   "kwargs": {"test_method": "tempest.scenario.test_network_advanced_server_ops.TestNetworkAdvancedServerOps.test_server_connectivity_stop_start",
              "class_setup_per": "process"}
diff --git a/tempest/stress/etc/volume-attach-delete-test.json b/tempest/stress/etc/volume-attach-delete-test.json
index 4553ff8..d468967 100644
--- a/tempest/stress/etc/volume-attach-delete-test.json
+++ b/tempest/stress/etc/volume-attach-delete-test.json
@@ -1,7 +1,7 @@
 [{"action": "tempest.stress.actions.volume_attach_delete.VolumeAttachDeleteTest",
   "threads": 4,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {}
   }
 ]
diff --git a/tempest/stress/etc/volume-attach-verify.json b/tempest/stress/etc/volume-attach-verify.json
index 731f5ed..d8c96fd 100644
--- a/tempest/stress/etc/volume-attach-verify.json
+++ b/tempest/stress/etc/volume-attach-verify.json
@@ -1,7 +1,7 @@
 [{"action": "tempest.stress.actions.volume_attach_verify.VolumeVerifyStress",
   "threads": 1,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {"vm_extra_args": {},
              "new_volume": true,
              "new_server": false,
diff --git a/tempest/stress/etc/volume-create-delete-test.json b/tempest/stress/etc/volume-create-delete-test.json
index e8a58f7..a60cde6 100644
--- a/tempest/stress/etc/volume-create-delete-test.json
+++ b/tempest/stress/etc/volume-create-delete-test.json
@@ -1,7 +1,7 @@
 [{"action": "tempest.stress.actions.volume_create_delete.VolumeCreateDeleteTest",
   "threads": 4,
-  "use_admin": false,
-  "use_isolated_tenants": false,
+  "use_admin": true,
+  "use_isolated_tenants": true,
   "kwargs": {}
   }
 ]
diff --git a/tempest/test.py b/tempest/test.py
index dfed947..ee3288c 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -234,6 +234,9 @@
     log_format = ('%(asctime)s %(process)d %(levelname)-8s '
                   '[%(name)s] %(message)s')
 
+    # Client manager class to use in this test case.
+    client_manager = clients.Manager
+
     @classmethod
     def setUpClass(cls):
         # It should never be overridden by descendants
@@ -293,7 +296,7 @@
                     LOG.exception("teardown of %s failed: %s" % (name, te))
                 if not etype:
                     etype, value, trace = sys_exec_info
-        # If exceptions were raised during teardown, an not before, re-raise
+        # If exceptions were raised during teardown, and not before, re-raise
         # the first one
         if re_raise and etype is not None:
             try:
@@ -437,14 +440,14 @@
         """
         if CONF.identity.auth_version == 'v2':
             client = self.os_admin.identity_client
+            users_client = self.os_admin.users_client
             project_client = self.os_admin.tenants_client
             roles_client = self.os_admin.roles_client
-            users_client = self.os_admin.users_client
         else:
             client = self.os_admin.identity_v3_client
-            project_client = None
+            project_client = self.os_adm.projects_client
+            users_client = self.os_admin.users_v3_client
             roles_client = None
-            users_client = None
 
         try:
             domain = client.auth_provider.credentials.project_domain_name
@@ -452,8 +455,8 @@
             domain = 'Default'
 
         return cred_client.get_creds_client(client, project_client,
-                                            roles_client,
                                             users_client,
+                                            roles_client,
                                             project_domain_name=domain)
 
     @classmethod
@@ -519,8 +522,8 @@
             else:
                 raise exceptions.InvalidCredentials(
                     "Invalid credentials type %s" % credential_type)
-        return clients.Manager(credentials=creds, service=cls._service,
-                               api_microversions=cls.services_microversion)
+        return cls.client_manager(credentials=creds, service=cls._service,
+                                  api_microversions=cls.services_microversion)
 
     @classmethod
     def clear_credentials(cls):
@@ -600,7 +603,7 @@
         networks_client = cls.get_client_manager().compute_networks_client
         cred_provider = cls._get_credentials_provider()
         # In case of nova network, isolated tenants are not able to list the
-        # network configured in fixed_network_name, even if the can use it
+        # network configured in fixed_network_name, even if they can use it
         # for their servers, so using an admin network client to validate
         # the network name
         if (not CONF.service_available.neutron and
@@ -790,9 +793,9 @@
 
     @classmethod
     def set_resource(cls, name, resource):
-        """Register a resoruce for a test
+        """Register a resource for a test
 
-        This function can be used in setUpClass context to register a resoruce
+        This function can be used in setUpClass context to register a resource
         for a test.
 
         :param name: The name of the kind of resource such as "flavor", "role",
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index 2fbb206..ab6a7a0 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -24,7 +24,7 @@
 
     def setUp(self):
         super(JavelinUnitTest, self).setUp()
-        javelin.setup_logging()
+        javelin.LOG = mock.MagicMock()
         self.fake_client = mock.MagicMock()
         self.fake_object = mock.MagicMock()
 
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index a5dea54..193abc7 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -201,7 +201,8 @@
                                    {'alias': 'fake2'},
                                    {'alias': 'not_fake'}]}
         fake_os = mock.MagicMock()
-        fake_os.network_client.list_extensions = fake_list_extensions
+        fake_os.network_extensions_client.list_extensions = (
+            fake_list_extensions)
         self.useFixture(mockpatch.PatchObject(
             verify_tempest_config, 'get_enabled_extensions',
             return_value=(['fake1', 'fake2', 'fake3'])))
@@ -223,7 +224,8 @@
                                    {'alias': 'fake2'},
                                    {'alias': 'not_fake'}]}
         fake_os = mock.MagicMock()
-        fake_os.network_client.list_extensions = fake_list_extensions
+        fake_os.network_extensions_client.list_extensions = (
+            fake_list_extensions)
         self.useFixture(mockpatch.PatchObject(
             verify_tempest_config, 'get_enabled_extensions',
             return_value=(['all'])))
diff --git a/tempest/tests/common/test_api_version_utils.py b/tempest/tests/common/test_api_version_utils.py
index 9f399a2..501f954 100644
--- a/tempest/tests/common/test_api_version_utils.py
+++ b/tempest/tests/common/test_api_version_utils.py
@@ -12,146 +12,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_config import cfg
 import testtools
 
-from tempest.api.compute import base as compute_base
 from tempest.common import api_version_utils
-from tempest import config
 from tempest import exceptions
 from tempest.tests import base
-from tempest.tests import fake_config
-
-
-class VersionTestNoneTolatest(compute_base.BaseV2ComputeTest):
-    min_microversion = None
-    max_microversion = 'latest'
-
-
-class VersionTestNoneTo2_2(compute_base.BaseV2ComputeTest):
-    min_microversion = None
-    max_microversion = '2.2'
-
-
-class VersionTest2_3ToLatest(compute_base.BaseV2ComputeTest):
-    min_microversion = '2.3'
-    max_microversion = 'latest'
-
-
-class VersionTest2_5To2_10(compute_base.BaseV2ComputeTest):
-    min_microversion = '2.5'
-    max_microversion = '2.10'
-
-
-class VersionTest2_10To2_10(compute_base.BaseV2ComputeTest):
-    min_microversion = '2.10'
-    max_microversion = '2.10'
-
-
-class InvalidVersionTest(compute_base.BaseV2ComputeTest):
-    min_microversion = '2.11'
-    max_microversion = '2.1'
-
-
-class TestMicroversionsTestsClass(base.TestCase):
-
-    def setUp(self):
-        super(TestMicroversionsTestsClass, self).setUp()
-        self.useFixture(fake_config.ConfigFixture())
-        self.stubs.Set(config, 'TempestConfigPrivate',
-                       fake_config.FakePrivate)
-
-    def _test_version(self, cfg_min, cfg_max,
-                      expected_pass_tests,
-                      expected_skip_tests):
-        cfg.CONF.set_default('min_microversion',
-                             cfg_min, group='compute-feature-enabled')
-        cfg.CONF.set_default('max_microversion',
-                             cfg_max, group='compute-feature-enabled')
-        try:
-            for test_class in expected_pass_tests:
-                test_class.skip_checks()
-            for test_class in expected_skip_tests:
-                self.assertRaises(testtools.TestCase.skipException,
-                                  test_class.skip_checks)
-        except testtools.TestCase.skipException as e:
-            raise testtools.TestCase.failureException(e.message)
-
-    def test_config_version_none_none(self):
-        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2]
-        expected_skip_tests = [VersionTest2_3ToLatest, VersionTest2_5To2_10,
-                               VersionTest2_10To2_10]
-        self._test_version(None, None,
-                           expected_pass_tests,
-                           expected_skip_tests)
-
-    def test_config_version_none_23(self):
-        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
-                               VersionTest2_3ToLatest]
-        expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
-        self._test_version(None, '2.3',
-                           expected_pass_tests,
-                           expected_skip_tests)
-
-    def test_config_version_22_latest(self):
-        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
-                               VersionTest2_3ToLatest, VersionTest2_5To2_10,
-                               VersionTest2_10To2_10]
-        expected_skip_tests = []
-        self._test_version('2.2', 'latest',
-                           expected_pass_tests,
-                           expected_skip_tests)
-
-    def test_config_version_22_23(self):
-        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
-                               VersionTest2_3ToLatest]
-        expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
-        self._test_version('2.2', '2.3',
-                           expected_pass_tests,
-                           expected_skip_tests)
-
-    def test_config_version_210_210(self):
-        expected_pass_tests = [VersionTestNoneTolatest,
-                               VersionTest2_3ToLatest,
-                               VersionTest2_5To2_10,
-                               VersionTest2_10To2_10]
-        expected_skip_tests = [VersionTestNoneTo2_2]
-        self._test_version('2.10', '2.10',
-                           expected_pass_tests,
-                           expected_skip_tests)
-
-    def test_config_version_none_latest(self):
-        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
-                               VersionTest2_3ToLatest, VersionTest2_5To2_10,
-                               VersionTest2_10To2_10]
-        expected_skip_tests = []
-        self._test_version(None, 'latest',
-                           expected_pass_tests,
-                           expected_skip_tests)
-
-    def test_config_version_latest_latest(self):
-        expected_pass_tests = [VersionTestNoneTolatest, VersionTest2_3ToLatest]
-        expected_skip_tests = [VersionTestNoneTo2_2, VersionTest2_5To2_10,
-                               VersionTest2_10To2_10]
-        self._test_version('latest', 'latest',
-                           expected_pass_tests,
-                           expected_skip_tests)
-
-    def test_config_invalid_version(self):
-        cfg.CONF.set_default('min_microversion',
-                             '2.5', group='compute-feature-enabled')
-        cfg.CONF.set_default('max_microversion',
-                             '2.1', group='compute-feature-enabled')
-        self.assertRaises(exceptions.InvalidConfiguration,
-                          VersionTestNoneTolatest.skip_checks)
-
-    def test_config_version_invalid_test_version(self):
-        cfg.CONF.set_default('min_microversion',
-                             None, group='compute-feature-enabled')
-        cfg.CONF.set_default('max_microversion',
-                             '2.13', group='compute-feature-enabled')
-        self.assertRaises(exceptions.InvalidConfiguration,
-                          InvalidVersionTest.skip_checks)
 
 
 class TestVersionSkipLogic(base.TestCase):
@@ -186,11 +51,11 @@
         self._test_version('2.8', '2.9', '2.3', '2.7', expected_skip=True)
 
     def test_version_min_greater_than_max(self):
-        self.assertRaises(exceptions.InvalidConfiguration,
+        self.assertRaises(exceptions.InvalidAPIVersionRange,
                           self._test_version, '2.8', '2.7', '2.3', '2.7')
 
     def test_cfg_version_min_greater_than_max(self):
-        self.assertRaises(exceptions.InvalidConfiguration,
+        self.assertRaises(exceptions.InvalidAPIVersionRange,
                           self._test_version, '2.2', '2.7', '2.9', '2.7')
 
 
@@ -219,3 +84,31 @@
 
     def test_both_min_version_equal(self):
         self._test_request_version('2.3', '2.3', expected_version='2.3')
+
+
+class TestMicroversionHeaderMatches(base.TestCase):
+
+    def test_header_matches(self):
+        microversion_header_name = 'x-openstack-xyz-api-version'
+        request_microversion = '2.1'
+        test_respose = {microversion_header_name: request_microversion}
+        api_version_utils.assert_version_header_matches_request(
+            microversion_header_name, request_microversion, test_respose)
+
+    def test_header_does_not_match(self):
+        microversion_header_name = 'x-openstack-xyz-api-version'
+        request_microversion = '2.1'
+        test_respose = {microversion_header_name: '2.2'}
+        self.assertRaises(
+            exceptions.InvalidHTTPResponseHeader,
+            api_version_utils.assert_version_header_matches_request,
+            microversion_header_name, request_microversion, test_respose)
+
+    def test_header_not_present(self):
+        microversion_header_name = 'x-openstack-xyz-api-version'
+        request_microversion = '2.1'
+        test_respose = {}
+        self.assertRaises(
+            exceptions.InvalidHTTPResponseHeader,
+            api_version_utils.assert_version_header_matches_request,
+            microversion_header_name, request_microversion, test_respose)
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index 5cb204f..7a21d96 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -322,9 +322,9 @@
         self._mock_router_create('1234', 'fake_router')
         router_interface_mock = self.patch(
             'tempest.services.network.json.network_client.NetworkClient.'
-            'add_router_interface_with_subnet_id')
+            'add_router_interface')
         primary_creds = creds.get_primary_creds()
-        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.assert_called_once_with('1234', subnet_id='1234')
         network = primary_creds.network
         subnet = primary_creds.subnet
         router = primary_creds.router
@@ -354,9 +354,9 @@
         self._mock_router_create('1234', 'fake_router')
         router_interface_mock = self.patch(
             'tempest.services.network.json.network_client.NetworkClient.'
-            'add_router_interface_with_subnet_id')
+            'add_router_interface')
         creds.get_primary_creds()
-        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.assert_called_once_with('1234', subnet_id='1234')
         router_interface_mock.reset_mock()
         # Create alternate tenant and network
         self._mock_user_create('12345', 'fake_alt_user')
@@ -365,7 +365,8 @@
         self._mock_subnet_create(creds, '12345', 'fake_alt_subnet')
         self._mock_router_create('12345', 'fake_alt_router')
         creds.get_alt_creds()
-        router_interface_mock.called_once_with('12345', '12345')
+        router_interface_mock.assert_called_once_with('12345',
+                                                      subnet_id='12345')
         router_interface_mock.reset_mock()
         # Create admin tenant and networks
         self._mock_user_create('123456', 'fake_admin_user')
@@ -390,7 +391,7 @@
         router_mock = router.start()
         remove_router_interface_mock = self.patch(
             'tempest.services.network.json.network_client.NetworkClient.'
-            'remove_router_interface_with_subnet_id')
+            'remove_router_interface')
         return_values = ({'status': 200}, {'ports': []})
         port_list_mock = mock.patch.object(creds.ports_admin_client,
                                            'list_ports',
@@ -405,7 +406,7 @@
 
         return_values = (fake_http.fake_httplib({}, status=204), {})
         remove_secgroup_mock = self.patch(
-            'tempest.services.network.json.security_groups_client.'
+            'tempest_lib.services.network.security_groups_client.'
             'SecurityGroupsClient.delete', return_value=return_values)
         creds.clear_creds()
         # Verify default security group delete
@@ -419,11 +420,11 @@
         # Verify remove router interface calls
         calls = remove_router_interface_mock.mock_calls
         self.assertEqual(len(calls), 3)
-        args = map(lambda x: x[1], calls)
+        args = map(lambda x: (x[1][0], x[2]), calls)
         args = list(args)
-        self.assertIn(('1234', '1234'), args)
-        self.assertIn(('12345', '12345'), args)
-        self.assertIn(('123456', '123456'), args)
+        self.assertIn(('1234', {'subnet_id': '1234'}), args)
+        self.assertIn(('12345', {'subnet_id': '12345'}), args)
+        self.assertIn(('123456', {'subnet_id': '123456'}), args)
         # Verify network delete calls
         calls = net_mock.mock_calls
         self.assertEqual(len(calls), 3)
@@ -461,9 +462,9 @@
         self._mock_router_create('1234', 'fake_alt_router')
         router_interface_mock = self.patch(
             'tempest.services.network.json.network_client.NetworkClient.'
-            'add_router_interface_with_subnet_id')
+            'add_router_interface')
         alt_creds = creds.get_alt_creds()
-        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.assert_called_once_with('1234', subnet_id='1234')
         network = alt_creds.network
         subnet = alt_creds.subnet
         router = alt_creds.router
@@ -485,10 +486,10 @@
         self._mock_router_create('1234', 'fake_admin_router')
         router_interface_mock = self.patch(
             'tempest.services.network.json.network_client.NetworkClient.'
-            'add_router_interface_with_subnet_id')
+            'add_router_interface')
         self._mock_list_roles('123456', 'admin')
         admin_creds = creds.get_admin_creds()
-        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.assert_called_once_with('1234', subnet_id='1234')
         network = admin_creds.network
         subnet = admin_creds.subnet
         router = admin_creds.router
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index f248957..5a00a2b 100644
--- a/tempest/tests/common/test_service_clients.py
+++ b/tempest/tests/common/test_service_clients.py
@@ -31,7 +31,6 @@
 from tempest.services.identity.v3.json import services_client
 from tempest.services.image.v1.json import images_client
 from tempest.services.image.v2.json import images_client as images_v2_client
-from tempest.services.messaging.json import messaging_client
 from tempest.services.network.json import network_client
 from tempest.services.object_storage import account_client
 from tempest.services.object_storage import container_client
@@ -86,7 +85,6 @@
             data_processing_client.DataProcessingClient,
             db_flavor_client.DatabaseFlavorsClient,
             db_version_client.DatabaseVersionsClient,
-            messaging_client.MessagingClient,
             network_client.NetworkClient,
             account_client.AccountClient,
             container_client.ContainerClient,
diff --git a/tempest/tests/services/compute/test_base_compute_client.py b/tempest/tests/services/compute/test_base_compute_client.py
index 134fe39..7a55cdb 100644
--- a/tempest/tests/services/compute/test_base_compute_client.py
+++ b/tempest/tests/services/compute/test_base_compute_client.py
@@ -13,64 +13,48 @@
 #    under the License.
 
 import httplib2
-import mock
+from oslotest import mockpatch
 from tempest_lib.common import rest_client
 
 from tempest import exceptions
-from tempest.services.compute.json import base as base_compute_client
+from tempest.services.compute.json import base_compute_client
 from tempest.tests import fake_auth_provider
 from tempest.tests.services.compute import base
 
 
-class TestClientWithoutMicroversionHeader(base.BaseComputeServiceTest):
+class TestMicroversionHeaderCheck(base.BaseComputeServiceTest):
 
     def setUp(self):
-        super(TestClientWithoutMicroversionHeader, self).setUp()
+        super(TestMicroversionHeaderCheck, self).setUp()
         fake_auth = fake_auth_provider.FakeAuthProvider()
         self.client = base_compute_client.BaseComputeClient(
             fake_auth, 'compute', 'regionOne')
+        self.client.set_api_microversion('2.2')
 
-    def test_no_microverion_header(self):
-        header = self.client.get_headers()
-        self.assertNotIn('X-OpenStack-Nova-API-Version', header)
+    def _check_microverion_header_in_response(self, fake_response):
+        def request(*args, **kwargs):
+            return (httplib2.Response(fake_response), {})
 
-    def test_no_microverion_header_in_raw_request(self):
-        def raw_request(*args, **kwargs):
-            self.assertNotIn('X-OpenStack-Nova-API-Version', kwargs['headers'])
-            return (httplib2.Response({'status': 200}), {})
+        self.useFixture(mockpatch.PatchObject(
+            rest_client.RestClient,
+            'request',
+            side_effect=request))
 
-        with mock.patch.object(rest_client.RestClient,
-                               'raw_request') as mock_get:
-            mock_get.side_effect = raw_request
-            self.client.get('fake_url')
+    def test_correct_microverion_in_response(self):
+        fake_response = {self.client.api_microversion_header_name: '2.2'}
+        self._check_microverion_header_in_response(fake_response)
+        self.client.get('fake_url')
 
+    def test_incorrect_microverion_in_response(self):
+        fake_response = {self.client.api_microversion_header_name: '2.3'}
+        self._check_microverion_header_in_response(fake_response)
+        self.assertRaises(exceptions.InvalidHTTPResponseHeader,
+                          self.client.get, 'fake_url')
 
-class TestClientWithMicroversionHeader(base.BaseComputeServiceTest):
-
-    def setUp(self):
-        super(TestClientWithMicroversionHeader, self).setUp()
-        fake_auth = fake_auth_provider.FakeAuthProvider()
-        self.client = base_compute_client.BaseComputeClient(
-            fake_auth, 'compute', 'regionOne')
-        self.client.api_microversion = '2.2'
-
-    def test_microverion_header(self):
-        header = self.client.get_headers()
-        self.assertIn('X-OpenStack-Nova-API-Version', header)
-        self.assertEqual(self.client.api_microversion,
-                         header['X-OpenStack-Nova-API-Version'])
-
-    def test_microverion_header_in_raw_request(self):
-        def raw_request(*args, **kwargs):
-            self.assertIn('X-OpenStack-Nova-API-Version', kwargs['headers'])
-            self.assertEqual(self.client.api_microversion,
-                             kwargs['headers']['X-OpenStack-Nova-API-Version'])
-            return (httplib2.Response({'status': 200}), {})
-
-        with mock.patch.object(rest_client.RestClient,
-                               'raw_request') as mock_get:
-            mock_get.side_effect = raw_request
-            self.client.get('fake_url')
+    def test_no_microverion_header_in_response(self):
+        self._check_microverion_header_in_response({})
+        self.assertRaises(exceptions.InvalidHTTPResponseHeader,
+                          self.client.get, 'fake_url')
 
 
 class DummyServiceClient1(base_compute_client.BaseComputeClient):
diff --git a/tempest/tests/services/test_base_microversion_client.py b/tempest/tests/services/test_base_microversion_client.py
new file mode 100644
index 0000000..11b8170
--- /dev/null
+++ b/tempest/tests/services/test_base_microversion_client.py
@@ -0,0 +1,75 @@
+# Copyright 2016 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import httplib2
+import mock
+from tempest_lib.common import rest_client
+
+from tempest.services import base_microversion_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestClientWithoutMicroversionHeader(base.BaseComputeServiceTest):
+
+    def setUp(self):
+        super(TestClientWithoutMicroversionHeader, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = base_microversion_client.BaseMicroversionClient(
+            fake_auth, 'compute', 'regionOne', 'X-OpenStack-Nova-API-Version')
+
+    def test_no_microverion_header(self):
+        header = self.client.get_headers()
+        self.assertNotIn(self.client.api_microversion_header_name, header)
+
+    def test_no_microverion_header_in_raw_request(self):
+        def raw_request(*args, **kwargs):
+            self.assertNotIn(self.client.api_microversion_header_name,
+                             kwargs['headers'])
+            return (httplib2.Response({'status': 200}), {})
+
+        with mock.patch.object(rest_client.RestClient,
+                               'raw_request') as mock_get:
+            mock_get.side_effect = raw_request
+            self.client.get('fake_url')
+
+
+class TestClientWithMicroversionHeader(base.BaseComputeServiceTest):
+
+    def setUp(self):
+        super(TestClientWithMicroversionHeader, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = base_microversion_client.BaseMicroversionClient(
+            fake_auth, 'compute', 'regionOne', 'X-OpenStack-Nova-API-Version')
+        self.client.set_api_microversion('2.2')
+
+    def test_microverion_header(self):
+        header = self.client.get_headers()
+        self.assertIn(self.client.api_microversion_header_name, header)
+        self.assertEqual(self.client.api_microversion,
+                         header[self.client.api_microversion_header_name])
+
+    def test_microverion_header_in_raw_request(self):
+        def raw_request(*args, **kwargs):
+            self.assertIn(self.client.api_microversion_header_name,
+                          kwargs['headers'])
+            self.assertEqual(
+                self.client.api_microversion,
+                kwargs['headers'][self.client.api_microversion_header_name])
+            return (httplib2.Response({'status': 200}), {})
+
+        with mock.patch.object(rest_client.RestClient,
+                               'raw_request') as mock_get:
+            mock_get.side_effect = raw_request
+            self.client.get('fake_url')
diff --git a/tempest/tests/test_microversions.py b/tempest/tests/test_microversions.py
new file mode 100644
index 0000000..6738641
--- /dev/null
+++ b/tempest/tests/test_microversions.py
@@ -0,0 +1,153 @@
+# Copyright 2015 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from oslo_config import cfg
+import testtools
+
+from tempest.api.compute import base as compute_base
+from tempest import config
+from tempest import exceptions
+from tempest.tests import base
+from tempest.tests import fake_config
+
+
+class VersionTestNoneTolatest(compute_base.BaseV2ComputeTest):
+    min_microversion = None
+    max_microversion = 'latest'
+
+
+class VersionTestNoneTo2_2(compute_base.BaseV2ComputeTest):
+    min_microversion = None
+    max_microversion = '2.2'
+
+
+class VersionTest2_3ToLatest(compute_base.BaseV2ComputeTest):
+    min_microversion = '2.3'
+    max_microversion = 'latest'
+
+
+class VersionTest2_5To2_10(compute_base.BaseV2ComputeTest):
+    min_microversion = '2.5'
+    max_microversion = '2.10'
+
+
+class VersionTest2_10To2_10(compute_base.BaseV2ComputeTest):
+    min_microversion = '2.10'
+    max_microversion = '2.10'
+
+
+class InvalidVersionTest(compute_base.BaseV2ComputeTest):
+    min_microversion = '2.11'
+    max_microversion = '2.1'
+
+
+class TestMicroversionsTestsClass(base.TestCase):
+
+    def setUp(self):
+        super(TestMicroversionsTestsClass, self).setUp()
+        self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate',
+                       fake_config.FakePrivate)
+
+    def _test_version(self, cfg_min, cfg_max,
+                      expected_pass_tests,
+                      expected_skip_tests):
+        cfg.CONF.set_default('min_microversion',
+                             cfg_min, group='compute-feature-enabled')
+        cfg.CONF.set_default('max_microversion',
+                             cfg_max, group='compute-feature-enabled')
+        try:
+            for test_class in expected_pass_tests:
+                test_class.skip_checks()
+            for test_class in expected_skip_tests:
+                self.assertRaises(testtools.TestCase.skipException,
+                                  test_class.skip_checks)
+        except testtools.TestCase.skipException as e:
+            raise testtools.TestCase.failureException(e.message)
+
+    def test_config_version_none_none(self):
+        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2]
+        expected_skip_tests = [VersionTest2_3ToLatest, VersionTest2_5To2_10,
+                               VersionTest2_10To2_10]
+        self._test_version(None, None,
+                           expected_pass_tests,
+                           expected_skip_tests)
+
+    def test_config_version_none_23(self):
+        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
+                               VersionTest2_3ToLatest]
+        expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
+        self._test_version(None, '2.3',
+                           expected_pass_tests,
+                           expected_skip_tests)
+
+    def test_config_version_22_latest(self):
+        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
+                               VersionTest2_3ToLatest, VersionTest2_5To2_10,
+                               VersionTest2_10To2_10]
+        expected_skip_tests = []
+        self._test_version('2.2', 'latest',
+                           expected_pass_tests,
+                           expected_skip_tests)
+
+    def test_config_version_22_23(self):
+        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
+                               VersionTest2_3ToLatest]
+        expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
+        self._test_version('2.2', '2.3',
+                           expected_pass_tests,
+                           expected_skip_tests)
+
+    def test_config_version_210_210(self):
+        expected_pass_tests = [VersionTestNoneTolatest,
+                               VersionTest2_3ToLatest,
+                               VersionTest2_5To2_10,
+                               VersionTest2_10To2_10]
+        expected_skip_tests = [VersionTestNoneTo2_2]
+        self._test_version('2.10', '2.10',
+                           expected_pass_tests,
+                           expected_skip_tests)
+
+    def test_config_version_none_latest(self):
+        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
+                               VersionTest2_3ToLatest, VersionTest2_5To2_10,
+                               VersionTest2_10To2_10]
+        expected_skip_tests = []
+        self._test_version(None, 'latest',
+                           expected_pass_tests,
+                           expected_skip_tests)
+
+    def test_config_version_latest_latest(self):
+        expected_pass_tests = [VersionTestNoneTolatest, VersionTest2_3ToLatest]
+        expected_skip_tests = [VersionTestNoneTo2_2, VersionTest2_5To2_10,
+                               VersionTest2_10To2_10]
+        self._test_version('latest', 'latest',
+                           expected_pass_tests,
+                           expected_skip_tests)
+
+    def test_config_invalid_version(self):
+        cfg.CONF.set_default('min_microversion',
+                             '2.5', group='compute-feature-enabled')
+        cfg.CONF.set_default('max_microversion',
+                             '2.1', group='compute-feature-enabled')
+        self.assertRaises(exceptions.InvalidAPIVersionRange,
+                          VersionTestNoneTolatest.skip_checks)
+
+    def test_config_version_invalid_test_version(self):
+        cfg.CONF.set_default('min_microversion',
+                             None, group='compute-feature-enabled')
+        cfg.CONF.set_default('max_microversion',
+                             '2.13', group='compute-feature-enabled')
+        self.assertRaises(exceptions.InvalidAPIVersionRange,
+                          InvalidVersionTest.skip_checks)
diff --git a/test-requirements.txt b/test-requirements.txt
index 5b01ea9..eb43f31 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,10 +3,10 @@
 # process, which may cause wedges in the gate later.
 hacking<0.11,>=0.10.0
 # needed for doc build
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
-python-subunit>=0.0.18
+sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+python-subunit>=0.0.18 # Apache-2.0/BSD
 oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
-mox>=0.5.3
-mock>=1.2
-coverage>=3.6
+mox>=0.5.3 # Apache-2.0
+mock>=1.2 # BSD
+coverage>=3.6 # Apache-2.0
 oslotest>=1.10.0 # Apache-2.0
diff --git a/tools/check_logs.py b/tools/check_logs.py
index c8d3a1a..fa7129d 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -19,7 +19,7 @@
 import gzip
 import os
 import re
-import StringIO
+import six
 import sys
 import urllib2
 
@@ -71,7 +71,7 @@
         req = urllib2.Request(url)
         req.add_header('Accept-Encoding', 'gzip')
         page = urllib2.urlopen(req)
-        buf = StringIO.StringIO(page.read())
+        buf = six.StringIO(page.read())
         f = gzip.GzipFile(fileobj=buf)
         if scan_content(name, f.read().splitlines(), regexp, whitelist):
             logs_with_errors.append(name)
@@ -105,7 +105,7 @@
 def main(opts):
     if opts.directory and opts.url or not (opts.directory or opts.url):
         print("Must provide exactly one of -d or -u")
-        exit(1)
+        return 1
     print("Checking logs...")
     WHITELIST_FILE = os.path.join(
         os.path.abspath(os.path.dirname(os.path.dirname(__file__))),
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index 4862d01..49a42fe 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -18,7 +18,7 @@
 import gzip
 import pprint
 import re
-import StringIO
+import six
 import sys
 import urllib2
 
@@ -68,7 +68,7 @@
     req = urllib2.Request(url)
     req.add_header('Accept-Encoding', 'gzip')
     page = urllib2.urlopen(req)
-    buf = StringIO.StringIO(page.read())
+    buf = six.StringIO(page.read())
     f = gzip.GzipFile(fileobj=buf)
     content = f.read()
 
diff --git a/tox.ini b/tox.ini
index fedd04c..95f2cf1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
 [tox]
 envlist = pep8,py34,py27
-minversion = 1.6
+minversion = 2.3.1
 skipsdist = True
 
 [tempestenv]
@@ -34,7 +34,7 @@
 sitepackages = {[tempestenv]sitepackages}
 # 'all' includes slow tests
 setenv = {[tempestenv]setenv}
-         OS_TEST_TIMEOUT=1200
+         OS_TEST_TIMEOUT={env:OS_TEST_TIMEOUT:1200}
 deps = {[tempestenv]deps}
 commands =
   find . -type f -name "*.pyc" -delete
@@ -44,7 +44,7 @@
 sitepackages = True
 # 'all' includes slow tests
 setenv = {[tempestenv]setenv}
-         OS_TEST_TIMEOUT=1200
+         OS_TEST_TIMEOUT={env:OS_TEST_TIMEOUT:1200}
 deps = {[tempestenv]deps}
 commands =
   find . -type f -name "*.pyc" -delete