Merge "Migrate tempest-lib code into new lib dir"
diff --git a/tempest/api/compute/api_microversion_fixture.py b/tempest/api/compute/api_microversion_fixture.py
new file mode 100644
index 0000000..bf4de3e
--- /dev/null
+++ b/tempest/api/compute/api_microversion_fixture.py
@@ -0,0 +1,31 @@
+# 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 fixtures
+
+from tempest.services.compute.json import base_compute_client
+
+
+class APIMicroversionFixture(fixtures.Fixture):
+
+    def __init__(self, compute_microversion):
+        self.compute_microversion = compute_microversion
+
+    def _setUp(self):
+        super(APIMicroversionFixture, self)._setUp()
+        base_compute_client.COMPUTE_MICROVERSION = self.compute_microversion
+        self.addCleanup(self._reset_compute_microversion)
+
+    def _reset_compute_microversion(self):
+        base_compute_client.COMPUTE_MICROVERSION = None
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 0856983..96f32aa 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -18,6 +18,7 @@
 from oslo_log import log as logging
 from tempest_lib import exceptions as lib_exc
 
+from tempest.api.compute import api_microversion_fixture
 from tempest.common import api_version_utils
 from tempest.common import compute
 from tempest.common.utils import data_utils
@@ -56,13 +57,6 @@
     @classmethod
     def setup_credentials(cls):
         cls.set_network_resources()
-        cls.request_microversion = (
-            api_version_utils.select_request_microversion(
-                cls.min_microversion,
-                CONF.compute_feature_enabled.min_microversion))
-        if cls.request_microversion:
-            cls.services_microversion = {
-                CONF.compute.catalog_type: cls.request_microversion}
         super(BaseV2ComputeTest, cls).setup_credentials()
 
     @classmethod
@@ -108,6 +102,10 @@
     @classmethod
     def resource_setup(cls):
         super(BaseV2ComputeTest, cls).resource_setup()
+        cls.request_microversion = (
+            api_version_utils.select_request_microversion(
+                cls.min_microversion,
+                CONF.compute_feature_enabled.min_microversion))
         cls.build_interval = CONF.compute.build_interval
         cls.build_timeout = CONF.compute.build_timeout
         cls.image_ref = CONF.compute.image_ref
@@ -371,6 +369,11 @@
         else:
             raise exceptions.InvalidConfiguration()
 
+    def setUp(self):
+        super(BaseV2ComputeTest, self).setUp()
+        self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+            self.request_microversion))
+
 
 class BaseV2ComputeAdminTest(BaseV2ComputeTest):
     """Base test case class for Compute Admin API tests."""
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 3dc3cb6..b2bef6e 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -32,14 +32,14 @@
     def _delete_domain(self, domain_id):
         # It is necessary to disable the domain before deleting,
         # or else it would result in unauthorized error
-        self.client.update_domain(domain_id, enabled=False)
-        self.client.delete_domain(domain_id)
+        self.domains_client.update_domain(domain_id, enabled=False)
+        self.domains_client.delete_domain(domain_id)
 
     @test.idempotent_id('d6110661-6a71-49a7-a453-b5e26640ff6d')
     def test_default_project_id(self):
         # create a domain
         dom_name = data_utils.rand_name('dom')
-        domain_body = self.client.create_domain(dom_name)['domain']
+        domain_body = self.domains_client.create_domain(dom_name)['domain']
         dom_id = domain_body['id']
         self.addCleanup(self._delete_domain, dom_id)
 
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 1729dc9..27ff15d 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -26,11 +26,11 @@
     def _delete_domain(self, domain_id):
         # It is necessary to disable the domain before deleting,
         # or else it would result in unauthorized error
-        self.client.update_domain(domain_id, enabled=False)
-        self.client.delete_domain(domain_id)
+        self.domains_client.update_domain(domain_id, enabled=False)
+        self.domains_client.delete_domain(domain_id)
         # Asserting that the domain is not found in the list
         # after deletion
-        body = self.client.list_domains()['domains']
+        body = self.domains_client.list_domains()['domains']
         domains_list = [d['id'] for d in body]
         self.assertNotIn(domain_id, domains_list)
 
@@ -40,14 +40,14 @@
         domain_ids = list()
         fetched_ids = list()
         for _ in range(3):
-            domain = self.client.create_domain(
+            domain = self.domains_client.create_domain(
                 data_utils.rand_name('domain'),
                 description=data_utils.rand_name('domain-desc'))['domain']
             # Delete the domain at the end of this method
             self.addCleanup(self._delete_domain, domain['id'])
             domain_ids.append(domain['id'])
         # List and Verify Domains
-        body = self.client.list_domains()['domains']
+        body = self.domains_client.list_domains()['domains']
         for d in body:
             fetched_ids.append(d['id'])
         missing_doms = [d for d in domain_ids if d not in fetched_ids]
@@ -58,7 +58,7 @@
     def test_create_update_delete_domain(self):
         d_name = data_utils.rand_name('domain')
         d_desc = data_utils.rand_name('domain-desc')
-        domain = self.client.create_domain(
+        domain = self.domains_client.create_domain(
             d_name, description=d_desc)['domain']
         self.addCleanup(self._delete_domain, domain['id'])
         self.assertIn('id', domain)
@@ -73,7 +73,7 @@
         new_desc = data_utils.rand_name('new-desc')
         new_name = data_utils.rand_name('new-name')
 
-        updated_domain = self.client.update_domain(
+        updated_domain = self.domains_client.update_domain(
             domain['id'], name=new_name, description=new_desc)['domain']
         self.assertIn('id', updated_domain)
         self.assertIn('description', updated_domain)
@@ -85,7 +85,8 @@
         self.assertEqual(new_desc, updated_domain['description'])
         self.assertEqual(True, updated_domain['enabled'])
 
-        fetched_domain = self.client.show_domain(domain['id'])['domain']
+        fetched_domain = self.domains_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'])
@@ -95,9 +96,9 @@
         # Create domain with enabled status as false
         d_name = data_utils.rand_name('domain')
         d_desc = data_utils.rand_name('domain-desc')
-        domain = self.client.create_domain(
+        domain = self.domains_client.create_domain(
             d_name, description=d_desc, enabled=False)['domain']
-        self.addCleanup(self.client.delete_domain, domain['id'])
+        self.addCleanup(self.domains_client.delete_domain, domain['id'])
         self.assertEqual(d_name, domain['name'])
         self.assertFalse(domain['enabled'])
         self.assertEqual(d_desc, domain['description'])
@@ -106,7 +107,7 @@
     def test_create_domain_without_description(self):
         # Create domain only with name
         d_name = data_utils.rand_name('domain')
-        domain = self.client.create_domain(d_name)['domain']
+        domain = self.domains_client.create_domain(d_name)['domain']
         self.addCleanup(self._delete_domain, domain['id'])
         self.assertIn('id', domain)
         expected_data = {'name': d_name, 'enabled': True}
@@ -124,6 +125,6 @@
     @test.attr(type='smoke')
     @test.idempotent_id('17a5de24-e6a0-4e4a-a9ee-d85b6e5612b5')
     def test_default_domain_exists(self):
-        domain = self.client.show_domain(self.domain_id)['domain']
+        domain = self.domains_client.show_domain(self.domain_id)['domain']
 
         self.assertTrue(domain['enabled'])
diff --git a/tempest/api/identity/admin/v3/test_domains_negative.py b/tempest/api/identity/admin/v3/test_domains_negative.py
index 9eb3149..253aeca 100644
--- a/tempest/api/identity/admin/v3/test_domains_negative.py
+++ b/tempest/api/identity/admin/v3/test_domains_negative.py
@@ -28,45 +28,46 @@
     def test_delete_active_domain(self):
         d_name = data_utils.rand_name('domain')
         d_desc = data_utils.rand_name('domain-desc')
-        domain = self.client.create_domain(d_name,
-                                           description=d_desc)['domain']
+        domain = self.domains_client.create_domain(
+            d_name,
+            description=d_desc)['domain']
         domain_id = domain['id']
 
         self.addCleanup(self.delete_domain, domain_id)
 
         # domain need to be disabled before deleting
-        self.assertRaises(lib_exc.Forbidden, self.client.delete_domain,
+        self.assertRaises(lib_exc.Forbidden, self.domains_client.delete_domain,
                           domain_id)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('9018461d-7d24-408d-b3fe-ae37e8cd5c9e')
     def test_create_domain_with_empty_name(self):
         # Domain name should not be empty
-        self.assertRaises(lib_exc.BadRequest, self.client.create_domain,
-                          name='')
+        self.assertRaises(lib_exc.BadRequest,
+                          self.domains_client.create_domain, name='')
 
     @test.attr(type=['negative'])
     @test.idempotent_id('37b1bbf2-d664-4785-9a11-333438586eae')
     def test_create_domain_with_name_length_over_64(self):
         # Domain name length should not ne greater than 64 characters
         d_name = 'a' * 65
-        self.assertRaises(lib_exc.BadRequest, self.client.create_domain,
-                          d_name)
+        self.assertRaises(lib_exc.BadRequest,
+                          self.domains_client.create_domain, d_name)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('43781c07-764f-4cf2-a405-953c1916f605')
     def test_delete_non_existent_domain(self):
         # Attempt to delete a non existent domain should fail
-        self.assertRaises(lib_exc.NotFound, self.client.delete_domain,
+        self.assertRaises(lib_exc.NotFound, self.domains_client.delete_domain,
                           data_utils.rand_uuid_hex())
 
     @test.attr(type=['negative'])
     @test.idempotent_id('e6f9e4a2-4f36-4be8-bdbc-4e199ae29427')
     def test_domain_create_duplicate(self):
         domain_name = data_utils.rand_name('domain-dup')
-        domain = self.client.create_domain(domain_name)['domain']
+        domain = self.domains_client.create_domain(domain_name)['domain']
         domain_id = domain['id']
         self.addCleanup(self.delete_domain, domain_id)
         # Domain name should be unique
         self.assertRaises(
-            lib_exc.Conflict, self.client.create_domain, domain_name)
+            lib_exc.Conflict, self.domains_client.create_domain, domain_name)
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 468f169..a0a842c 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -32,7 +32,7 @@
         u_desc = '%s description' % u_name
         u_email = '%s@testmail.tm' % u_name
         cls.u_password = data_utils.rand_password()
-        cls.domain = cls.client.create_domain(
+        cls.domain = cls.domains_client.create_domain(
             data_utils.rand_name('domain'),
             description=data_utils.rand_name('domain-desc'))['domain']
         cls.project = cls.projects_client.create_project(
@@ -57,8 +57,8 @@
         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)
-        cls.client.delete_domain(cls.domain['id'])
+        cls.domains_client.update_domain(cls.domain['id'], enabled=False)
+        cls.domains_client.delete_domain(cls.domain['id'])
         super(RolesV3TestJSON, cls).resource_cleanup()
 
     def _list_assertions(self, body, fetched_role_ids, role_id):
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 180e695..da1f155 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -97,7 +97,7 @@
             tenant_name=self.trustor_project_name,
             project_domain_id='default')
         os = clients.Manager(credentials=creds)
-        self.trustor_client = os.identity_v3_client
+        self.trustor_client = os.trusts_client
 
     def cleanup_user_and_roles(self):
         if self.trustor_user_id:
@@ -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.list_trusts()['trusts']
+        trusts_get = self.trusts_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/base.py b/tempest/api/identity/base.py
index 1025de7..b209a82 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -146,7 +146,9 @@
     def setup_clients(cls):
         super(BaseIdentityV3AdminTest, cls).setup_clients()
         cls.client = cls.os_adm.identity_v3_client
+        cls.domains_client = cls.os_adm.domains_client
         cls.users_client = cls.os_adm.users_v3_client
+        cls.trusts_client = cls.os_adm.trusts_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
@@ -160,7 +162,7 @@
     def resource_setup(cls):
         super(BaseIdentityV3AdminTest, cls).resource_setup()
         cls.data = DataGeneratorV3(cls.client, cls.projects_client,
-                                   cls.users_client)
+                                   cls.users_client, None, cls.domains_client)
 
     @classmethod
     def resource_cleanup(cls):
@@ -182,18 +184,19 @@
     def delete_domain(self, domain_id):
         # NOTE(mpavlase) It is necessary to disable the domain before deleting
         # otherwise it raises Forbidden exception
-        self.client.update_domain(domain_id, enabled=False)
-        self.client.delete_domain(domain_id)
+        self.domains_client.update_domain(domain_id, enabled=False)
+        self.domains_client.delete_domain(domain_id)
 
 
 class BaseDataGenerator(object):
 
     def __init__(self, client, projects_client,
-                 users_client, roles_client=None):
+                 users_client, roles_client=None, domains_client=None):
         self.client = client
         self.projects_client = projects_client
         self.users_client = users_client
         self.roles_client = roles_client or client
+        self.domains_client = domains_client
 
         self.user_password = None
         self.user = None
@@ -242,8 +245,9 @@
         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)
+            self._try_wrapper(self.domains_client.update_domain, domain,
+                              enabled=False)
+            self._try_wrapper(self.domains_client.delete_domain, domain)
 
 
 class DataGeneratorV2(BaseDataGenerator):
@@ -277,7 +281,7 @@
 
     def setup_test_domain(self):
         """Set up a test domain."""
-        self.domain = self.client.create_domain(
+        self.domain = self.domains_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/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index dbb0d14..3e261db 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -66,8 +66,8 @@
         body = self.ports_client.list_ports()
         ports = body['ports']
         for port in ports:
-            if (port['device_owner'].startswith('network:router_interface')
-                and port['device_id'] in [r['id'] for r in self.routers]):
+            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(port['device_id'],
                                                     port_id=port['id'])
             else:
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 09e863e..001bc08 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -30,6 +30,8 @@
 
     @classmethod
     def skip_checks(cls):
+        msg = "Skipped until Bug: 1547261 is resolved."
+        raise cls.skipException(msg)
         super(NeutronResourcesTestJSON, cls).skip_checks()
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron support is required")
diff --git a/tempest/api/volume/admin/test_volume_services.py b/tempest/api/volume/admin/test_volume_services.py
index 2b7ee45..fb42633 100644
--- a/tempest/api/volume/admin/test_volume_services.py
+++ b/tempest/api/volume/admin/test_volume_services.py
@@ -13,10 +13,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest_lib import decorators
+
 from tempest.api.volume import base
+from tempest import config
 from tempest import test
 
 
+CONF = config.CONF
+
+
 class VolumesServicesV2TestJSON(base.BaseVolumeAdminTest):
     """Tests Volume Services API.
 
@@ -45,10 +51,16 @@
         for service in services:
             self.assertEqual(self.binary_name, service['binary'])
 
+    @decorators.skip_because(bug="1530144")
     @test.idempotent_id('178710e4-7596-4e08-9333-745cb8bc4f8d')
     def test_get_service_by_host_name(self):
+        def get_host(host):
+            if CONF.volume_feature_enabled.volume_services:
+                host = host.split('@')[0]
+            return host
+
         services_on_host = [service for service in self.services if
-                            service['host'] == self.host_name]
+                            get_host(service['host']) == self.host_name]
 
         services = (self.admin_volume_services_client.list_services(
             host=self.host_name)['services'])
diff --git a/tempest/clients.py b/tempest/clients.py
index 2a8a4ae..b398493 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -117,6 +117,7 @@
     UsersClient
 from tempest.services.identity.v3.json.credentials_client import \
     CredentialsClient as CredentialsV3Client
+from tempest.services.identity.v3.json.domains_client import DomainsClient
 from tempest.services.identity.v3.json.endpoints_client import \
     EndPointClient as EndPointV3Client
 from tempest.services.identity.v3.json.groups_client import \
@@ -129,6 +130,7 @@
     RegionsClient as RegionsV3Client
 from tempest.services.identity.v3.json.services_client import \
     ServicesClient as IdentityServicesV3Client
+from tempest.services.identity.v3.json.trusts_client import TrustsClient
 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
@@ -202,30 +204,14 @@
     }
     default_params_with_timeout_values.update(default_params)
 
-    def __init__(self, credentials, service=None, api_microversions=None):
+    def __init__(self, credentials, service=None):
         """Initialization of Manager class.
 
         Setup all services clients and make them available for tests cases.
         :param credentials: type Credentials or TestResources
         :param service: Service name
-        :param api_microversions: This is dict of services catalog type
-               and their microversion which will be set on respective
-               services clients.
-               {<service catalog type>: request_microversion}
-               Example :
-                {'compute': request_microversion}
-                    - request_microversion will be set on all compute
-                      service clients.
-                OR
-                {'compute': request_microversion,
-                 'volume': request_microversion}
-                    - request_microversion of compute will be set on all
-                      compute service clients.
-                    - request_microversion of volume will be set on all
-                      volume service clients.
         """
         super(Manager, self).__init__(credentials=credentials)
-        self.api_microversions = api_microversions or {}
         self._set_compute_clients()
         self._set_database_clients()
         self._set_identity_clients()
@@ -390,8 +376,6 @@
         self.negative_client = negative_rest_client.NegativeRestClient(
             self.auth_provider, service, **self.default_params)
 
-        self._set_api_microversions()
-
     def _set_compute_clients(self):
         params = {
             'service': CONF.compute.catalog_type,
@@ -527,8 +511,11 @@
         # Clients below use the endpoint type of Keystone API v3
         params_v3 = params.copy()
         params_v3['endpoint_type'] = CONF.identity.v3_endpoint_type
+        self.domains_client = DomainsClient(self.auth_provider,
+                                            **params_v3)
         self.identity_v3_client = IdentityV3Client(self.auth_provider,
                                                    **params_v3)
+        self.trusts_client = TrustsClient(self.auth_provider, **params_v3)
         self.users_v3_client = UsersV3Client(self.auth_provider, **params_v3)
         self.endpoints_client = EndPointV3Client(self.auth_provider,
                                                  **params_v3)
@@ -623,15 +610,3 @@
         self.account_client = AccountClient(self.auth_provider, **params)
         self.container_client = ContainerClient(self.auth_provider, **params)
         self.object_client = ObjectClient(self.auth_provider, **params)
-
-    def _set_api_microversions(self):
-        service_clients = [x for x in self.__dict__ if x.endswith('_client')]
-        for client in service_clients:
-            client_obj = getattr(self, client)
-            microversion = self.api_microversions.get(client_obj.service)
-            if microversion:
-                if hasattr(client_obj, 'set_api_microversion'):
-                    client_obj.set_api_microversion(microversion)
-                else:
-                    LOG.debug("Need to implement set_api_microversion on %s"
-                              % client)
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 5ec8008..0640a4e 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -940,7 +940,7 @@
 
     def __init__(self, manager, **kwargs):
         super(DomainService, self).__init__(kwargs)
-        self.client = manager.identity_v3_client
+        self.client = manager.domains_client
 
     def list(self):
         client = self.client
diff --git a/tempest/common/api_version_utils.py b/tempest/common/api_version_utils.py
index c3d977f..7c7e96a 100644
--- a/tempest/common/api_version_utils.py
+++ b/tempest/common/api_version_utils.py
@@ -18,6 +18,9 @@
 from tempest import exceptions
 
 
+LATEST_MICROVERSION = 'latest'
+
+
 class BaseMicroversionTest(object):
     """Mixin class for API microversion test class."""
 
@@ -27,7 +30,7 @@
     # for all microversions. We need to define microversion range
     # (min_microversion, max_microversion) on each test class if necessary.
     min_microversion = None
-    max_microversion = 'latest'
+    max_microversion = LATEST_MICROVERSION
 
 
 def check_skip_with_microversion(test_min_version, test_max_version,
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index 5aa794c..494bcee 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -130,13 +130,15 @@
 class V3CredsClient(CredsClient):
 
     def __init__(self, identity_client, projects_client, users_client,
-                 domain_name):
-        super(V3CredsClient, self).__init__(identity_client,
-                                            projects_client, users_client)
+                 domains_client, domain_name):
+        super(V3CredsClient, self).__init__(identity_client, projects_client,
+                                            users_client)
+        self.domains_client = domains_client
+
         try:
             # Domain names must be unique, in any case a list is returned,
             # selecting the first (and only) element
-            self.creds_domain = self.identity_client.list_domains(
+            self.creds_domain = self.domains_client.list_domains(
                 params={'name': domain_name})['domains'][0]
         except lib_exc.NotFound:
             # TODO(andrea) we could probably create the domain on the fly
@@ -179,10 +181,11 @@
                      projects_client,
                      users_client,
                      roles_client=None,
+                     domains_client=None,
                      project_domain_name=None):
     if isinstance(identity_client, v2_identity.IdentityClient):
         return V2CredsClient(identity_client, projects_client, users_client,
                              roles_client)
     else:
         return V3CredsClient(identity_client, projects_client, users_client,
-                             project_domain_name)
+                             domains_client, project_domain_name)
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 1810c57..a758a32 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -61,6 +61,7 @@
          self.tenants_admin_client,
          self.users_admin_client,
          self.roles_admin_client,
+         self.domains_admin_client,
          self.network_admin_client,
          self.networks_admin_client,
          self.subnets_admin_client,
@@ -78,6 +79,7 @@
             self.tenants_admin_client,
             self.users_admin_client,
             self.roles_admin_client,
+            self.domains_admin_client,
             self.creds_domain_name)
 
     def _get_admin_clients(self):
@@ -90,14 +92,14 @@
         os = clients.Manager(self.default_admin_creds)
         if self.identity_version == 'v2':
             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.roles_client, None, os.network_client,
+                    os.networks_client, os.subnets_client, os.ports_client,
                     os.security_groups_client)
         else:
             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)
+                    os.users_v3_client, None, os.domains_client,
+                    os.network_client, os.networks_client, os.subnets_client,
+                    os.ports_client, os.security_groups_client)
 
     def _create_creds(self, suffix="", admin=False, roles=None):
         """Create random credentials under the following schema.
diff --git a/tempest/config.py b/tempest/config.py
index 515f736..4fe7163 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -740,7 +740,11 @@
                 default=True,
                 help='Update bootable status of a volume '
                      'Not implemented on icehouse ',
-                deprecated_for_removal=True)
+                deprecated_for_removal=True),
+    # TODO(ynesenenko): Remove volume_services once liberty-eol happens.
+    cfg.BoolOpt('volume_services',
+                default=False,
+                help='Extract correct host info from host@backend')
 ]
 
 
diff --git a/tempest/services/base_microversion_client.py b/tempest/services/base_microversion_client.py
deleted file mode 100644
index 4c750f5..0000000
--- a/tempest/services/base_microversion_client.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# 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_compute_client.py b/tempest/services/compute/json/base_compute_client.py
index 5349af6..5ea289c 100644
--- a/tempest/services/compute/json/base_compute_client.py
+++ b/tempest/services/compute/json/base_compute_client.py
@@ -11,30 +11,38 @@
 #    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
 
 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
+
+COMPUTE_MICROVERSION = None
 
 
-class BaseComputeClient(base_microversion_client.BaseMicroversionClient):
+class BaseComputeClient(rest_client.RestClient):
+    api_microversion_header_name = 'X-OpenStack-Nova-API-Version'
 
     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)
+            auth_provider, service, region, **kwargs)
+
+    def get_headers(self):
+        headers = super(BaseComputeClient, self).get_headers()
+        if COMPUTE_MICROVERSION:
+            headers[self.api_microversion_header_name] = COMPUTE_MICROVERSION
+        return headers
 
     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':
+        if (COMPUTE_MICROVERSION and
+            COMPUTE_MICROVERSION != api_version_utils.LATEST_MICROVERSION):
             api_version_utils.assert_version_header_matches_request(
                 self.api_microversion_header_name,
-                self.api_microversion,
+                COMPUTE_MICROVERSION,
                 resp)
         return resp, resp_body
 
@@ -52,7 +60,7 @@
             {'min': '2.10', 'max': None, 'schema': schemav210}]
         """
         schema = None
-        version = api_version_request.APIVersionRequest(self.api_microversion)
+        version = api_version_request.APIVersionRequest(COMPUTE_MICROVERSION)
         for items in schema_versions_info:
             min_version = api_version_request.APIVersionRequest(items['min'])
             max_version = api_version_request.APIVersionRequest(items['max'])
diff --git a/tempest/services/identity/v3/json/domains_client.py b/tempest/services/identity/v3/json/domains_client.py
new file mode 100644
index 0000000..626a474
--- /dev/null
+++ b/tempest/services/identity/v3/json/domains_client.py
@@ -0,0 +1,77 @@
+# 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 DomainsClient(service_client.ServiceClient):
+    api_version = "v3"
+
+    def create_domain(self, name, **kwargs):
+        """Creates a domain."""
+        description = kwargs.get('description', None)
+        en = kwargs.get('enabled', True)
+        post_body = {
+            'description': description,
+            'enabled': en,
+            'name': name
+        }
+        post_body = json.dumps({'domain': post_body})
+        resp, body = self.post('domains', post_body)
+        self.expected_success(201, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_domain(self, domain_id):
+        """Deletes a domain."""
+        resp, body = self.delete('domains/%s' % str(domain_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def list_domains(self, params=None):
+        """List Domains."""
+        url = 'domains'
+        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_domain(self, domain_id, **kwargs):
+        """Updates a 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'])
+        post_body = {
+            'description': description,
+            'enabled': en,
+            'name': name
+        }
+        post_body = json.dumps({'domain': post_body})
+        resp, body = self.patch('domains/%s' % domain_id, post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def show_domain(self, domain_id):
+        """Get Domain details."""
+        resp, body = self.get('domains/%s' % domain_id)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 809d0b5..e4daf7a 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -14,7 +14,6 @@
 #    under the License.
 
 from oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
 
 from tempest.common import service_client
 
@@ -74,61 +73,6 @@
         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)
-        en = kwargs.get('enabled', True)
-        post_body = {
-            'description': description,
-            'enabled': en,
-            'name': name
-        }
-        post_body = json.dumps({'domain': post_body})
-        resp, body = self.post('domains', post_body)
-        self.expected_success(201, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_domain(self, domain_id):
-        """Delete a domain."""
-        resp, body = self.delete('domains/%s' % str(domain_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def list_domains(self, params=None):
-        """List Domains."""
-        url = 'domains'
-        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_domain(self, domain_id, **kwargs):
-        """Updates a 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'])
-        post_body = {
-            'description': description,
-            'enabled': en,
-            'name': name
-        }
-        post_body = json.dumps({'domain': post_body})
-        resp, body = self.patch('domains/%s' % domain_id, post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def show_domain(self, domain_id):
-        """Get Domain details."""
-        resp, body = self.get('domains/%s' % domain_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
     def show_token(self, resp_token):
         """Get token details."""
         headers = {'X-Subject-Token': resp_token}
@@ -263,64 +207,3 @@
                                (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.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3-ext.html#createTrust
-        """
-        post_body = json.dumps({'trust': kwargs})
-        resp, body = self.post('OS-TRUST/trusts', post_body)
-        self.expected_success(201, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_trust(self, trust_id):
-        """Deletes a trust."""
-        resp, body = self.delete("OS-TRUST/trusts/%s" % trust_id)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    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"
-                                  % trustor_user_id)
-        elif trustee_user_id:
-            resp, body = self.get("OS-TRUST/trusts?trustee_user_id=%s"
-                                  % trustee_user_id)
-        else:
-            resp, body = self.get("OS-TRUST/trusts")
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    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 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 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))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def check_trust_role(self, trust_id, role_id):
-        """HEAD Check if role is delegated by a trust."""
-        resp, body = self.head("OS-TRUST/trusts/%s/roles/%s"
-                               % (trust_id, role_id))
-        self.expected_success(200, resp.status)
-        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/trusts_client.py b/tempest/services/identity/v3/json/trusts_client.py
new file mode 100644
index 0000000..42b2bdb
--- /dev/null
+++ b/tempest/services/identity/v3/json/trusts_client.py
@@ -0,0 +1,82 @@
+# 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 TrustsClient(service_client.ServiceClient):
+    api_version = "v3"
+
+    def create_trust(self, **kwargs):
+        """Creates a trust.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3-ext.html#createTrust
+        """
+        post_body = json.dumps({'trust': kwargs})
+        resp, body = self.post('OS-TRUST/trusts', post_body)
+        self.expected_success(201, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_trust(self, trust_id):
+        """Deletes a trust."""
+        resp, body = self.delete("OS-TRUST/trusts/%s" % trust_id)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    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"
+                                  % trustor_user_id)
+        elif trustee_user_id:
+            resp, body = self.get("OS-TRUST/trusts?trustee_user_id=%s"
+                                  % trustee_user_id)
+        else:
+            resp, body = self.get("OS-TRUST/trusts")
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    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 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 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))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def check_trust_role(self, trust_id, role_id):
+        """HEAD Check if role is delegated by a trust."""
+        resp, body = self.head("OS-TRUST/trusts/%s/roles/%s"
+                               % (trust_id, role_id))
+        self.expected_success(200, resp.status)
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 3c69a8b..2ebb11d 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -149,16 +149,18 @@
                     projects_client = admin_manager.tenants_client
                     roles_client = admin_manager.roles_client
                     users_client = admin_manager.users_client
+                    domains_client = None
                 else:
                     identity_client = admin_manager.identity_v3_client
                     projects_client = admin_manager.projects_client
                     roles_client = None
                     users_client = admin_manager.users_v3_client
+                    domains_client = admin_manager.domains_client
                 domain = (identity_client.auth_provider.credentials.
                           get('project_domain_name', 'Default'))
                 credentials_client = cred_client.get_creds_client(
                     identity_client, projects_client, users_client,
-                    roles_client, project_domain_name=domain)
+                    roles_client, domains_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/test.py b/tempest/test.py
index ee3288c..a93903e 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -226,7 +226,6 @@
     # Resources required to validate a server using ssh
     validation_resources = {}
     network_resources = {}
-    services_microversion = {}
 
     # NOTE(sdague): log_format is defined inline here instead of using the oslo
     # default because going through the config path recouples config to the
@@ -443,11 +442,13 @@
             users_client = self.os_admin.users_client
             project_client = self.os_admin.tenants_client
             roles_client = self.os_admin.roles_client
+            domains_client = None
         else:
             client = self.os_admin.identity_v3_client
             project_client = self.os_adm.projects_client
             users_client = self.os_admin.users_v3_client
             roles_client = None
+            domains_client = self.os_admin.domains_client
 
         try:
             domain = client.auth_provider.credentials.project_domain_name
@@ -457,6 +458,7 @@
         return cred_client.get_creds_client(client, project_client,
                                             users_client,
                                             roles_client,
+                                            domains_client,
                                             project_domain_name=domain)
 
     @classmethod
@@ -522,8 +524,7 @@
             else:
                 raise exceptions.InvalidCredentials(
                     "Invalid credentials type %s" % credential_type)
-        return cls.client_manager(credentials=creds, service=cls._service,
-                                  api_microversions=cls.services_microversion)
+        return cls.client_manager(credentials=creds, service=cls._service)
 
     @classmethod
     def clear_credentials(cls):
@@ -610,8 +611,7 @@
                 credentials.is_admin_available(
                     identity_version=cls.get_identity_version())):
             admin_creds = cred_provider.get_admin_creds()
-            admin_manager = clients.Manager(
-                admin_creds, api_microversions=cls.services_microversion)
+            admin_manager = clients.Manager(admin_creds)
             networks_client = admin_manager.compute_networks_client
         return fixed_network.get_tenant_network(
             cred_provider, networks_client, CONF.compute.fixed_network_name)
diff --git a/tempest/tests/services/compute/test_base_compute_client.py b/tempest/tests/services/compute/test_base_compute_client.py
index 7a55cdb..672ae33 100644
--- a/tempest/tests/services/compute/test_base_compute_client.py
+++ b/tempest/tests/services/compute/test_base_compute_client.py
@@ -13,9 +13,11 @@
 #    under the License.
 
 import httplib2
+import mock
 from oslotest import mockpatch
 from tempest_lib.common import rest_client
 
+from tempest.api.compute import api_microversion_fixture
 from tempest import exceptions
 from tempest.services.compute.json import base_compute_client
 from tempest.tests import fake_auth_provider
@@ -29,7 +31,7 @@
         fake_auth = fake_auth_provider.FakeAuthProvider()
         self.client = base_compute_client.BaseComputeClient(
             fake_auth, 'compute', 'regionOne')
-        self.client.set_api_microversion('2.2')
+        self.useFixture(api_microversion_fixture.APIMicroversionFixture('2.2'))
 
     def _check_microverion_header_in_response(self, fake_response):
         def request(*args, **kwargs):
@@ -75,7 +77,8 @@
         super(TestSchemaVersionsNone, self).setUp()
         fake_auth = fake_auth_provider.FakeAuthProvider()
         self.client = DummyServiceClient1(fake_auth, 'compute', 'regionOne')
-        self.client.api_microversion = self.api_microversion
+        self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+            self.api_microversion))
 
     def test_schema(self):
         self.assertEqual(self.expected_schema,
@@ -129,8 +132,62 @@
         super(TestSchemaVersionsNotFound, self).setUp()
         fake_auth = fake_auth_provider.FakeAuthProvider()
         self.client = DummyServiceClient2(fake_auth, 'compute', 'regionOne')
-        self.client.api_microversion = self.api_microversion
+        self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+            self.api_microversion))
 
     def test_schema(self):
         self.assertRaises(exceptions.JSONSchemaNotFound,
                           self.client.return_selected_schema)
+
+
+class TestClientWithoutMicroversionHeader(base.BaseComputeServiceTest):
+
+    def setUp(self):
+        super(TestClientWithoutMicroversionHeader, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = base_compute_client.BaseComputeClient(
+            fake_auth, 'compute', 'regionOne')
+
+    def test_no_microverion_header(self):
+        header = self.client.get_headers()
+        self.assertNotIn('X-OpenStack-Nova-API-Version', header)
+
+    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}), {})
+
+        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_compute_client.BaseComputeClient(
+            fake_auth, 'compute', 'regionOne')
+        self.useFixture(api_microversion_fixture.APIMicroversionFixture('2.2'))
+
+    def test_microverion_header(self):
+        header = self.client.get_headers()
+        self.assertIn('X-OpenStack-Nova-API-Version', header)
+        self.assertEqual('2.2',
+                         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('2.2',
+                             kwargs['headers']['X-OpenStack-Nova-API-Version'])
+            return (httplib2.Response(
+                {'status': 200,
+                 self.client.api_microversion_header_name: '2.2'}), {})
+
+        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/services/test_base_microversion_client.py b/tempest/tests/services/test_base_microversion_client.py
deleted file mode 100644
index 11b8170..0000000
--- a/tempest/tests/services/test_base_microversion_client.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# 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')