Merge "Fix volume mountpoint - read from configuration file"
diff --git a/HACKING.rst b/HACKING.rst
index 44519d4..b82f8c9 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -214,9 +214,9 @@
 things to watch out for to try to avoid issues when running your tests in
 parallel.
 
-- Resources outside of a tenant scope still have the potential to conflict. This
+- Resources outside of a project scope still have the potential to conflict. This
   is a larger concern for the admin tests since most resources and actions that
-  require admin privileges are outside of tenants.
+  require admin privileges are outside of projects.
 
 - Races between methods in the same class are not a problem because
   parallelization in tempest is at the test class level, but if there is a json
diff --git a/REVIEWING.rst b/REVIEWING.rst
index f7334ad..bd6018d 100644
--- a/REVIEWING.rst
+++ b/REVIEWING.rst
@@ -2,7 +2,7 @@
 ======================
 
 To start read the `OpenStack Common Review Checklist
-<https://wiki.openstack.org/wiki/ReviewChecklist#Common_Review_Checklist>`_
+<http://docs.openstack.org/infra/manual/developers.html#peer-review>`_
 
 
 Ensuring code is executed
diff --git a/data/tempest-plugins-registry.header b/data/tempest-plugins-registry.header
new file mode 100644
index 0000000..9821e8e
--- /dev/null
+++ b/data/tempest-plugins-registry.header
@@ -0,0 +1,23 @@
+..
+  Note to patch submitters: this file is covered by a periodic proposal
+  job.  You should edit the files data/tempest-plugins-registry.footer
+  and data/tempest-plugins-registry.header instead of this one.
+
+==========================
+ Tempest Plugin Registry
+==========================
+
+Since we've created the external plugin mechanism, it's gotten used by
+a lot of projects. The following is a list of plugins that currently
+exist.
+
+Detected Plugins
+================
+
+The following are plugins that a script has found in the openstack/
+namespace, which includes but is not limited to official OpenStack
+projects.
+
++----------------------------+-------------------------------------------------------------------------+
+|Plugin Name                 |URL                                                                      |
++----------------------------+-------------------------------------------------------------------------+
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 367be41..245386b 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -17,7 +17,7 @@
 in the tempest.conf file. These options are clearly labelled in the ``identity``
 section and let you specify a set of credentials for a regular user, a global
 admin user, and an alternate user, consisting of a username, password, and
-project/tenant name.
+project name.
 
 The other method to provide credentials is using the accounts.yaml file. This
 file is used to specify an arbitrary number of users available to run tests
@@ -59,13 +59,13 @@
 Dynamic Credentials (formerly known as Tenant isolation) was originally created
 to enable running Tempest in parallel.  For each test class it creates a unique
 set of user credentials to use for the tests in the class. It can create up to
-three sets of username, password, and tenant/project names for a primary user,
-an admin user, and an alternate user.  To enable and use dynamic credentials you
+three sets of username, password, and project names for a primary user,
+an admin user, and an alternate user. To enable and use dynamic credentials you
 only need to configure two things:
 
  #. A set of admin credentials with permissions to create users and
-    tenants/projects. This is specified in the ``auth`` section with the
-    ``admin_username``, ``admin_tenant_name``, ``admin_domain_name`` and
+    projects. This is specified in the ``auth`` section with the
+    ``admin_username``, ``admin_project_name``, ``admin_domain_name`` and
     ``admin_password`` options
  #. To enable dynamic credentials in the ``auth`` section with the
     ``use_dynamic_credentials`` option.
@@ -112,7 +112,7 @@
  #. Set ``use_dynamic_credentials = False`` in the ``auth`` group
 
 It is worth pointing out that each set of credentials in the accounts.yaml
-should have a unique tenant. This is required to provide proper isolation
+should have a unique project. This is required to provide proper isolation
 to the tests using the credentials, and failure to do this will likely cause
 unexpected failures in some tests.
 
@@ -123,7 +123,7 @@
 removed in a future release.**
 
 When Tempest was refactored to allow for locking test accounts, the original
-non-tenant isolated case was converted to internally work similarly to the
+non-project isolated case was converted to internally work similarly to the
 accounts.yaml file. This mechanism was then called the legacy test accounts
 provider. To use the legacy test accounts provider you can specify the sets of
 credentials in the configuration file as detailed above with following nine
@@ -131,13 +131,13 @@
 
  #. ``username``
  #. ``password``
- #. ``tenant_name``
+ #. ``project_name``
  #. ``admin_username``
  #. ``admin_password``
- #. ``admin_tenant_name``
+ #. ``admin_project_name``
  #. ``alt_username``
  #. ``alt_password``
- #. ``alt_tenant_name``
+ #. ``alt_project_name``
 
 If using Identity API v3, use the ``domain_name`` option to specify a
 domain other than the default domain.  The ``auth_version`` setting is
@@ -265,7 +265,7 @@
 """"""""""""""""""
 This is the simplest method of specifying how networks should be used. You can
 just specify a single network name/label to use for all server creations. The
-limitation with this is that all tenants/projects and users must be able to see
+limitation with this is that all projects and users must be able to see
 that network name/label if they are to perform a network list and be able to use
 it.
 
@@ -287,10 +287,10 @@
 """""""""""""
 If you are using an accounts file to provide credentials for running Tempest
 then you can leverage it to also specify which network should be used with
-server creations on a per tenant/project and user pair basis. This provides
+server creations on a per project and user pair basis. This provides
 the necessary flexibility to work with more intricate networking configurations
 by enabling the user to specify exactly which network to use for which
-tenants/projects. You can refer to the accounts.yaml.sample file included in
+projects. You can refer to the accounts.yaml.sample file included in
 the Tempest repo for the syntax around specifying networks in the file.
 
 However, specifying a network is not required when using an accounts file. If
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 5f357b2..10364db 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -11,6 +11,7 @@
    HACKING
    REVIEWING
    plugin
+   plugin-registry
    library
    microversion_testing
 
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
new file mode 100644
index 0000000..517e5b8
--- /dev/null
+++ b/doc/source/plugin-registry.rst
@@ -0,0 +1,23 @@
+..
+  Note to patch submitters: this file is covered by a periodic proposal
+  job.  You should edit the files data/tempest-plugins-registry.footer
+  data/tempest-plugins-registry.header instead of this one.
+
+==========================
+ Tempest Plugin Registry
+==========================
+
+Since we've created the external plugin mechanism, it's gotten used by
+a lot of projects. The following is a list of plugins that currently
+exist.
+
+Detected Plugins
+================
+
+The following will list plugins that a script has found in the openstack/
+namespace, which includes but is not limited to official OpenStack
+projects.
+
++----------------------------+-------------------------------------------------------------------------+
+|Plugin Name                 |URL                                                                      |
++----------------------------+-------------------------------------------------------------------------+
diff --git a/releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml b/releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml
new file mode 100644
index 0000000..09ff15d
--- /dev/null
+++ b/releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml
@@ -0,0 +1,12 @@
+---
+prelude: >
+    This release is marking the start of Mitaka release support in tempest
+other:
+    - OpenStack Releases Supported at this time are **Kilo**, **Liberty**,
+      **Mitaka**
+
+      The release under current development as of this tag is Newton,
+      meaning that every Tempest commit is also tested against master during
+      the Newton cycle. However, this does not necessarily mean that using
+      Tempest as of this tag will work against a Newton (or future releases)
+      cloud.
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index 5bd9176..b617b22 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -5,6 +5,7 @@
  .. toctree::
     :maxdepth: 1
 
+    v11.0.0
     v10.0.0
     unreleased
 
diff --git a/releasenotes/source/v11.0.0.rst b/releasenotes/source/v11.0.0.rst
new file mode 100644
index 0000000..84b145d
--- /dev/null
+++ b/releasenotes/source/v11.0.0.rst
@@ -0,0 +1,6 @@
+=====================
+v11.0.0 Release Notes
+=====================
+
+.. release-notes:: 11.0.0 Release Notes
+   :version: 11.0.0
diff --git a/requirements.txt b/requirements.txt
index 9dd57a9..7c426e6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,14 +12,14 @@
 testrepository>=0.0.18 # Apache-2.0/BSD
 pyOpenSSL>=0.14 # Apache-2.0
 oslo.concurrency>=3.5.0 # Apache-2.0
-oslo.config>=3.7.0 # Apache-2.0
+oslo.config>=3.9.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.5.0 # Apache-2.0
 six>=1.9.0 # MIT
 iso8601>=0.1.9 # MIT
-fixtures>=1.3.1 # Apache-2.0/BSD
+fixtures<2.0,>=1.3.1 # Apache-2.0/BSD
 testscenarios>=0.4 # Apache-2.0/BSD
 PyYAML>=3.1.0 # MIT
 stevedore>=1.5.0 # Apache-2.0
diff --git a/tempest/api/baremetal/admin/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
index 8cc4d05..2c44665 100644
--- a/tempest/api/baremetal/admin/test_nodes.py
+++ b/tempest/api/baremetal/admin/test_nodes.py
@@ -138,14 +138,14 @@
         body = self.client.get_node_boot_device(self.node['uuid'])
         self.assertIn('boot_device', body)
         self.assertIn('persistent', body)
-        self.assertTrue(isinstance(body['boot_device'], six.string_types))
-        self.assertTrue(isinstance(body['persistent'], bool))
+        self.assertIsInstance(body['boot_device'], six.string_types)
+        self.assertIsInstance(body['persistent'], bool)
 
     @test.idempotent_id('3622bc6f-3589-4bc2-89f3-50419c66b133')
     def test_get_node_supported_boot_devices(self):
         body = self.client.get_node_supported_boot_devices(self.node['uuid'])
         self.assertIn('supported_boot_devices', body)
-        self.assertTrue(isinstance(body['supported_boot_devices'], list))
+        self.assertIsInstance(body['supported_boot_devices'], list)
 
     @test.idempotent_id('f63b6288-1137-4426-8cfe-0d5b7eb87c06')
     def test_get_console(self):
diff --git a/tempest/api/compute/admin/test_keypairs_v210.py b/tempest/api/compute/admin/test_keypairs_v210.py
new file mode 100644
index 0000000..dfa7c39
--- /dev/null
+++ b/tempest/api/compute/admin/test_keypairs_v210.py
@@ -0,0 +1,76 @@
+# 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 base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class KeyPairsV210TestJSON(base.BaseKeypairTest):
+    credentials = ['primary', 'admin']
+    min_microversion = '2.10'
+
+    @classmethod
+    def setup_clients(cls):
+        super(KeyPairsV210TestJSON, cls).setup_clients()
+        cls.client = cls.os_adm.keypairs_client
+        cls.non_admin_client = cls.os.keypairs_client
+
+    def _create_and_check_keypairs(self, user_id):
+        key_list = list()
+        for i in range(2):
+            k_name = data_utils.rand_name('keypair')
+            keypair = self._create_keypair(k_name,
+                                           keypair_type='ssh',
+                                           user_id=user_id)
+            self.assertEqual(k_name, keypair['name'],
+                             "The created keypair name is not equal "
+                             "to the requested name!")
+            self.assertEqual(user_id, keypair['user_id'],
+                             "The created keypair is not for requested user!")
+            keypair.pop('private_key', None)
+            keypair.pop('user_id')
+            key_list.append(keypair)
+        return key_list
+
+    @test.idempotent_id('3c8484af-cfb3-48f6-b8ba-d5d58bbf3eac')
+    def test_admin_manage_keypairs_for_other_users(self):
+        user_id = self.non_admin_client.user_id
+        key_list = self._create_and_check_keypairs(user_id)
+        first_keyname = key_list[0]['name']
+        keypair_detail = self.client.show_keypair(first_keyname,
+                                                  user_id=user_id)['keypair']
+        self.assertEqual(first_keyname, keypair_detail['name'])
+        self.assertEqual(user_id, keypair_detail['user_id'],
+                         "The fetched keypair is not for requested user!")
+        # Create a admin keypair
+        admin_k_name = data_utils.rand_name('keypair')
+        admin_keypair = self._create_keypair(admin_k_name, keypair_type='ssh')
+        admin_keypair.pop('private_key', None)
+        admin_keypair.pop('user_id')
+
+        # Admin fetch keypairs list of non admin user
+        keypairs = self.client.list_keypairs(user_id=user_id)['keypairs']
+        fetched_list = [keypair['keypair'] for keypair in keypairs]
+
+        # Check admin keypair is not present in non admin user keypairs list
+        self.assertNotIn(admin_keypair, fetched_list,
+                         "The fetched user keypairs has admin keypair!")
+
+        # Now check if all the created keypairs are in the fetched list
+        missing_kps = [kp for kp in key_list if kp not in fetched_list]
+        self.assertFalse(missing_kps,
+                         "Failed to find keypairs %s in fetched list"
+                         % ', '.join(m_key['name'] for m_key in missing_kps))
diff --git a/tempest/api/compute/keypairs/base.py b/tempest/api/compute/keypairs/base.py
index ebfb724..ad7f958 100644
--- a/tempest/api/compute/keypairs/base.py
+++ b/tempest/api/compute/keypairs/base.py
@@ -24,15 +24,21 @@
         super(BaseKeypairTest, cls).setup_clients()
         cls.client = cls.keypairs_client
 
-    def _delete_keypair(self, keypair_name):
-        self.client.delete_keypair(keypair_name)
+    def _delete_keypair(self, keypair_name, **params):
+        self.client.delete_keypair(keypair_name, **params)
 
-    def _create_keypair(self, keypair_name, pub_key=None, keypair_type=None):
+    def _create_keypair(self, keypair_name,
+                        pub_key=None, keypair_type=None,
+                        user_id=None):
         kwargs = {'name': keypair_name}
+        delete_params = {}
         if pub_key:
             kwargs.update({'public_key': pub_key})
         if keypair_type:
             kwargs.update({'type': keypair_type})
+        if user_id:
+            kwargs.update({'user_id': user_id})
+            delete_params['user_id'] = user_id
         body = self.client.create_keypair(**kwargs)['keypair']
-        self.addCleanup(self._delete_keypair, keypair_name)
+        self.addCleanup(self._delete_keypair, keypair_name, **delete_params)
         return body
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index f719bfc..87f3c86 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -38,7 +38,6 @@
     def setup_clients(cls):
         super(ServersTestJSON, cls).setup_clients()
         cls.client = cls.servers_client
-        cls.network_client = cls.os.network_client
         cls.networks_client = cls.os.networks_client
         cls.subnets_client = cls.os.subnets_client
 
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 0df6ead..8f0e430 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -29,8 +29,6 @@
 
 class ServersNegativeTestJSON(base.BaseV2ComputeTest):
 
-    credentials = ['primary', 'alt']
-
     def setUp(self):
         super(ServersNegativeTestJSON, self).setUp()
         try:
@@ -47,7 +45,6 @@
     def setup_clients(cls):
         super(ServersNegativeTestJSON, cls).setup_clients()
         cls.client = cls.servers_client
-        cls.alt_client = cls.os_alt.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -271,16 +268,6 @@
                           self.server_id, name=new_name)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
-    def test_update_server_of_another_tenant(self):
-        # Update name of a server that belongs to another tenant
-
-        new_name = self.server_id + '_new'
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_client.update_server, self.server_id,
-                          name=new_name)
-
-    @test.attr(type=['negative'])
     @test.idempotent_id('5c8e244c-dada-4590-9944-749c455b431f')
     def test_update_server_name_length_exceeds_256(self):
         # Update name of server exceed the name length limit
@@ -301,14 +288,6 @@
                           nonexistent_server)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
-    def test_delete_a_server_of_another_tenant(self):
-        # Delete a server that belongs to another tenant
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_client.delete_server,
-                          self.server_id)
-
-    @test.attr(type=['negative'])
     @test.idempotent_id('75f79124-277c-45e6-a373-a1d6803f4cc4')
     def test_delete_server_pass_negative_id(self):
         # Pass an invalid string parameter to delete server
@@ -519,3 +498,45 @@
         self.assertRaises(lib_exc.Conflict,
                           self.client.unshelve_server,
                           self.server_id)
+
+
+class ServersNegativeTestMultiTenantJSON(base.BaseV2ComputeTest):
+
+    credentials = ['primary', 'alt']
+
+    def setUp(self):
+        super(ServersNegativeTestMultiTenantJSON, self).setUp()
+        try:
+            waiters.wait_for_server_status(self.client, self.server_id,
+                                           'ACTIVE')
+        except Exception:
+            self.__class__.server_id = self.rebuild_server(self.server_id)
+
+    @classmethod
+    def setup_clients(cls):
+        super(ServersNegativeTestMultiTenantJSON, cls).setup_clients()
+        cls.alt_client = cls.os_alt.servers_client
+
+    @classmethod
+    def resource_setup(cls):
+        super(ServersNegativeTestMultiTenantJSON, cls).resource_setup()
+        server = cls.create_test_server(wait_until='ACTIVE')
+        cls.server_id = server['id']
+
+    @test.attr(type=['negative'])
+    @test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
+    def test_update_server_of_another_tenant(self):
+        # Update name of a server that belongs to another tenant
+
+        new_name = self.server_id + '_new'
+        self.assertRaises(lib_exc.NotFound,
+                          self.alt_client.update_server, self.server_id,
+                          name=new_name)
+
+    @test.attr(type=['negative'])
+    @test.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
+    def test_delete_a_server_of_another_tenant(self):
+        # Delete a server that belongs to another tenant
+        self.assertRaises(lib_exc.NotFound,
+                          self.alt_client.delete_server,
+                          self.server_id)
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
deleted file mode 100644
index 133502c..0000000
--- a/tempest/api/compute/test_authorization.py
+++ /dev/null
@@ -1,451 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import six
-
-from oslo_log import log as logging
-
-from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest.lib import exceptions as lib_exc
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class AuthorizationTestJSON(base.BaseV2ComputeTest):
-
-    credentials = ['primary', 'alt']
-
-    @classmethod
-    def skip_checks(cls):
-        super(AuthorizationTestJSON, cls).skip_checks()
-        if not CONF.service_available.glance:
-            raise cls.skipException('Glance is not available.')
-
-    @classmethod
-    def setup_credentials(cls):
-        # No network resources required for this test
-        cls.set_network_resources()
-        super(AuthorizationTestJSON, cls).setup_credentials()
-
-    @classmethod
-    def setup_clients(cls):
-        super(AuthorizationTestJSON, cls).setup_clients()
-        cls.client = cls.os.servers_client
-        cls.compute_images_client = cls.os.compute_images_client
-        cls.glance_client = cls.os.image_client
-        cls.keypairs_client = cls.os.keypairs_client
-        cls.security_client = cls.os.compute_security_groups_client
-        cls.rule_client = cls.os.compute_security_group_rules_client
-
-        cls.alt_client = cls.alt_manager.servers_client
-        cls.alt_compute_images_client = cls.alt_manager.compute_images_client
-        cls.alt_keypairs_client = cls.alt_manager.keypairs_client
-        cls.alt_security_client = (
-            cls.alt_manager.compute_security_groups_client)
-        cls.alt_rule_client = (
-            cls.alt_manager.compute_security_group_rules_client)
-
-    @classmethod
-    def resource_setup(cls):
-        super(AuthorizationTestJSON, cls).resource_setup()
-        server = cls.create_test_server(wait_until='ACTIVE')
-        cls.server = cls.client.show_server(server['id'])['server']
-
-        name = data_utils.rand_name('image')
-        body = cls.glance_client.create_image(name=name,
-                                              container_format='bare',
-                                              disk_format='raw',
-                                              is_public=False)['image']
-        image_id = body['id']
-        image_file = six.StringIO(('*' * 1024))
-        body = cls.glance_client.update_image(image_id,
-                                              data=image_file)['image']
-        cls.glance_client.wait_for_image_status(image_id, 'active')
-        cls.image = cls.compute_images_client.show_image(image_id)['image']
-
-        cls.keypairname = data_utils.rand_name('keypair')
-        cls.keypairs_client.create_keypair(name=cls.keypairname)
-
-        name = data_utils.rand_name('security')
-        description = data_utils.rand_name('description')
-        cls.security_group = cls.security_client.create_security_group(
-            name=name, description=description)['security_group']
-
-        parent_group_id = cls.security_group['id']
-        ip_protocol = 'tcp'
-        from_port = 22
-        to_port = 22
-        cls.rule = cls.rule_client.create_security_group_rule(
-            parent_group_id=parent_group_id, ip_protocol=ip_protocol,
-            from_port=from_port, to_port=to_port)['security_group_rule']
-
-    @classmethod
-    def resource_cleanup(cls):
-        if hasattr(cls, 'image'):
-            cls.compute_images_client.delete_image(cls.image['id'])
-        if hasattr(cls, 'keypairname'):
-            cls.keypairs_client.delete_keypair(cls.keypairname)
-        if hasattr(cls, 'security_group'):
-            cls.security_client.delete_security_group(cls.security_group['id'])
-        super(AuthorizationTestJSON, cls).resource_cleanup()
-
-    @test.idempotent_id('56816e4a-bd34-47b5-aee9-268c3efeb5d4')
-    def test_get_server_for_alt_account_fails(self):
-        # A GET request for a server on another user's account should fail
-        self.assertRaises(lib_exc.NotFound, self.alt_client.show_server,
-                          self.server['id'])
-
-    @test.idempotent_id('fb8a4870-6d9d-44ad-8375-95d52e98d9f6')
-    def test_delete_server_for_alt_account_fails(self):
-        # A DELETE request for another user's server should fail
-        self.assertRaises(lib_exc.NotFound, self.alt_client.delete_server,
-                          self.server['id'])
-
-    @test.idempotent_id('d792f91f-1d49-4eb5-b1ff-b229c4b9dc64')
-    def test_update_server_for_alt_account_fails(self):
-        # An update server request for another user's server should fail
-        self.assertRaises(lib_exc.NotFound, self.alt_client.update_server,
-                          self.server['id'], name='test')
-
-    @test.idempotent_id('488f24df-d7f7-4207-949a-f17fcb8e8769')
-    def test_list_server_addresses_for_alt_account_fails(self):
-        # A list addresses request for another user's server should fail
-        self.assertRaises(lib_exc.NotFound, self.alt_client.list_addresses,
-                          self.server['id'])
-
-    @test.idempotent_id('00b442d0-2e72-40e7-9b1f-31772e36da01')
-    def test_list_server_addresses_by_network_for_alt_account_fails(self):
-        # A list address/network request for another user's server should fail
-        server_id = self.server['id']
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_client.list_addresses_by_network, server_id,
-                          'public')
-
-    @test.idempotent_id('cc90b35a-19f0-45d2-b680-2aabf934aa22')
-    def test_list_servers_with_alternate_tenant(self):
-        # A list on servers from one tenant should not
-        # show on alternate tenant
-        # Listing servers from alternate tenant
-        alt_server_ids = []
-        body = self.alt_client.list_servers()
-        alt_server_ids = [s['id'] for s in body['servers']]
-        self.assertNotIn(self.server['id'], alt_server_ids)
-
-    @test.idempotent_id('376dbc16-0779-4384-a723-752774799641')
-    def test_change_password_for_alt_account_fails(self):
-        # A change password request for another user's server should fail
-        self.assertRaises(lib_exc.NotFound, self.alt_client.change_password,
-                          self.server['id'], adminPass='newpass')
-
-    @test.idempotent_id('14cb5ff5-f646-45ca-8f51-09081d6c0c24')
-    def test_reboot_server_for_alt_account_fails(self):
-        # A reboot request for another user's server should fail
-        self.assertRaises(lib_exc.NotFound, self.alt_client.reboot_server,
-                          self.server['id'], type='HARD')
-
-    @test.idempotent_id('8a0bce51-cd00-480b-88ba-dbc7d8408a37')
-    def test_rebuild_server_for_alt_account_fails(self):
-        # A rebuild request for another user's server should fail
-        self.assertRaises(lib_exc.NotFound, self.alt_client.rebuild_server,
-                          self.server['id'], self.image_ref_alt)
-
-    @test.idempotent_id('e4da647e-f982-4e61-9dad-1d1abebfb933')
-    def test_resize_server_for_alt_account_fails(self):
-        # A resize request for another user's server should fail
-        self.assertRaises(lib_exc.NotFound, self.alt_client.resize_server,
-                          self.server['id'], self.flavor_ref_alt)
-
-    @test.idempotent_id('a9fe8112-0ffa-4902-b061-f892bd5fe0d3')
-    def test_create_image_for_alt_account_fails(self):
-        # A create image request for another user's server should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_compute_images_client.create_image,
-                          self.server['id'], name='testImage')
-
-    @test.idempotent_id('95d445f6-babc-4f2e-aea3-aa24ec5e7f0d')
-    def test_create_server_with_unauthorized_image(self):
-        # Server creation with another user's image should fail
-        self.assertRaises(lib_exc.BadRequest, self.alt_client.create_server,
-                          name='test', imageRef=self.image['id'],
-                          flavorRef=self.flavor_ref)
-
-    @test.idempotent_id('acf8724b-142b-4044-82c3-78d31a533f24')
-    def test_create_server_fails_when_tenant_incorrect(self):
-        # BUG(sdague): this test should fail because of bad auth url,
-        # which means that when we run with a service catalog without
-        # project_id in the urls, it should fail to fail, and thus
-        # fail the test. It does not.
-        #
-        # The 400 BadRequest is clearly ambiguous, and something else
-        # is wrong about this request. This should be fixed.
-        #
-        # A create server request should fail if the tenant id does not match
-        # the current user
-        # Change the base URL to impersonate another user
-        self.alt_client.auth_provider.set_alt_auth_data(
-            request_part='url',
-            auth_data=self.client.auth_provider.auth_data
-        )
-        self.assertRaises(lib_exc.BadRequest,
-                          self.alt_client.create_server, name='test',
-                          imageRef=self.image['id'], flavorRef=self.flavor_ref)
-
-    @test.idempotent_id('f03d1ded-7fd4-4d29-bc13-e2391f29c625')
-    def test_create_keypair_in_analt_user_tenant(self):
-        """create keypair should not function for alternate tenant
-
-        POST {alt_service_url}/os-keypairs
-
-        Attempt to create a keypair against an alternate tenant by
-        changing using a different tenant's service url. This should
-        return a BadRequest. This tests basic tenant isolation protections.
-
-        NOTE(sdague): if the environment does not use project_id in
-        the service urls, this test is not valid. Skip under these
-        conditions.
-
-        """
-        if self.alt_keypairs_client.base_url == self.keypairs_client.base_url:
-            raise self.skipException("Service urls don't include project_id")
-
-        k_name = data_utils.rand_name('keypair')
-        try:
-            # Change the base URL to impersonate another user
-            self.alt_keypairs_client.auth_provider.set_alt_auth_data(
-                request_part='url',
-                auth_data=self.keypairs_client.auth_provider.auth_data
-            )
-            resp = {}
-            resp['status'] = None
-            self.assertRaises(lib_exc.BadRequest,
-                              self.alt_keypairs_client.create_keypair,
-                              name=k_name)
-        finally:
-            # Next request the base_url is back to normal
-            if (resp['status'] is not None):
-                self.alt_keypairs_client.delete_keypair(k_name)
-                LOG.error("Create keypair request should not happen "
-                          "if the tenant id does not match the current user")
-
-    @test.idempotent_id('85bcdd8f-56b4-4868-ae56-63fbf6f7e405')
-    def test_get_keypair_of_alt_account_fails(self):
-        # A GET request for another user's keypair should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_keypairs_client.show_keypair,
-                          self.keypairname)
-
-    @test.idempotent_id('6d841683-a8e0-43da-a1b8-b339f7692b61')
-    def test_delete_keypair_of_alt_account_fails(self):
-        # A DELETE request for another user's keypair should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_keypairs_client.delete_keypair,
-                          self.keypairname)
-
-    @test.idempotent_id('fcb2e144-36e3-4dfb-9f9f-e72fcdec5656')
-    def test_get_image_for_alt_account_fails(self):
-        # A GET request for an image on another user's account should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_compute_images_client.show_image,
-                          self.image['id'])
-
-    @test.idempotent_id('9facb962-f043-4a9d-b9ee-166a32dea098')
-    def test_delete_image_for_alt_account_fails(self):
-        # A DELETE request for another user's image should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_compute_images_client.delete_image,
-                          self.image['id'])
-
-    @test.idempotent_id('752c917e-83be-499d-a422-3559127f7d3c')
-    def test_create_security_group_in_analt_user_tenant(self):
-        """create security group should not function for alternate tenant
-
-        POST {alt_service_url}/os-security-groups
-
-        Attempt to create a security group against an alternate tenant
-        by changing using a different tenant's service url. This
-        should return a BadRequest. This tests basic tenant isolation
-        protections.
-
-        NOTE(sdague): if the environment does not use project_id in
-        the service urls, this test is not valid. Skip under these
-        conditions.
-
-        """
-        if self.alt_security_client.base_url == self.security_client.base_url:
-            raise self.skipException("Service urls don't include project_id")
-
-        s_name = data_utils.rand_name('security')
-        s_description = data_utils.rand_name('security')
-        try:
-            # Change the base URL to impersonate another user
-            self.alt_security_client.auth_provider.set_alt_auth_data(
-                request_part='url',
-                auth_data=self.security_client.auth_provider.auth_data
-            )
-            resp = {}
-            resp['status'] = None
-            self.assertRaises(lib_exc.BadRequest,
-                              self.alt_security_client.create_security_group,
-                              name=s_name, description=s_description)
-        finally:
-            # Next request the base_url is back to normal
-            if resp['status'] is not None:
-                self.alt_security_client.delete_security_group(resp['id'])
-                LOG.error("Create Security Group request should not happen if"
-                          "the tenant id does not match the current user")
-
-    @test.idempotent_id('9db3590f-4d15-4e5f-985e-b28514919a6f')
-    def test_get_security_group_of_alt_account_fails(self):
-        # A GET request for another user's security group should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_security_client.show_security_group,
-                          self.security_group['id'])
-
-    @test.idempotent_id('155387a5-2bbc-4acf-ab06-698dae537ea5')
-    def test_delete_security_group_of_alt_account_fails(self):
-        # A DELETE request for another user's security group should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_security_client.delete_security_group,
-                          self.security_group['id'])
-
-    @test.idempotent_id('b2b76de0-210a-4089-b921-591c9ec552f6')
-    def test_create_security_group_rule_in_analt_user_tenant(self):
-        """create security group rule should not function for alternate tenant
-
-        POST {alt_service_url}/os-security-group-rules
-
-        Attempt to create a security group rule against an alternate
-        tenant by changing using a different tenant's service
-        url. This should return a BadRequest. This tests basic tenant
-        isolation protections.
-
-        NOTE(sdague): if the environment does not use project_id in
-        the service urls, this test is not valid. Skip under these
-        conditions.
-
-        """
-        if self.alt_security_client.base_url == self.security_client.base_url:
-            raise self.skipException("Service urls don't include project_id")
-
-        parent_group_id = self.security_group['id']
-        ip_protocol = 'icmp'
-        from_port = -1
-        to_port = -1
-        try:
-            # Change the base URL to impersonate another user
-            self.alt_rule_client.auth_provider.set_alt_auth_data(
-                request_part='url',
-                auth_data=self.rule_client.auth_provider.auth_data
-            )
-            resp = {}
-            resp['status'] = None
-            self.assertRaises(lib_exc.BadRequest,
-                              self.alt_rule_client.
-                              create_security_group_rule,
-                              parent_group_id=parent_group_id,
-                              ip_protocol=ip_protocol,
-                              from_port=from_port, to_port=to_port)
-        finally:
-            # Next request the base_url is back to normal
-            if resp['status'] is not None:
-                self.alt_rule_client.delete_security_group_rule(resp['id'])
-                LOG.error("Create security group rule request should not "
-                          "happen if the tenant id does not match the"
-                          " current user")
-
-    @test.idempotent_id('c6044177-37ef-4ce4-b12c-270ddf26d7da')
-    def test_delete_security_group_rule_of_alt_account_fails(self):
-        # A DELETE request for another user's security group rule
-        # should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_rule_client.delete_security_group_rule,
-                          self.rule['id'])
-
-    @test.idempotent_id('c5f52351-53d9-4fc9-83e5-917f7f5e3d71')
-    def test_set_metadata_of_alt_account_server_fails(self):
-        # A set metadata for another user's server should fail
-        req_metadata = {'meta1': 'data1', 'meta2': 'data2'}
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_client.set_server_metadata,
-                          self.server['id'],
-                          req_metadata)
-
-    @test.idempotent_id('fb6f51e9-df15-4939-898d-1aca38c258f0')
-    def test_set_metadata_of_alt_account_image_fails(self):
-        # A set metadata for another user's image should fail
-        req_metadata = {'meta1': 'value1', 'meta2': 'value2'}
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_compute_images_client.set_image_metadata,
-                          self.image['id'], req_metadata)
-
-    @test.idempotent_id('dea1936a-473d-49f2-92ad-97bb7aded22e')
-    def test_get_metadata_of_alt_account_server_fails(self):
-        # A get metadata for another user's server should fail
-        req_metadata = {'meta1': 'data1'}
-        self.client.set_server_metadata(self.server['id'], req_metadata)
-        self.addCleanup(self.client.delete_server_metadata_item,
-                        self.server['id'], 'meta1')
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_client.show_server_metadata_item,
-                          self.server['id'], 'meta1')
-
-    @test.idempotent_id('16b2d724-0d3b-4216-a9fa-97bd4d9cf670')
-    def test_get_metadata_of_alt_account_image_fails(self):
-        # A get metadata for another user's image should fail
-        req_metadata = {'meta1': 'value1'}
-        self.addCleanup(self.compute_images_client.delete_image_metadata_item,
-                        self.image['id'], 'meta1')
-        self.compute_images_client.set_image_metadata(self.image['id'],
-                                                      req_metadata)
-        self.assertRaises(
-            lib_exc.NotFound,
-            self.alt_compute_images_client.show_image_metadata_item,
-            self.image['id'], 'meta1')
-
-    @test.idempotent_id('79531e2e-e721-493c-8b30-a35db36fdaa6')
-    def test_delete_metadata_of_alt_account_server_fails(self):
-        # A delete metadata for another user's server should fail
-        req_metadata = {'meta1': 'data1'}
-        self.addCleanup(self.client.delete_server_metadata_item,
-                        self.server['id'], 'meta1')
-        self.client.set_server_metadata(self.server['id'], req_metadata)
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_client.delete_server_metadata_item,
-                          self.server['id'], 'meta1')
-
-    @test.idempotent_id('a5175dcf-cef8-43d6-9b77-3cb707d62e94')
-    def test_delete_metadata_of_alt_account_image_fails(self):
-        # A delete metadata for another user's image should fail
-        req_metadata = {'meta1': 'data1'}
-        self.addCleanup(self.compute_images_client.delete_image_metadata_item,
-                        self.image['id'], 'meta1')
-        self.compute_images_client.set_image_metadata(self.image['id'],
-                                                      req_metadata)
-        self.assertRaises(
-            lib_exc.NotFound,
-            self.alt_compute_images_client.delete_image_metadata_item,
-            self.image['id'], 'meta1')
-
-    @test.idempotent_id('b0c1e7a0-8853-40fd-8384-01f93d116cae')
-    def test_get_console_output_of_alt_account_server_fails(self):
-        # A Get Console Output for another user's server should fail
-        self.assertRaises(lib_exc.NotFound,
-                          self.alt_client.get_console_output,
-                          self.server['id'], length=10)
diff --git a/tempest/api/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
index f75b867..bdb4383 100644
--- a/tempest/api/database/flavors/test_flavors.py
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.api.database import base
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -58,6 +59,7 @@
     @test.attr(type='smoke')
     @test.idempotent_id('afb2667f-4ec2-4925-bcb7-313fdcffb80d')
     @test.services('compute')
+    @decorators.skip_because(bug='1567134')
     def test_compare_db_flavors_with_os(self):
         db_flavors = self.client.list_db_flavors()['flavors']
         os_flavors = (self.os_flavors_client.list_flavors(detail=True)
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 010e4a0..a3ada21 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -20,12 +20,18 @@
 
 class GroupsV3TestJSON(base.BaseIdentityV3AdminTest):
 
+    @classmethod
+    def resource_setup(cls):
+        super(GroupsV3TestJSON, cls).resource_setup()
+        cls.data.setup_test_domain()
+
     @test.idempotent_id('2e80343b-6c81-4ac3-88c7-452f3e9d5129')
     def test_group_create_update_get(self):
         name = data_utils.rand_name('Group')
         description = data_utils.rand_name('Description')
         group = self.groups_client.create_group(
-            name=name, description=description)['group']
+            name=name, domain_id=self.data.domain['id'],
+            description=description)['group']
         self.addCleanup(self.groups_client.delete_group, group['id'])
         self.assertEqual(group['name'], name)
         self.assertEqual(group['description'], description)
@@ -47,7 +53,8 @@
         name = data_utils.rand_name('Group')
         old_description = data_utils.rand_name('Description')
         group = self.groups_client.create_group(
-            name=name, description=old_description)['group']
+            name=name, domain_id=self.data.domain['id'],
+            description=old_description)['group']
         self.addCleanup(self.groups_client.delete_group, group['id'])
 
         new_name = data_utils.rand_name('UpdateGroup')
@@ -61,7 +68,8 @@
     @test.idempotent_id('1598521a-2f36-4606-8df9-30772bd51339')
     def test_group_users_add_list_delete(self):
         name = data_utils.rand_name('Group')
-        group = self.groups_client.create_group(name=name)['group']
+        group = self.groups_client.create_group(
+            name=name, domain_id=self.data.domain['id'])['group']
         self.addCleanup(self.groups_client.delete_group, group['id'])
         # add user into group
         users = []
@@ -94,7 +102,8 @@
         groups = []
         for i in range(2):
             name = data_utils.rand_name('Group')
-            group = self.groups_client.create_group(name=name)['group']
+            group = self.groups_client.create_group(
+                name=name, domain_id=self.data.domain['id'])['group']
             groups.append(group)
             self.addCleanup(self.groups_client.delete_group, group['id'])
             self.groups_client.add_group_user(group['id'], user['id'])
@@ -112,7 +121,8 @@
             name = data_utils.rand_name('Group')
             description = data_utils.rand_name('Description')
             group = self.groups_client.create_group(
-                name=name, description=description)['group']
+                name=name, domain_id=self.data.domain['id'],
+                description=description)['group']
             self.addCleanup(self.groups_client.delete_group, group['id'])
             group_ids.append(group['id'])
         # List and Verify Groups
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index 6ad374b..baeaa0c 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -28,7 +28,6 @@
     @classmethod
     def setup_clients(cls):
         super(FloatingIPAdminTestJSON, cls).setup_clients()
-        cls.alt_client = cls.alt_manager.network_client
         cls.alt_floating_ips_client = cls.alt_manager.floating_ips_client
 
     @classmethod
@@ -68,7 +67,7 @@
         body = self.floating_ips_client.list_floatingips()
         floating_ip_ids = [f['id'] for f in body['floatingips']]
         # Check that nonadmin user doesn't see floating ip created from admin
-        # and floating ip that is created in another tenant (alt user)
+        # and floating ip that is created in another project (alt user)
         self.assertIn(self.floating_ip['id'], floating_ip_ids)
         self.assertNotIn(floating_ip_admin['floatingip']['id'],
                          floating_ip_ids)
diff --git a/tempest/api/network/admin/test_negative_quotas.py b/tempest/api/network/admin/test_negative_quotas.py
index c1cdbf2..7b037d5 100644
--- a/tempest/api/network/admin/test_negative_quotas.py
+++ b/tempest/api/network/admin/test_negative_quotas.py
@@ -24,7 +24,7 @@
         set network quota and exceed this quota
 
     v2.0 of the API is assumed.
-    It is also assumed that the per-tenant quota extension API is configured
+    It is also assumed that the per-project quota extension API is configured
     in /etc/neutron/neutron.conf as follows:
 
         quota_driver = neutron.db.quota_db.DbQuotaDriver
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index d72e960..ea3d59a 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -24,13 +24,13 @@
 class QuotasTest(base.BaseAdminNetworkTest):
     """Tests the following operations in the Neutron API:
 
-        list quotas for tenants who have non-default quota values
-        show quotas for a specified tenant
-        update quotas for a specified tenant
-        reset quotas to default values for a specified tenant
+        list quotas for projects who have non-default quota values
+        show quotas for a specified project
+        update quotas for a specified project
+        reset quotas to default values for a specified project
 
     v2.0 of the API is assumed.
-    It is also assumed that the per-tenant quota extension API is configured
+    It is also assumed that the per-project quota extension API is configured
     in /etc/neutron/neutron.conf as follows:
 
         quota_driver = neutron.db.quota_db.DbQuotaDriver
@@ -49,7 +49,7 @@
         cls.identity_admin_client = cls.os_adm.identity_client
 
     def _check_quotas(self, new_quotas):
-        # Add a tenant to conduct the test
+        # Add a project to conduct the test
         project = data_utils.rand_name('test_project_')
         description = data_utils.rand_name('desc_')
         project = self.identity_utils.create_project(name=project,
@@ -57,14 +57,14 @@
         project_id = project['id']
         self.addCleanup(self.identity_utils.delete_project, project_id)
 
-        # Change quotas for tenant
+        # Change quotas for project
         quota_set = self.admin_quotas_client.update_quotas(
             project_id, **new_quotas)['quota']
         self.addCleanup(self._cleanup_quotas, project_id)
         for key, value in six.iteritems(new_quotas):
             self.assertEqual(value, quota_set[key])
 
-        # Confirm our tenant is listed among tenants with non default quotas
+        # Confirm our project is listed among projects with non default quotas
         non_default_quotas = self.admin_quotas_client.list_quotas()
         found = False
         for qs in non_default_quotas['quotas']:
@@ -72,7 +72,7 @@
                 found = True
         self.assertTrue(found)
 
-        # Confirm from API quotas were changed as requested for tenant
+        # Confirm from API quotas were changed as requested for project
         quota_set = self.admin_quotas_client.show_quotas(project_id)
         quota_set = quota_set['quota']
         for key, value in six.iteritems(new_quotas):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 71edf74..9823345 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -32,11 +32,11 @@
     Therefore, v2.x of the Neutron API is assumed. It is also assumed that the
     following options are defined in the [network] section of etc/tempest.conf:
 
-        tenant_network_cidr with a block of cidr's from which smaller blocks
-        can be allocated for tenant networks
+        project_network_cidr with a block of cidr's from which smaller blocks
+        can be allocated for project networks
 
-        tenant_network_mask_bits with the mask bits to be used to partition the
-        block defined by tenant-network_cidr
+        project_network_mask_bits with the mask bits to be used to partition
+        the block defined by project-network_cidr
 
     Finally, it is assumed that the following option is defined in the
     [service_available] section of etc/tempest.conf
@@ -67,7 +67,6 @@
     @classmethod
     def setup_clients(cls):
         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
@@ -176,12 +175,12 @@
         ip_version = ip_version if ip_version is not None else cls._ip_version
         gateway_not_set = gateway == ''
         if ip_version == 4:
-            cidr = cidr or netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-            mask_bits = mask_bits or CONF.network.tenant_network_mask_bits
+            cidr = cidr or netaddr.IPNetwork(CONF.network.project_network_cidr)
+            mask_bits = mask_bits or CONF.network.project_network_mask_bits
         elif ip_version == 6:
-            cidr = (
-                cidr or netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr))
-            mask_bits = mask_bits or CONF.network.tenant_network_v6_mask_bits
+            cidr = (cidr or
+                    netaddr.IPNetwork(CONF.network.project_network_v6_cidr))
+            mask_bits = mask_bits or CONF.network.project_network_v6_mask_bits
         # Find a cidr that is not in use yet and create a subnet with it
         for subnet_cidr in cidr.subnet(mask_bits):
             if gateway_not_set:
@@ -276,7 +275,6 @@
     @classmethod
     def setup_clients(cls):
         super(BaseAdminNetworkTest, cls).setup_clients()
-        cls.admin_client = cls.os_adm.network_client
         cls.admin_agents_client = cls.os_adm.network_agents_client
         cls.admin_networks_client = cls.os_adm.networks_client
         cls.admin_routers_client = cls.os_adm.routers_client
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index 394aec1..b2892e5 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -100,7 +100,7 @@
     @test.idempotent_id('4d6d178f-34f6-4bff-a01c-0a2f8fe909e4')
     def test_update_port_with_cidr_address_pair(self):
         # Update allowed address pair with cidr
-        cidr = str(netaddr.IPNetwork(CONF.network.tenant_network_cidr))
+        cidr = str(netaddr.IPNetwork(CONF.network.project_network_cidr))
         self._update_port_with_address(cidr)
 
     @test.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index d71d600..2c981a1 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -31,7 +31,7 @@
     @test.attr(type='smoke')
     @test.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
     def test_list_show_extensions(self):
-        # List available extensions for the tenant
+        # List available extensions for the project
         expected_alias = ['security-group', 'l3_agent_scheduler',
                           'ext-gw-mode', 'binding', 'quotas',
                           'agent', 'dhcp_agent_scheduler', 'provider',
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index fa1ed6a..b6f9da7 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -29,12 +29,12 @@
 class NetworksTest(base.BaseNetworkTest):
     """Tests the following operations in the Neutron API:
 
-        create a network for a tenant
-        list tenant's networks
-        show a tenant network details
-        create a subnet for a tenant
-        list tenant's subnets
-        show a tenant subnet details
+        create a network for a project
+        list project's networks
+        show a project network details
+        create a subnet for a project
+        list project's subnets
+        show a project subnet details
         network update
         subnet update
         delete a network also deletes its subnets
@@ -45,15 +45,15 @@
     v2.0 of the Neutron API is assumed. It is also assumed that the following
     options are defined in the [network] section of etc/tempest.conf:
 
-        tenant_network_cidr with a block of cidr's from which smaller blocks
-        can be allocated for tenant ipv4 subnets
+        project_network_cidr with a block of cidr's from which smaller blocks
+        can be allocated for project ipv4 subnets
 
-        tenant_network_v6_cidr is the equivalent for ipv6 subnets
+        project_network_v6_cidr is the equivalent for ipv6 subnets
 
-        tenant_network_mask_bits with the mask bits to be used to partition the
-        block defined by tenant_network_cidr
+        project_network_mask_bits with the mask bits to be used to partition
+        the block defined by project_network_cidr
 
-        tenant_network_v6_mask_bits is the equivalent for ipv6 subnets
+        project_network_v6_mask_bits is the equivalent for ipv6 subnets
     """
 
     @classmethod
@@ -92,14 +92,14 @@
 
     @classmethod
     def _create_subnet_with_last_subnet_block(cls, network, ip_version):
-        # Derive last subnet CIDR block from tenant CIDR and
+        # Derive last subnet CIDR block from project CIDR and
         # create the subnet with that derived CIDR
         if ip_version == 4:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-            mask_bits = CONF.network.tenant_network_mask_bits
+            cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+            mask_bits = CONF.network.project_network_mask_bits
         elif ip_version == 6:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
-            mask_bits = CONF.network.tenant_network_v6_mask_bits
+            cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
+            mask_bits = CONF.network.project_network_v6_mask_bits
 
         subnet_cidr = list(cidr.subnet(mask_bits))[-1]
         gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
@@ -110,11 +110,11 @@
     def _get_gateway_from_tempest_conf(cls, ip_version):
         """Return first subnet gateway for configured CIDR """
         if ip_version == 4:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-            mask_bits = CONF.network.tenant_network_mask_bits
+            cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+            mask_bits = CONF.network.project_network_mask_bits
         elif ip_version == 6:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
-            mask_bits = CONF.network.tenant_network_v6_mask_bits
+            cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
+            mask_bits = CONF.network.project_network_v6_mask_bits
 
         if mask_bits >= cidr.prefixlen:
             return netaddr.IPAddress(cidr) + 1
@@ -403,16 +403,16 @@
         bulk network creation
         bulk subnet creation
         bulk port creation
-        list tenant's networks
+        list project's networks
 
     v2.0 of the Neutron API is assumed. It is also assumed that the following
     options are defined in the [network] section of etc/tempest.conf:
 
-        tenant_network_cidr with a block of cidr's from which smaller blocks
-        can be allocated for tenant networks
+        project_network_cidr with a block of cidr's from which smaller blocks
+        can be allocated for project networks
 
-        tenant_network_mask_bits with the mask bits to be used to partition the
-        block defined by tenant-network_cidr
+        project_network_mask_bits with the mask bits to be used to partition
+        the block defined by project-network_cidr
     """
 
     def _delete_networks(self, created_networks):
@@ -464,11 +464,11 @@
         networks = [self.create_network(), self.create_network()]
         # Creates 2 subnets in one request
         if self._ip_version == 4:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-            mask_bits = CONF.network.tenant_network_mask_bits
+            cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+            mask_bits = CONF.network.project_network_mask_bits
         else:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
-            mask_bits = CONF.network.tenant_network_v6_mask_bits
+            cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
+            mask_bits = CONF.network.project_network_v6_mask_bits
 
         cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
 
@@ -529,7 +529,7 @@
 
     @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
     def test_create_delete_subnet_with_gw(self):
-        net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+        net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
         gateway = str(netaddr.IPAddress(net.first + 2))
         name = data_utils.rand_name('network-')
         network = self.create_network(network_name=name)
@@ -539,7 +539,7 @@
 
     @test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
     def test_create_delete_subnet_with_default_gw(self):
-        net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+        net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
         gateway_ip = str(netaddr.IPAddress(net.first + 1))
         name = data_utils.rand_name('network-')
         network = self.create_network(network_name=name)
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index e302284..caf7f14 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -90,12 +90,12 @@
     def _get_ipaddress_from_tempest_conf(cls):
         """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
+            cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+            cidr.prefixlen = CONF.network.project_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
+            cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
+            cidr.prefixlen = CONF.network.project_network_v6_mask_bits
 
         return cidr
 
@@ -428,11 +428,7 @@
 
 class PortsIpV6TestJSON(PortsTestJSON):
     _ip_version = 6
-    _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
-    _tenant_network_mask_bits = CONF.network.tenant_network_v6_mask_bits
 
 
 class PortsAdminExtendedAttrsIpV6TestJSON(PortsAdminExtendedAttrsTestJSON):
     _ip_version = 6
-    _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
-    _tenant_network_mask_bits = CONF.network.tenant_network_v6_mask_bits
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 11f7fc6..3654b2e 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -41,9 +41,9 @@
     @classmethod
     def resource_setup(cls):
         super(RoutersTest, cls).resource_setup()
-        cls.tenant_cidr = (CONF.network.tenant_network_cidr
+        cls.tenant_cidr = (CONF.network.project_network_cidr
                            if cls._ip_version == 4 else
-                           CONF.network.tenant_network_v6_cidr)
+                           CONF.network.project_network_v6_cidr)
 
     @test.attr(type='smoke')
     @test.idempotent_id('f64403e2-8483-4b34-8ccd-b09a87bcc68c')
@@ -274,7 +274,7 @@
     @test.requires_ext(extension='extraroute', service='network')
     def test_update_delete_extra_route(self):
         # Create different cidr for each subnet to avoid cidr duplicate
-        # The cidr starts from tenant_cidr
+        # The cidr starts from project_cidr
         next_cidr = netaddr.IPNetwork(self.tenant_cidr)
         # Prepare to build several routes
         test_routes = []
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 36aaf2d..cd9f6ad 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -39,9 +39,9 @@
         cls.router = cls.create_router(data_utils.rand_name('router-'))
         cls.network = cls.create_network()
         cls.subnet = cls.create_subnet(cls.network)
-        cls.tenant_cidr = (CONF.network.tenant_network_cidr
+        cls.tenant_cidr = (CONF.network.project_network_cidr
                            if cls._ip_version == 4 else
-                           CONF.network.tenant_network_v6_cidr)
+                           CONF.network.project_network_v6_cidr)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('37a94fc0-a834-45b9-bd23-9a81d2fd1e22')
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 7d0765e..5312979 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -24,7 +24,7 @@
 
 
 class SecGroupTest(base.BaseSecGroupTest):
-    _tenant_network_cidr = CONF.network.tenant_network_cidr
+    _project_network_cidr = CONF.network.project_network_cidr
 
     @classmethod
     def skip_checks(cls):
@@ -71,7 +71,7 @@
     @test.attr(type='smoke')
     @test.idempotent_id('e30abd17-fef9-4739-8617-dc26da88e686')
     def test_list_security_groups(self):
-        # Verify the that security group belonging to tenant exist in list
+        # Verify the that security group belonging to project exist in list
         body = self.security_groups_client.list_security_groups()
         security_groups = body['security_groups']
         found = None
@@ -210,7 +210,7 @@
         protocol = 'tcp'
         port_range_min = 76
         port_range_max = 77
-        ip_prefix = self._tenant_network_cidr
+        ip_prefix = self._project_network_cidr
         self._create_verify_security_group_rule(sg_id, direction,
                                                 self.ethertype, protocol,
                                                 port_range_min,
@@ -239,4 +239,4 @@
 
 class SecGroupIPv6Test(SecGroupTest):
     _ip_version = 6
-    _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
+    _project_network_cidr = CONF.network.project_network_v6_cidr
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index 401fa3b..86d0b46 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -24,7 +24,7 @@
 
 
 class NegativeSecGroupTest(base.BaseSecGroupTest):
-    _tenant_network_cidr = CONF.network.tenant_network_cidr
+    _project_network_cidr = CONF.network.project_network_cidr
 
     @classmethod
     def skip_checks(cls):
@@ -110,7 +110,7 @@
         sg2_body, _ = self._create_security_group()
 
         # Create rule specifying both remote_ip_prefix and remote_group_id
-        prefix = self._tenant_network_cidr
+        prefix = self._project_network_cidr
         self.assertRaises(
             lib_exc.BadRequest,
             self.security_group_rules_client.create_security_group_rule,
@@ -214,7 +214,7 @@
 
 class NegativeSecGroupIPv6Test(NegativeSecGroupTest):
     _ip_version = 6
-    _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
+    _project_network_cidr = CONF.network.project_network_v6_cidr
 
     @test.attr(type=['negative'])
     @test.idempotent_id('7607439c-af73-499e-bf64-f687fd12a842')
@@ -223,9 +223,9 @@
 
         # Create rule with bad remote_ip_prefix
         pairs = ({'ethertype': 'IPv6',
-                  'ip_prefix': CONF.network.tenant_network_cidr},
+                  'ip_prefix': CONF.network.project_network_cidr},
                  {'ethertype': 'IPv4',
-                  'ip_prefix': CONF.network.tenant_network_v6_cidr})
+                  'ip_prefix': CONF.network.project_network_v6_cidr})
         for pair in pairs:
             self.assertRaisesRegex(
                 lib_exc.BadRequest,
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 26ace81..d813263 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -46,7 +46,6 @@
         cls.client = cls.orchestration_client
         cls.servers_client = cls.os.servers_client
         cls.keypairs_client = cls.os.keypairs_client
-        cls.network_client = cls.os.network_client
         cls.networks_client = cls.os.networks_client
         cls.volumes_client = cls.os.volumes_client
         cls.images_v2_client = cls.os.image_client_v2
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 5483361..3f45634 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -44,7 +44,6 @@
     @classmethod
     def setup_clients(cls):
         super(NeutronResourcesTestJSON, cls).setup_clients()
-        cls.network_client = cls.os.network_client
         cls.subnets_client = cls.os.subnets_client
         cls.ports_client = cls.os.ports_client
 
@@ -58,8 +57,8 @@
                             cls._create_keypair()['name'])
         cls.external_network_id = CONF.network.public_network_id
 
-        tenant_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-        mask_bits = CONF.network.tenant_network_mask_bits
+        tenant_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+        mask_bits = CONF.network.project_network_mask_bits
         cls.subnet_cidr = tenant_cidr.subnet(mask_bits).next()
 
         # create the stack
diff --git a/tempest/api_schema/response/__init__.py b/tempest/api_schema/response/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api_schema/response/__init__.py
+++ /dev/null
diff --git a/tempest/api_schema/response/compute/__init__.py b/tempest/api_schema/response/compute/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api_schema/response/compute/__init__.py
+++ /dev/null
diff --git a/tempest/api_schema/response/compute/v2_1/__init__.py b/tempest/api_schema/response/compute/v2_1/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api_schema/response/compute/v2_1/__init__.py
+++ /dev/null
diff --git a/tempest/api_schema/response/compute/v2_1/keypairs.py b/tempest/api_schema/response/compute/v2_1/keypairs.py
deleted file mode 100644
index 9c04c79..0000000
--- a/tempest/api_schema/response/compute/v2_1/keypairs.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright 2014 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-get_keypair = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'keypair': {
-                'type': 'object',
-                'properties': {
-                    'public_key': {'type': 'string'},
-                    'name': {'type': 'string'},
-                    'fingerprint': {'type': 'string'},
-                    'user_id': {'type': 'string'},
-                    'deleted': {'type': 'boolean'},
-                    'created_at': {'type': 'string'},
-                    'updated_at': {'type': ['string', 'null']},
-                    'deleted_at': {'type': ['string', 'null']},
-                    'id': {'type': 'integer'}
-
-                },
-                'additionalProperties': False,
-                # When we run the get keypair API, response body includes
-                # all the above mentioned attributes.
-                # But in Nova API sample file, response body includes only
-                # 'public_key', 'name' & 'fingerprint'. So only 'public_key',
-                # 'name' & 'fingerprint' are defined as 'required'.
-                'required': ['public_key', 'name', 'fingerprint']
-            }
-        },
-        'additionalProperties': False,
-        'required': ['keypair']
-    }
-}
-
-create_keypair = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'keypair': {
-                'type': 'object',
-                'properties': {
-                    'fingerprint': {'type': 'string'},
-                    'name': {'type': 'string'},
-                    'public_key': {'type': 'string'},
-                    'user_id': {'type': 'string'},
-                    'private_key': {'type': 'string'}
-                },
-                'additionalProperties': False,
-                # When create keypair API is being called with 'Public key'
-                # (Importing keypair) then, response body does not contain
-                # 'private_key' So it is not defined as 'required'
-                'required': ['fingerprint', 'name', 'public_key', 'user_id']
-            }
-        },
-        'additionalProperties': False,
-        'required': ['keypair']
-    }
-}
-
-delete_keypair = {
-    'status_code': [202],
-}
-
-list_keypairs = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'keypairs': {
-                'type': 'array',
-                'items': {
-                    'type': 'object',
-                    'properties': {
-                        'keypair': {
-                            'type': 'object',
-                            'properties': {
-                                'public_key': {'type': 'string'},
-                                'name': {'type': 'string'},
-                                'fingerprint': {'type': 'string'}
-                            },
-                            'additionalProperties': False,
-                            'required': ['public_key', 'name', 'fingerprint']
-                        }
-                    },
-                    'additionalProperties': False,
-                    'required': ['keypair']
-                }
-            }
-        },
-        'additionalProperties': False,
-        'required': ['keypairs']
-    }
-}
diff --git a/tempest/clients.py b/tempest/clients.py
index fc0cc89..0eded8b 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -46,6 +46,7 @@
 from tempest.lib.services.compute.instance_usage_audit_log_client import \
     InstanceUsagesAuditLogClient
 from tempest.lib.services.compute.interfaces_client import InterfacesClient
+from tempest.lib.services.compute.keypairs_client import KeyPairsClient
 from tempest.lib.services.compute.limits_client import LimitsClient
 from tempest.lib.services.compute.migrations_client import MigrationsClient
 from tempest.lib.services.compute.networks_client import NetworksClient \
@@ -96,7 +97,6 @@
 from tempest import manager
 from tempest.services.baremetal.v1.json.baremetal_client import \
     BaremetalClient
-from tempest.services.compute.json.keypairs_client import KeyPairsClient
 from tempest.services.data_processing.v1_1.data_processing_client import \
     DataProcessingClient
 from tempest.services.database.json.flavors_client import \
@@ -132,7 +132,6 @@
     UsersClient as UsersV3Client
 from tempest.services.image.v1.json.images_client import ImagesClient
 from tempest.services.image.v2.json.images_client import ImagesClientV2
-from tempest.services.network.json.network_client import NetworkClient
 from tempest.services.network.json.routers_client import RoutersClient
 from tempest.services.object_storage.account_client import AccountClient
 from tempest.services.object_storage.container_client import ContainerClient
@@ -237,14 +236,6 @@
             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,
-            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.networks_client = NetworksClient(
             self.auth_provider,
             CONF.network.catalog_type,
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 6124676..a154d0b 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -103,7 +103,6 @@
 from tempest.services.identity.v2.json import roles_client
 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 routers_client
 
 LOG = None
@@ -170,7 +169,6 @@
         endpoint_type='adminURL',
         **params
     )
-    network_admin = None
     networks_admin = None
     routers_admin = None
     subnets_admin = None
@@ -178,12 +176,6 @@
     if (CONF.service_available.neutron and
         CONF.auth.create_isolated_networks):
         neutron_iso_networks = True
-        network_admin = network_client.NetworkClient(
-            _auth,
-            CONF.network.catalog_type,
-            CONF.network.region or CONF.identity.region,
-            endpoint_type='adminURL',
-            **params)
         networks_admin = networks_client.NetworksClient(
             _auth,
             CONF.network.catalog_type,
@@ -203,13 +195,13 @@
             endpoint_type='adminURL',
             **params)
     return (identity_admin, tenants_admin, roles_admin, users_admin,
-            neutron_iso_networks, network_admin, networks_admin, routers_admin,
+            neutron_iso_networks, networks_admin, routers_admin,
             subnets_admin)
 
 
 def create_resources(opts, resources):
     (identity_admin, tenants_admin, roles_admin, users_admin,
-     neutron_iso_networks, network_admin, networks_admin, routers_admin,
+     neutron_iso_networks, networks_admin, routers_admin,
      subnets_admin) = get_admin_clients(opts)
     roles = roles_admin.list_roles()['roles']
     for u in resources['users']:
@@ -255,7 +247,7 @@
         for u in resources['users']:
             tenant = identity.get_tenant_by_name(tenants_admin, u['tenant'])
             network_name, router_name = create_network_resources(
-                network_admin, networks_admin, routers_admin, subnets_admin,
+                networks_admin, routers_admin, subnets_admin,
                 tenant['id'], u['name'])
             u['network'] = network_name
             u['router'] = router_name
@@ -282,7 +274,7 @@
     LOG.info('Resources deployed successfully!')
 
 
-def create_network_resources(network_admin_client, networks_admin_client,
+def create_network_resources(networks_admin_client,
                              routers_admin_client, subnets_admin_client,
                              tenant_id, name):
 
@@ -292,8 +284,8 @@
         return resp_body['network']
 
     def _create_subnet(subnet_name, network_id):
-        base_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-        mask_bits = CONF.network.tenant_network_mask_bits
+        base_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+        mask_bits = CONF.network.project_network_mask_bits
         for subnet_cidr in base_cidr.subnet(mask_bits):
             try:
                 resp_body = subnets_admin_client.\
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index 3706b54..caba4b5 100644
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -190,7 +190,7 @@
         rl_cl = self.admin_mgr.roles_client
 
         tenant = identity.get_tenant_by_name(tn_cl,
-                                             CONF.auth.admin_tenant_name)
+                                             CONF.auth.admin_project_name)
         self.admin_tenant_id = tenant['id']
 
         user = identity.get_user_by_username(tn_cl, self.admin_tenant_id,
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 99933dd..f51fc53 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -33,7 +33,7 @@
 CONF_TENANTS = None
 CONF_USERS = None
 
-IS_CEILOMETER = None
+IS_AODH = None
 IS_CINDER = None
 IS_GLANCE = None
 IS_HEAT = None
@@ -51,14 +51,14 @@
     global CONF_PUB_ROUTER
     global CONF_TENANTS
     global CONF_USERS
-    global IS_CEILOMETER
+    global IS_AODH
     global IS_CINDER
     global IS_GLANCE
     global IS_HEAT
     global IS_NEUTRON
     global IS_NOVA
 
-    IS_CEILOMETER = CONF.service_available.ceilometer
+    IS_AODH = CONF.service_available.aodh
     IS_CINDER = CONF.service_available.cinder
     IS_GLANCE = CONF.service_available.glance
     IS_HEAT = CONF.service_available.heat
@@ -70,25 +70,25 @@
     CONF_PRIV_NETWORK_NAME = CONF.compute.fixed_network_name
     CONF_PUB_NETWORK = CONF.network.public_network_id
     CONF_PUB_ROUTER = CONF.network.public_router_id
-    CONF_TENANTS = [CONF.auth.admin_tenant_name,
-                    CONF.identity.tenant_name,
-                    CONF.identity.alt_tenant_name]
+    CONF_TENANTS = [CONF.auth.admin_project_name,
+                    CONF.identity.project_name,
+                    CONF.identity.alt_project_name]
     CONF_USERS = [CONF.auth.admin_username, CONF.identity.username,
                   CONF.identity.alt_username]
 
     if IS_NEUTRON:
         CONF_PRIV_NETWORK = _get_network_id(CONF.compute.fixed_network_name,
-                                            CONF.auth.admin_tenant_name)
+                                            CONF.auth.admin_project_name)
         CONF_NETWORKS = [CONF_PUB_NETWORK, CONF_PRIV_NETWORK]
 
 
-def _get_network_id(net_name, tenant_name):
+def _get_network_id(net_name, project_name):
     am = credentials.AdminManager()
     net_cl = am.networks_client
     tn_cl = am.tenants_client
 
     networks = net_cl.list_networks()
-    tenant = identity.get_tenant_by_name(tn_cl, tenant_name)
+    tenant = identity.get_tenant_by_name(tn_cl, project_name)
     t_id = tenant['id']
     n_id = None
     for net in networks['networks']:
@@ -382,7 +382,6 @@
 class NetworkService(BaseService):
     def __init__(self, manager, **kwargs):
         super(NetworkService, self).__init__(kwargs)
-        self.client = manager.network_client
         self.networks_client = manager.networks_client
         self.subnets_client = manager.subnets_client
         self.ports_client = manager.ports_client
@@ -711,7 +710,7 @@
 class TelemetryAlarmService(BaseService):
     def __init__(self, manager, **kwargs):
         super(TelemetryAlarmService, self).__init__(kwargs)
-        self.client = manager.telemetry_client
+        self.client = manager.alarming_client
 
     def list(self):
         client = self.client
@@ -910,7 +909,7 @@
         if not self.is_save_state:
             tenants = [tenant for tenant in tenants if (tenant['id']
                        not in self.saved_state_json['tenants'].keys()
-                       and tenant['name'] != CONF.auth.admin_tenant_name)]
+                       and tenant['name'] != CONF.auth.admin_project_name)]
 
         if self.is_preserve:
             tenants = [tenant for tenant in tenants if tenant['name']
@@ -977,7 +976,7 @@
 
 def get_tenant_cleanup_services():
     tenant_services = []
-    if IS_CEILOMETER:
+    if IS_AODH:
         tenant_services.append(TelemetryAlarmService)
     if IS_NOVA:
         tenant_services.append(ServerService)
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index e3c1c64..2a4e314 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -127,6 +127,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 networks_client
 from tempest.lib.services.network import ports_client
 from tempest.lib.services.network import subnets_client
 from tempest.services.identity.v2.json import identity_client
@@ -134,7 +135,6 @@
 from tempest.services.identity.v2.json import tenants_client
 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 routers_client
 from tempest.services.object_storage import container_client
 from tempest.services.object_storage import object_client
@@ -264,7 +264,7 @@
             build_interval=CONF.volume.build_interval,
             build_timeout=CONF.volume.build_timeout,
             **default_params)
-        self.networks = network_client.NetworkClient(
+        self.networks = networks_client.NetworksClient(
             _auth,
             CONF.network.catalog_type,
             CONF.network.region or CONF.identity.region,
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 0ca14a9..58157ef 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -256,7 +256,7 @@
 
     if credential_type not in CREDENTIAL_TYPES:
         raise exceptions.InvalidCredentials()
-    conf_attributes = ['username', 'password', 'tenant_name']
+    conf_attributes = ['username', 'password', 'project_name']
 
     if identity_version == 'v3':
         conf_attributes.append('domain_name')
@@ -269,6 +269,11 @@
             params[attr] = getattr(_section, attr)
         else:
             params[attr] = getattr(_section, prefix + "_" + attr)
+    # NOTE(andreaf) v2 API still uses tenants, so we must translate project
+    # to tenant before building the Credentials object
+    if identity_version == 'v2':
+        params['tenant_name'] = params.get('project_name')
+        params.pop('project_name', None)
     # Build and validate credentials. We are reading configured credentials,
     # so validate them even if fill_in is False
     credentials = get_credentials(fill_in=fill_in,
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 5f6c8b8..d374be4 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -62,7 +62,6 @@
          self.users_admin_client,
          self.roles_admin_client,
          self.domains_admin_client,
-         self.network_admin_client,
          self.networks_admin_client,
          self.routers_admin_client,
          self.subnets_admin_client,
@@ -93,13 +92,13 @@
         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, None, os.network_client,
+                    os.roles_client, None,
                     os.networks_client, os.routers_client, os.subnets_client,
                     os.ports_client, os.security_groups_client)
         else:
             return (os.identity_v3_client, os.projects_client,
                     os.users_v3_client, os.roles_v3_client, os.domains_client,
-                    os.network_client, os.networks_client, os.routers_client,
+                    os.networks_client, os.routers_client,
                     os.subnets_client, os.ports_client,
                     os.security_groups_client)
 
@@ -208,8 +207,8 @@
         return resp_body['network']
 
     def _create_subnet(self, subnet_name, tenant_id, network_id):
-        base_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-        mask_bits = CONF.network.tenant_network_mask_bits
+        base_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+        mask_bits = CONF.network.project_network_mask_bits
         for subnet_cidr in base_cidr.subnet(mask_bits):
             try:
                 if self.network_resources:
diff --git a/tempest/common/preprov_creds.py b/tempest/common/preprov_creds.py
index 97cc2ec..f3df387 100644
--- a/tempest/common/preprov_creds.py
+++ b/tempest/common/preprov_creds.py
@@ -331,6 +331,7 @@
     def _wrap_creds_with_network(self, hash):
         creds_dict = self.hash_dict['creds'][hash]
         # Make sure a domain scope if defined for users in case of V3
+        # Make sure a tenant is available in case of V2
         creds_dict = self._extend_credentials(creds_dict)
         # This just builds a Credentials object, it does not validate
         # nor fill  with missing fields.
@@ -356,4 +357,17 @@
             user_domain_fields = set(['user_domain_name', 'user_domain_id'])
             if not user_domain_fields.intersection(set(creds_dict.keys())):
                 creds_dict['user_domain_name'] = self.credentials_domain
+        # NOTE(andreaf) In case of v2, replace project with tenant if project
+        # is provided and tenant is not
+        if self.identity_version == 'v2':
+            if ('project_name' in creds_dict and
+                    'tenant_name' in creds_dict and
+                    creds_dict['project_name'] != creds_dict['tenant_name']):
+                clean_creds = self._sanitize_creds(creds_dict)
+                msg = 'Cannot specify project and tenant at the same time %s'
+                raise exceptions.InvalidCredentials(msg % clean_creds)
+            if ('project_name' in creds_dict and
+                    'tenant_name' not in creds_dict):
+                creds_dict['tenant_name'] = creds_dict['project_name']
+                creds_dict.pop('project_name')
         return creds_dict
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 36e3e3a..3a215a0 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -118,7 +118,7 @@
 
     def assign_static_ip(self, nic, addr):
         cmd = "sudo ip addr add {ip}/{mask} dev {nic}".format(
-            ip=addr, mask=CONF.network.tenant_network_mask_bits,
+            ip=addr, mask=CONF.network.project_network_mask_bits,
             nic=nic
         )
         return self.exec_command(cmd)
diff --git a/tempest/config.py b/tempest/config.py
index 4c3b04b..b787b19 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -56,7 +56,7 @@
                     "number of concurrent test processes."),
     cfg.BoolOpt('use_dynamic_credentials',
                 default=True,
-                help="Allows test cases to create/destroy tenants and "
+                help="Allows test cases to create/destroy projects and "
                      "users. This option requires that OpenStack Identity "
                      "API admin credentials are known. If false, isolated "
                      "test cases and parallel execution, can still be "
@@ -81,23 +81,26 @@
                 default=True,
                 help="If use_dynamic_credentials is set to True and Neutron "
                      "is enabled Tempest will try to create a usable network, "
-                     "subnet, and router when needed for each tenant it "
+                     "subnet, and router when needed for each project it "
                      "creates. However in some neutron configurations, like "
                      "with VLAN provider networks, this doesn't work. So if "
                      "set to False the isolated networks will not be created"),
     cfg.StrOpt('admin_username',
                help="Username for an administrative user. This is needed for "
-                    "authenticating requests made by tenant isolation to "
+                    "authenticating requests made by project isolation to "
                     "create users and projects",
                deprecated_group='identity'),
-    cfg.StrOpt('admin_tenant_name',
-               help="Tenant name to use for an  administrative user. This is "
-                    "needed for authenticating requests made by tenant "
+    cfg.StrOpt('admin_project_name',
+               help="Project name to use for an  administrative user. This is "
+                    "needed for authenticating requests made by project "
                     "isolation to create users and projects",
-               deprecated_group='identity'),
+               deprecated_opts=[cfg.DeprecatedOpt('admin_tenant_name',
+                                                  group='auth'),
+                                cfg.DeprecatedOpt('admin_tenant_name',
+                                                  group='identity')]),
     cfg.StrOpt('admin_password',
                help="Password to use for an  administrative user. This is "
-                    "needed for authenticating requests made by tenant "
+                    "needed for authenticating requests made by project "
                     "isolation to create users and projects",
                secret=True,
                deprecated_group='identity'),
@@ -158,8 +161,9 @@
     cfg.StrOpt('username',
                help="Username to use for Nova API requests.",
                deprecated_for_removal=True),
-    cfg.StrOpt('tenant_name',
-               help="Tenant name to use for Nova API requests.",
+    cfg.StrOpt('project_name',
+               deprecated_name='tenant_name',
+               help="Project name to use for Nova API requests.",
                deprecated_for_removal=True),
     cfg.StrOpt('admin_role',
                default='admin',
@@ -176,8 +180,9 @@
                help="Username of alternate user to use for Nova API "
                     "requests.",
                deprecated_for_removal=True),
-    cfg.StrOpt('alt_tenant_name',
-               help="Alternate user's Tenant name to use for Nova API "
+    cfg.StrOpt('alt_project_name',
+               deprecated_name='alt_tenant_name',
+               help="Alternate user's Project name to use for Nova API "
                     "requests.",
                deprecated_for_removal=True),
     cfg.StrOpt('alt_password',
@@ -246,10 +251,10 @@
                     "no OS-EXT-STS extension available"),
     cfg.StrOpt('fixed_network_name',
                help="Name of the fixed network that is visible to all test "
-                    "tenants. If multiple networks are available for a tenant"
-                    " this is the network which will be used for creating "
-                    "servers if tempest does not create a network or a "
-                    "network is not specified elsewhere. It may be used for "
+                    "projects. If multiple networks are available for a "
+                    "project, this is the network which will be used for "
+                    "creating servers if tempest does not create a network or "
+                    "s network is not specified elsewhere. It may be used for "
                     "ssh validation only if floating IPs are disabled."),
     cfg.StrOpt('catalog_type',
                default='compute',
@@ -493,21 +498,26 @@
                choices=['public', 'admin', 'internal',
                         'publicURL', 'adminURL', 'internalURL'],
                help="The endpoint type to use for the network service."),
-    cfg.StrOpt('tenant_network_cidr',
+    cfg.StrOpt('project_network_cidr',
+               deprecated_name='tenant_network_cidr',
                default="10.100.0.0/16",
-               help="The cidr block to allocate tenant ipv4 subnets from"),
-    cfg.IntOpt('tenant_network_mask_bits',
+               help="The cidr block to allocate project ipv4 subnets from"),
+    cfg.IntOpt('project_network_mask_bits',
+               deprecated_name='tenant_network_mask_bits',
                default=28,
-               help="The mask bits for tenant ipv4 subnets"),
-    cfg.StrOpt('tenant_network_v6_cidr',
+               help="The mask bits for project ipv4 subnets"),
+    cfg.StrOpt('project_network_v6_cidr',
+               deprecated_name='tenant_network_v6_cidr',
                default="2003::/48",
-               help="The cidr block to allocate tenant ipv6 subnets from"),
-    cfg.IntOpt('tenant_network_v6_mask_bits',
+               help="The cidr block to allocate project ipv6 subnets from"),
+    cfg.IntOpt('project_network_v6_mask_bits',
+               deprecated_name='tenant_network_v6_mask_bits',
                default=64,
-               help="The mask bits for tenant ipv6 subnets"),
-    cfg.BoolOpt('tenant_networks_reachable',
+               help="The mask bits for project ipv6 subnets"),
+    cfg.BoolOpt('project_networks_reachable',
+                deprecated_name='tenant_networks_reachable',
                 default=False,
-                help="Whether tenant networks can be reached directly from "
+                help="Whether project networks can be reached directly from "
                      "the test client. This must be set to True when the "
                      "'fixed' ssh_connect_method is selected."),
     cfg.StrOpt('public_network_id',
@@ -1003,7 +1013,7 @@
                 default=False,
                 help='Allows a full cleaning process after a stress test.'
                      ' Caution : this cleanup will remove every objects of'
-                     ' every tenant.')
+                     ' every project.')
 ]
 
 
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index f4b76e5..d1bc141 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -151,7 +151,7 @@
 
 def _common_service_clients_check(logical_line, physical_line, filename,
                                   ignored_list_file=None):
-    if 'tempest/services/' not in filename:
+    if not re.match('tempest/(lib/)?services/.*', filename):
         return False
 
     if ignored_list_file is not None:
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
index 5d3fc93..380c173 100644
--- a/tempest/hacking/ignored_list_T110.txt
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -4,5 +4,4 @@
 ./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
 ./tempest/services/network/json/routers_client.py
diff --git a/tempest/api_schema/response/compute/v2_2/__init__.py b/tempest/lib/api_schema/response/compute/v2_2/__init__.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2_2/__init__.py
rename to tempest/lib/api_schema/response/compute/v2_2/__init__.py
diff --git a/tempest/api_schema/response/compute/v2_2/keypairs.py b/tempest/lib/api_schema/response/compute/v2_2/keypairs.py
similarity index 95%
rename from tempest/api_schema/response/compute/v2_2/keypairs.py
rename to tempest/lib/api_schema/response/compute/v2_2/keypairs.py
index 5d8d24d..0bb7771 100644
--- a/tempest/api_schema/response/compute/v2_2/keypairs.py
+++ b/tempest/lib/api_schema/response/compute/v2_2/keypairs.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.response.compute.v2_1 import keypairs
+from tempest.lib.api_schema.response.compute.v2_1 import keypairs
 
 get_keypair = copy.deepcopy(keypairs.get_keypair)
 get_keypair['response_body']['properties']['keypair'][
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index 7d2eda0..d001d27 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -248,10 +248,10 @@
         :param str url: the relative url to send the post request to
         :param dict body: the request body
         :param dict headers: The headers to use for the request
-        :param dict extra_headers: If the headers returned by the get_headers()
-                                   method are to be used but additional headers
-                                   are needed in the request pass them in as a
-                                   dict
+        :param bool extra_headers: Boolean value than indicates if the headers
+                                   returned by the get_headers() method are to
+                                   be used but additional headers are needed in
+                                   the request pass them in as a dict.
         :return: a tuple with the first entry containing the response headers
                  and the second the response body
         :rtype: tuple
@@ -263,10 +263,10 @@
 
         :param str url: the relative url to send the post request to
         :param dict headers: The headers to use for the request
-        :param dict extra_headers: If the headers returned by the get_headers()
-                                   method are to be used but additional headers
-                                   are needed in the request pass them in as a
-                                   dict
+        :param bool extra_headers: Boolean value than indicates if the headers
+                                   returned by the get_headers() method are to
+                                   be used but additional headers are needed in
+                                   the request pass them in as a dict.
         :return: a tuple with the first entry containing the response headers
                  and the second the response body
         :rtype: tuple
@@ -279,10 +279,10 @@
         :param str url: the relative url to send the post request to
         :param dict headers: The headers to use for the request
         :param dict body: the request body
-        :param dict extra_headers: If the headers returned by the get_headers()
-                                   method are to be used but additional headers
-                                   are needed in the request pass them in as a
-                                   dict
+        :param bool extra_headers: Boolean value than indicates if the headers
+                                   returned by the get_headers() method are to
+                                   be used but additional headers are needed in
+                                   the request pass them in as a dict.
         :return: a tuple with the first entry containing the response headers
                  and the second the response body
         :rtype: tuple
@@ -295,10 +295,10 @@
         :param str url: the relative url to send the post request to
         :param dict body: the request body
         :param dict headers: The headers to use for the request
-        :param dict extra_headers: If the headers returned by the get_headers()
-                                   method are to be used but additional headers
-                                   are needed in the request pass them in as a
-                                   dict
+        :param bool extra_headers: Boolean value than indicates if the headers
+                                   returned by the get_headers() method are to
+                                   be used but additional headers are needed in
+                                   the request pass them in as a dict.
         :return: a tuple with the first entry containing the response headers
                  and the second the response body
         :rtype: tuple
@@ -311,10 +311,10 @@
         :param str url: the relative url to send the post request to
         :param dict body: the request body
         :param dict headers: The headers to use for the request
-        :param dict extra_headers: If the headers returned by the get_headers()
-                                   method are to be used but additional headers
-                                   are needed in the request pass them in as a
-                                   dict
+        :param bool extra_headers: Boolean value than indicates if the headers
+                                   returned by the get_headers() method are to
+                                   be used but additional headers are needed in
+                                   the request pass them in as a dict.
         :return: a tuple with the first entry containing the response headers
                  and the second the response body
         :rtype: tuple
@@ -326,10 +326,10 @@
 
         :param str url: the relative url to send the post request to
         :param dict headers: The headers to use for the request
-        :param dict extra_headers: If the headers returned by the get_headers()
-                                   method are to be used but additional headers
-                                   are needed in the request pass them in as a
-                                   dict
+        :param bool extra_headers: Boolean value than indicates if the headers
+                                   returned by the get_headers() method are to
+                                   be used but additional headers are needed in
+                                   the request pass them in as a dict.
         :return: a tuple with the first entry containing the response headers
                  and the second the response body
         :rtype: tuple
@@ -341,10 +341,10 @@
 
         :param str url: the relative url to send the post request to
         :param dict headers: The headers to use for the request
-        :param dict extra_headers: If the headers returned by the get_headers()
-                                   method are to be used but additional headers
-                                   are needed in the request pass them in as a
-                                   dict
+        :param bool extra_headers: Boolean value than indicates if the headers
+                                   returned by the get_headers() method are to
+                                   be used but additional headers are needed in
+                                   the request pass them in as a dict.
         :return: a tuple with the first entry containing the response headers
                  and the second the response body
         :rtype: tuple
@@ -576,10 +576,10 @@
 
         :param str method: The HTTP verb to use for the request
         :param str url: Relative url to send the request to
-        :param dict extra_headers: If specified without the headers kwarg the
-                                   headers sent with the request will be the
-                                   combination from the get_headers() method
-                                   and this kwarg
+        :param bool extra_headers: Boolean value than indicates if the headers
+                                   returned by the get_headers() method are to
+                                   be used but additional headers are needed in
+                                   the request pass them in as a dict.
         :param dict headers: Headers to use for the request if none are
                              specifed the headers returned from the
                              get_headers() method are used. If the request
@@ -620,7 +620,6 @@
             headers = self.get_headers()
         elif extra_headers:
             try:
-                headers = headers.copy()
                 headers.update(self.get_headers())
             except (ValueError, TypeError):
                 headers = self.get_headers()
diff --git a/tempest/lib/services/compute/flavors_client.py b/tempest/lib/services/compute/flavors_client.py
index 6869f02..e377c84 100644
--- a/tempest/lib/services/compute/flavors_client.py
+++ b/tempest/lib/services/compute/flavors_client.py
@@ -133,7 +133,9 @@
             resp, body)
         return rest_client.ResponseBody(resp, body)
 
-    def unset_flavor_extra_spec(self, flavor_id, key):
+    def unset_flavor_extra_spec(self, flavor_id, key):  # noqa
+        # NOTE: This noqa is for passing T111 check and we cannot rename
+        #       to keep backwards compatibility.
         """Unset extra Specs from the mentioned flavor."""
         resp, body = self.delete('flavors/%s/os-extra_specs/%s' %
                                  (flavor_id, key))
diff --git a/tempest/lib/services/compute/hosts_client.py b/tempest/lib/services/compute/hosts_client.py
index 0143765..16b5edd 100644
--- a/tempest/lib/services/compute/hosts_client.py
+++ b/tempest/lib/services/compute/hosts_client.py
@@ -61,7 +61,11 @@
         self.validate_response(schema.update_host, resp, body)
         return rest_client.ResponseBody(resp, body)
 
-    def startup_host(self, hostname):
+    def startup_host(self, hostname):  # noqa
+        # NOTE: This noqa is for passing T110 check and we cannot rename
+        #       to keep backwards compatibility. Actually, the root problem
+        #       of this is a wrong API design. GET operation should not change
+        #       resource status, but current API does that.
         """Startup a host."""
 
         resp, body = self.get("os-hosts/%s/startup" % hostname)
@@ -69,7 +73,11 @@
         self.validate_response(schema.startup_host, resp, body)
         return rest_client.ResponseBody(resp, body)
 
-    def shutdown_host(self, hostname):
+    def shutdown_host(self, hostname):  # noqa
+        # NOTE: This noqa is for passing T110 check and we cannot rename
+        #       to keep backwards compatibility. Actually, the root problem
+        #       of this is a wrong API design. GET operation should not change
+        #       resource status, but current API does that.
         """Shutdown a host."""
 
         resp, body = self.get("os-hosts/%s/shutdown" % hostname)
@@ -77,7 +85,11 @@
         self.validate_response(schema.shutdown_host, resp, body)
         return rest_client.ResponseBody(resp, body)
 
-    def reboot_host(self, hostname):
+    def reboot_host(self, hostname):  # noqa
+        # NOTE: This noqa is for passing T110 check and we cannot rename
+        #       to keep backwards compatibility. Actually, the root problem
+        #       of this is a wrong API design. GET operation should not change
+        #       resource status, but current API does that.
         """Reboot a host."""
 
         resp, body = self.get("os-hosts/%s/reboot" % hostname)
diff --git a/tempest/lib/services/compute/hypervisor_client.py b/tempest/lib/services/compute/hypervisor_client.py
index 5dcecc9..23c304e 100644
--- a/tempest/lib/services/compute/hypervisor_client.py
+++ b/tempest/lib/services/compute/hypervisor_client.py
@@ -63,7 +63,9 @@
         self.validate_response(schema.get_hypervisor_uptime, resp, body)
         return rest_client.ResponseBody(resp, body)
 
-    def search_hypervisor(self, hypervisor_name):
+    def search_hypervisor(self, hypervisor_name):  # noqa
+        # NOTE: This noqa is for passing T110 check and we cannot rename
+        #       to keep backwards compatibility.
         """Search specified hypervisor."""
         resp, body = self.get('os-hypervisors/%s/search' % hypervisor_name)
         body = json.loads(body)
diff --git a/tempest/lib/services/compute/keypairs_client.py b/tempest/lib/services/compute/keypairs_client.py
index 0361b9d..7b8e6b2 100644
--- a/tempest/lib/services/compute/keypairs_client.py
+++ b/tempest/lib/services/compute/keypairs_client.py
@@ -14,23 +14,36 @@
 #    under the License.
 
 from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
 
-from tempest.lib.api_schema.response.compute.v2_1 import keypairs as schema
+from tempest.lib.api_schema.response.compute.v2_1 import keypairs as schemav21
+from tempest.lib.api_schema.response.compute.v2_2 import keypairs as schemav22
 from tempest.lib.common import rest_client
 from tempest.lib.services.compute import base_compute_client
 
 
 class KeyPairsClient(base_compute_client.BaseComputeClient):
 
-    def list_keypairs(self):
-        resp, body = self.get("os-keypairs")
+    schema_versions_info = [{'min': None, 'max': '2.1', 'schema': schemav21},
+                            {'min': '2.2', 'max': None, 'schema': schemav22}]
+
+    def list_keypairs(self, **params):
+        url = 'os-keypairs'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.list_keypairs, resp, body)
         return rest_client.ResponseBody(resp, body)
 
-    def show_keypair(self, keypair_name):
-        resp, body = self.get("os-keypairs/%s" % keypair_name)
+    def show_keypair(self, keypair_name, **params):
+        url = "os-keypairs/%s" % keypair_name
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.get_keypair, resp, body)
         return rest_client.ResponseBody(resp, body)
 
@@ -43,10 +56,15 @@
         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 rest_client.ResponseBody(resp, body)
 
-    def delete_keypair(self, keypair_name):
-        resp, body = self.delete("os-keypairs/%s" % keypair_name)
+    def delete_keypair(self, keypair_name, **params):
+        url = "os-keypairs/%s" % keypair_name
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.delete(url)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.delete_keypair, resp, body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/network/ports_client.py b/tempest/lib/services/network/ports_client.py
index 1793d6a..eba11d3 100644
--- a/tempest/lib/services/network/ports_client.py
+++ b/tempest/lib/services/network/ports_client.py
@@ -10,6 +10,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest.lib import exceptions as lib_exc
 from tempest.lib.services.network import base
 
 
@@ -45,3 +46,10 @@
         """
         uri = '/ports'
         return self.create_resource(uri, kwargs)
+
+    def is_resource_deleted(self, id):
+        try:
+            self.show_port(id)
+        except lib_exc.NotFound:
+            return True
+        return False
diff --git a/tempest/lib/services/network/quotas_client.py b/tempest/lib/services/network/quotas_client.py
index b5cf35b..752b253 100644
--- a/tempest/lib/services/network/quotas_client.py
+++ b/tempest/lib/services/network/quotas_client.py
@@ -22,7 +22,9 @@
         uri = '/quotas/%s' % tenant_id
         return self.update_resource(uri, put_body)
 
-    def reset_quotas(self, tenant_id):
+    def reset_quotas(self, tenant_id):  # noqa
+        # NOTE: This noqa is for passing T111 check and we cannot rename
+        #       to keep backwards compatibility.
         uri = '/quotas/%s' % tenant_id
         return self.delete_resource(uri)
 
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 1217dc9..988ee1a 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -63,7 +63,6 @@
         cls.servers_client = cls.manager.servers_client
         cls.interface_client = cls.manager.interfaces_client
         # Neutron network client
-        cls.network_client = cls.manager.network_client
         cls.networks_client = cls.manager.networks_client
         cls.ports_client = cls.manager.ports_client
         cls.routers_client = cls.manager.routers_client
@@ -217,7 +216,7 @@
                 networks = kwargs.pop('networks')
 
             # If there are no networks passed to us we look up
-            # for the tenant's private networks and create a port
+            # for the project's private networks and create a port
             # if there is only one private network. The same behaviour
             # as we would expect when passing the call to the clients
             # with no networks
@@ -687,17 +686,15 @@
         super(NetworkScenarioTest, cls).resource_setup()
         cls.tenant_id = cls.manager.identity_client.tenant_id
 
-    def _create_network(self, client=None, networks_client=None,
+    def _create_network(self, networks_client=None,
                         routers_client=None, tenant_id=None,
                         namestart='network-smoke-'):
-        if not client:
-            client = self.network_client
         if not networks_client:
             networks_client = self.networks_client
         if not routers_client:
             routers_client = self.routers_client
         if not tenant_id:
-            tenant_id = client.tenant_id
+            tenant_id = networks_client.tenant_id
         name = data_utils.rand_name(namestart)
         result = networks_client.create_network(name=name, tenant_id=tenant_id)
         network = net_resources.DeletableNetwork(
@@ -737,15 +734,13 @@
             *args, **kwargs)
         return agents_list['agents']
 
-    def _create_subnet(self, network, client=None, subnets_client=None,
+    def _create_subnet(self, network, subnets_client=None,
                        routers_client=None, namestart='subnet-smoke',
                        **kwargs):
         """Create a subnet for the given network
 
         within the cidr block configured for tenant networks.
         """
-        if not client:
-            client = self.network_client
         if not subnets_client:
             subnets_client = self.subnets_client
         if not routers_client:
@@ -764,11 +759,11 @@
 
         if ip_version == 6:
             tenant_cidr = netaddr.IPNetwork(
-                CONF.network.tenant_network_v6_cidr)
-            num_bits = CONF.network.tenant_network_v6_mask_bits
+                CONF.network.project_network_v6_cidr)
+            num_bits = CONF.network.project_network_v6_mask_bits
         else:
-            tenant_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-            num_bits = CONF.network.tenant_network_mask_bits
+            tenant_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+            num_bits = CONF.network.project_network_mask_bits
 
         result = None
         str_cidr = None
@@ -796,7 +791,7 @@
                     raise
         self.assertIsNotNone(result, 'Unable to allocate tenant network')
         subnet = net_resources.DeletableSubnet(
-            network_client=client, subnets_client=subnets_client,
+            subnets_client=subnets_client,
             routers_client=routers_client, **result['subnet'])
         self.assertEqual(subnet.cidr, str_cidr)
         self.addCleanup(self.delete_wrapper, subnet.delete)
@@ -908,7 +903,7 @@
                                            private_key,
                                            should_connect=True,
                                            servers_for_debug=None):
-        if not CONF.network.tenant_networks_reachable:
+        if not CONF.network.project_networks_reachable:
             msg = 'Tenant networks not configured to be reachable.'
             LOG.info(msg)
             return
@@ -1169,7 +1164,7 @@
         router.update(admin_state_up=admin_state_up)
         self.assertEqual(admin_state_up, router.admin_state_up)
 
-    def create_networks(self, client=None, networks_client=None,
+    def create_networks(self, networks_client=None,
                         routers_client=None, subnets_client=None,
                         tenant_id=None, dns_nameservers=None):
         """Create a network with a subnet connected to a router.
@@ -1177,7 +1172,6 @@
         The baremetal driver is a special case since all nodes are
         on the same shared network.
 
-        :param client: network client to create resources with.
         :param tenant_id: id of tenant to create resources in.
         :param dns_nameservers: list of dns servers to send to subnet.
         :returns: network, subnet, router
@@ -1197,12 +1191,12 @@
             subnet = None
         else:
             network = self._create_network(
-                client=client, networks_client=networks_client,
+                networks_client=networks_client,
                 tenant_id=tenant_id)
             router = self._get_router(client=routers_client,
                                       tenant_id=tenant_id)
 
-            subnet_kwargs = dict(network=network, client=client,
+            subnet_kwargs = dict(network=network,
                                  subnets_client=subnets_client,
                                  routers_client=routers_client)
             # use explicit check because empty list is a valid option
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 2cbe6dc..4c2d31b 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -38,9 +38,9 @@
     @classmethod
     def skip_checks(cls):
         super(TestNetworkAdvancedServerOps, cls).skip_checks()
-        if not (CONF.network.tenant_networks_reachable
+        if not (CONF.network.project_networks_reachable
                 or CONF.network.public_network_id):
-            msg = ('Either tenant_networks_reachable must be "true", or '
+            msg = ('Either project_networks_reachable must be "true", or '
                    'public_network_id must be defined.')
             raise cls.skipException(msg)
 
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 9e2477e..dfa4815 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -59,7 +59,7 @@
      Determine which types of networks to test as follows:
 
      * Configure tenant network checks (via the
-       'tenant_networks_reachable' key) if the Tempest host should
+       'project_networks_reachable' key) if the Tempest host should
        have direct connectivity to tenant networks.  This is likely to
        be the case if Tempest is running on the same host as a
        single-node devstack installation with IP namespaces disabled.
@@ -81,9 +81,9 @@
     @classmethod
     def skip_checks(cls):
         super(TestNetworkBasicOps, cls).skip_checks()
-        if not (CONF.network.tenant_networks_reachable
+        if not (CONF.network.project_networks_reachable
                 or CONF.network.public_network_id):
-            msg = ('Either tenant_networks_reachable must be "true", or '
+            msg = ('Either project_networks_reachable must be "true", or '
                    'public_network_id must be defined.')
             raise cls.skipException(msg)
         for ext in ['router', 'security-group']:
@@ -250,9 +250,8 @@
         interface = self.interface_client.create_interface(
             server_id=server['id'],
             net_id=self.new_net.id)['interfaceAttachment']
-        self.addCleanup(self.network_client.wait_for_resource_deletion,
-                        'port',
-                        interface['port_id'], client=self.ports_client)
+        self.addCleanup(self.ports_client.wait_for_resource_deletion,
+                        interface['port_id'])
         self.addCleanup(self.delete_wrapper,
                         self.interface_client.delete_interface,
                         server['id'], interface['port_id'])
@@ -692,7 +691,7 @@
         self._setup_network_and_servers()
 
         # NOTE(kevinbenton): we have to use the admin credentials to check
-        # for the distributed flag because self.router only has a tenant view.
+        # for the distributed flag because self.router only has a project view.
         admin = self.admin_manager.routers_client.show_router(self.router.id)
         if admin['router'].get('distributed', False):
             msg = "Rescheduling test does not apply to distributed routers."
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 66c8ade..a52d8f9 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -44,9 +44,9 @@
         if not (CONF.network_feature_enabled.ipv6
                 and CONF.network_feature_enabled.ipv6_subnet_attributes):
             raise cls.skipException('IPv6 or its attributes not supported')
-        if not (CONF.network.tenant_networks_reachable
+        if not (CONF.network.project_networks_reachable
                 or CONF.network.public_network_id):
-            msg = ('Either tenant_networks_reachable must be "true", or '
+            msg = ('Either project_networks_reachable must be "true", or '
                    'public_network_id must be defined.')
             raise cls.skipException(msg)
         if CONF.baremetal.driver_enabled:
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 058f43b..adc9008 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -45,6 +45,12 @@
     success - ping returns
     failure - ping_timeout reached
 
+    multi-node:
+        Multi-Node mode is enabled when CONF.compute.min_compute_nodes > 1.
+        Tests connectivity between servers on different compute nodes.
+        When enabled, test will boot each new server to different
+        compute nodes.
+
     setup:
         for primary tenant:
             1. create a network&subnet
@@ -130,9 +136,9 @@
             msg = ('Not currently supported when using vnic_type'
                    ' direct or macvtap')
             raise cls.skipException(msg)
-        if not (CONF.network.tenant_networks_reachable or
+        if not (CONF.network.project_networks_reachable or
                 CONF.network.public_network_id):
-            msg = ('Either tenant_networks_reachable must be "true", or '
+            msg = ('Either project_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'):
@@ -194,7 +200,7 @@
             client=tenant.manager.security_groups_client
         )
 
-        # don't use default secgroup since it allows in-tenant traffic
+        # don't use default secgroup since it allows in-project traffic
         def_sg = self._create_empty_security_group(
             namestart='secgroup_general-',
             tenant_id=tenant.creds.tenant_id,
@@ -301,7 +307,7 @@
 
     def _set_access_point(self, tenant):
         # creates a server in a secgroup with rule allowing external ssh
-        # in order to access tenant internal network
+        # in order to access project internal network
         # workaround ip namespace
         secgroups = tenant.security_groups.values()
         name = 'server-{tenant}-access_point'.format(
@@ -321,7 +327,6 @@
 
     def _create_tenant_network(self, tenant):
         network, subnet, router = self.create_networks(
-            client=tenant.manager.network_client,
             networks_client=tenant.manager.networks_client,
             routers_client=tenant.manager.routers_client,
             subnets_client=tenant.manager.subnets_client)
@@ -468,7 +473,7 @@
         if not self.credentials_provider.is_multi_tenant():
             raise self.skipException("No secondary tenant defined")
         try:
-            # deploy new tenant
+            # deploy new project
             self._deploy_tenant(self.alt_tenant)
             self._verify_network_details(self.alt_tenant)
             self._verify_mac_addr(self.alt_tenant)
diff --git a/tempest/services/compute/__init__.py b/tempest/services/compute/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/compute/__init__.py
+++ /dev/null
diff --git a/tempest/services/compute/json/__init__.py b/tempest/services/compute/json/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/compute/json/__init__.py
+++ /dev/null
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
deleted file mode 100644
index 2af55b2..0000000
--- a/tempest/services/compute/json/keypairs_client.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from oslo_serialization import jsonutils as json
-
-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.lib.common import rest_client
-from tempest.lib.services.compute import base_compute_client
-
-
-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 rest_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 rest_client.ResponseBody(resp, body)
-
-    def create_keypair(self, **kwargs):
-        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 rest_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 rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
deleted file mode 100644
index 5080657..0000000
--- a/tempest/services/network/json/network_client.py
+++ /dev/null
@@ -1,56 +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.
-
-import time
-
-from tempest import exceptions
-from tempest.lib import exceptions as lib_exc
-from tempest.lib.services.network import base
-
-
-class NetworkClient(base.BaseNetworkClient):
-
-    """Tempest REST client for Neutron.
-
-    Uses v2 of the Neutron API, since the V1 API has been removed from the
-    code base.
-
-    Implements create, delete, update, list and show for the basic Neutron
-    abstractions (networks, sub-networks, routers, ports and floating IP):
-
-    Implements add/remove interface to router using subnet ID / port ID
-
-    It also implements list, show, update and reset for OpenStack Networking
-    quotas
-    """
-
-    def wait_for_resource_deletion(self, resource_type, id, client=None):
-        """Waits for a resource to be deleted."""
-        start_time = int(time.time())
-        while True:
-            if self.is_resource_deleted(resource_type, id, client=client):
-                return
-            if int(time.time()) - start_time >= self.build_timeout:
-                raise exceptions.TimeoutException
-            time.sleep(self.build_interval)
-
-    def is_resource_deleted(self, resource_type, id, client=None):
-        if client is None:
-            client = self
-        method = 'show_' + resource_type
-        try:
-            getattr(client, method)(id)
-        except AttributeError:
-            raise Exception("Unknown resource type %s " % resource_type)
-        except lib_exc.NotFound:
-            return True
-        return False
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index e78fcfe..329c54d 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -41,7 +41,6 @@
 
     def __init__(self, *args, **kwargs):
         self.client = kwargs.pop('client', None)
-        self.network_client = kwargs.pop('network_client', None)
         self.networks_client = kwargs.pop('networks_client', None)
         self.routers_client = kwargs.pop('routers_client', None)
         self.subnets_client = kwargs.pop('subnets_client', None)
diff --git a/tempest/tests/base.py b/tempest/tests/base.py
deleted file mode 100644
index fe9268e..0000000
--- a/tempest/tests/base.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-#    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 mock
-from oslotest import base
-from oslotest import moxstubout
-
-
-class TestCase(base.BaseTestCase):
-
-    def setUp(self):
-        super(TestCase, self).setUp()
-        mox_fixture = self.useFixture(moxstubout.MoxStubout())
-        self.mox = mox_fixture.mox
-        self.stubs = mox_fixture.stubs
-
-    def patch(self, target, **kwargs):
-        """Returns a started `mock.patch` object for the supplied target.
-
-        The caller may then call the returned patcher to create a mock object.
-
-        The caller does not need to call stop() on the returned
-        patcher object, as this method automatically adds a cleanup
-        to the test class to stop the patcher.
-
-        :param target: String module.class or module.object expression to patch
-        :param **kwargs: Passed as-is to `mock.patch`. See mock documentation
-                         for details.
-        """
-        p = mock.patch(target, **kwargs)
-        m = p.start()
-        self.addCleanup(p.stop)
-        return m
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index 2d0256a..b8c9969 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -17,7 +17,7 @@
 
 from tempest.cmd import javelin
 from tempest.lib import exceptions as lib_exc
-from tempest.tests import base
+from tempest.tests.lib import base
 
 
 class JavelinUnitTest(base.TestCase):
diff --git a/tempest/tests/cmd/test_list_plugins.py b/tempest/tests/cmd/test_list_plugins.py
index 17ddb18..782dde7 100644
--- a/tempest/tests/cmd/test_list_plugins.py
+++ b/tempest/tests/cmd/test_list_plugins.py
@@ -14,7 +14,7 @@
 
 import subprocess
 
-from tempest.tests import base
+from tempest.tests.lib import base
 
 
 class TestTempestListPlugins(base.TestCase):
diff --git a/tempest/tests/cmd/test_tempest_init.py b/tempest/tests/cmd/test_tempest_init.py
index 685a0b3..6c5326a 100644
--- a/tempest/tests/cmd/test_tempest_init.py
+++ b/tempest/tests/cmd/test_tempest_init.py
@@ -18,7 +18,7 @@
 import fixtures
 
 from tempest.cmd import init
-from tempest.tests import base
+from tempest.tests.lib import base
 
 
 class TestTempestInit(base.TestCase):
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index dc0ba6f..5d050d1 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -19,8 +19,8 @@
 
 from tempest.cmd import verify_tempest_config
 from tempest import config
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class TestGetAPIVersions(base.TestCase):
diff --git a/tempest/tests/common/test_admin_available.py b/tempest/tests/common/test_admin_available.py
index 75401db..c803541 100644
--- a/tempest/tests/common/test_admin_available.py
+++ b/tempest/tests/common/test_admin_available.py
@@ -17,8 +17,8 @@
 
 from tempest.common import credentials_factory as credentials
 from tempest import config
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class TestAdminAvailable(base.TestCase):
@@ -36,19 +36,19 @@
                              dynamic_creds, group='auth')
         if use_accounts_file:
             accounts = [{'username': 'u1',
-                         'tenant_name': 't1',
+                         'project_name': 't1',
                          'password': 'p'},
                         {'username': 'u2',
-                         'tenant_name': 't2',
+                         'project_name': 't2',
                          'password': 'p'}]
             if admin_creds == 'role':
                 accounts.append({'username': 'admin',
-                                 'tenant_name': 'admin',
+                                 'project_name': 'admin',
                                  'password': 'p',
                                  'roles': ['admin']})
             elif admin_creds == 'type':
                 accounts.append({'username': 'admin',
-                                 'tenant_name': 'admin',
+                                 'project_name': 'admin',
                                  'password': 'p',
                                  'types': ['admin']})
             self.useFixture(mockpatch.Patch(
@@ -63,17 +63,17 @@
                                             return_value=False))
             if admin_creds:
                 username = 'u'
-                tenant = 't'
+                project = 't'
                 password = 'p'
                 domain = 'd'
             else:
                 username = None
-                tenant = None
+                project = None
                 password = None
                 domain = None
 
             cfg.CONF.set_default('admin_username', username, group='auth')
-            cfg.CONF.set_default('admin_tenant_name', tenant, group='auth')
+            cfg.CONF.set_default('admin_project_name', project, group='auth')
             cfg.CONF.set_default('admin_password', password, group='auth')
             cfg.CONF.set_default('admin_domain_name', domain, group='auth')
 
diff --git a/tempest/tests/common/test_alt_available.py b/tempest/tests/common/test_alt_available.py
index db3f5ec..cb1de16 100644
--- a/tempest/tests/common/test_alt_available.py
+++ b/tempest/tests/common/test_alt_available.py
@@ -17,8 +17,8 @@
 
 from tempest.common import credentials_factory as credentials
 from tempest import config
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class TestAltAvailable(base.TestCase):
@@ -36,7 +36,7 @@
                              dynamic_creds, group='auth')
         if use_accounts_file:
             accounts = [dict(username="u%s" % ii,
-                             tenant_name="t%s" % ii,
+                             project_name="t%s" % ii,
                              password="p") for ii in creds]
             self.useFixture(mockpatch.Patch(
                 'tempest.common.preprov_creds.read_accounts_yaml',
@@ -52,19 +52,19 @@
             for ii in range(0, 2):
                 if len(creds) > ii:
                     username = 'u%s' % creds[ii]
-                    tenant = 't%s' % creds[ii]
+                    project = 't%s' % creds[ii]
                     password = 'p'
                     domain = 'd'
                 else:
                     username = None
-                    tenant = None
+                    project = None
                     password = None
                     domain = None
 
                 cfg.CONF.set_default('%susername' % cred_prefix[ii], username,
                                      group='identity')
-                cfg.CONF.set_default('%stenant_name' % cred_prefix[ii], tenant,
-                                     group='identity')
+                cfg.CONF.set_default('%sproject_name' % cred_prefix[ii],
+                                     project, group='identity')
                 cfg.CONF.set_default('%spassword' % cred_prefix[ii], password,
                                      group='identity')
                 cfg.CONF.set_default('%sdomain_name' % cred_prefix[ii], domain,
diff --git a/tempest/tests/common/test_configured_creds.py b/tempest/tests/common/test_configured_creds.py
index be24595..8c721e6 100644
--- a/tempest/tests/common/test_configured_creds.py
+++ b/tempest/tests/common/test_configured_creds.py
@@ -21,9 +21,9 @@
 from tempest.lib import exceptions as lib_exc
 from tempest.lib.services.identity.v2 import token_client as v2_client
 from tempest.lib.services.identity.v3 import token_client as v3_client
-from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests import fake_identity
+from tempest.tests.lib import base
 
 
 class ConfiguredV2CredentialsTests(base.TestCase):
diff --git a/tempest/tests/common/test_credentials.py b/tempest/tests/common/test_credentials.py
index 136ac02..6fc490e 100644
--- a/tempest/tests/common/test_credentials.py
+++ b/tempest/tests/common/test_credentials.py
@@ -15,8 +15,8 @@
 from tempest.common import credentials_factory as credentials
 from tempest import config
 from tempest import exceptions
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class TestLegacyCredentialsProvider(base.TestCase):
diff --git a/tempest/tests/common/test_custom_matchers.py b/tempest/tests/common/test_custom_matchers.py
index 2656a47..d664961 100644
--- a/tempest/tests/common/test_custom_matchers.py
+++ b/tempest/tests/common/test_custom_matchers.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 from tempest.common import custom_matchers
-from tempest.tests import base
+from tempest.tests.lib import base
 
 from testtools.tests.matchers import helpers
 
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index be4a6ee..f2052dc 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -30,12 +30,11 @@
     json_tenants_client
 from tempest.services.identity.v2.json import users_client as \
     json_users_client
-from tempest.services.network.json import network_client as json_network_client
 from tempest.services.network.json import routers_client
-from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests import fake_http
 from tempest.tests import fake_identity
+from tempest.tests.lib import base
 
 
 class TestDynamicCredentialProvider(base.TestCase):
@@ -59,10 +58,8 @@
 
     def test_tempest_client(self):
         creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
-        self.assertTrue(isinstance(creds.identity_admin_client,
-                                   json_iden_client.IdentityClient))
-        self.assertTrue(isinstance(creds.network_admin_client,
-                                   json_network_client.NetworkClient))
+        self.assertIsInstance(creds.identity_admin_client,
+                              json_iden_client.IdentityClient)
 
     def _get_fake_admin_creds(self):
         return credentials.get_credentials(
diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py
index 7188e5f..efc5ef6 100644
--- a/tempest/tests/common/test_preprov_creds.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -28,10 +28,10 @@
 from tempest.lib import auth
 from tempest.lib import exceptions as lib_exc
 from tempest.lib.services.identity.v2 import token_client
-from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests import fake_http
 from tempest.tests import fake_identity
+from tempest.tests.lib import base
 
 
 class TestPreProvisionedCredentials(base.TestCase):
@@ -325,7 +325,7 @@
                                                     'id': 'fake-id',
                                                     'label': 'network-2'}]}):
             creds = test_accounts_class.get_creds_by_roles(['role-7'])
-        self.assertTrue(isinstance(creds, cred_provider.TestResources))
+        self.assertIsInstance(creds, cred_provider.TestResources)
         network = creds.network
         self.assertIsNotNone(network)
         self.assertIn('name', network)
diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py
index 492bdca..e0cef62 100644
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -19,7 +19,7 @@
 from tempest.common import waiters
 from tempest import exceptions
 from tempest.services.volume.base import base_volumes_client
-from tempest.tests import base
+from tempest.tests.lib import base
 import tempest.tests.utils as utils
 
 
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index 9c2b99e..22cf47a 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -19,8 +19,8 @@
 
 from tempest.common.utils.linux import remote_client
 from tempest import config
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class TestRemoteClient(base.TestCase):
diff --git a/tempest/tests/common/utils/test_file_utils.py b/tempest/tests/common/utils/test_file_utils.py
index 937aefa..1a14592 100644
--- a/tempest/tests/common/utils/test_file_utils.py
+++ b/tempest/tests/common/utils/test_file_utils.py
@@ -16,7 +16,7 @@
 import mock
 
 from tempest.common.utils import file_utils
-from tempest.tests import base
+from tempest.tests.lib import base
 
 
 class TestFileUtils(base.TestCase):
diff --git a/tempest/tests/fake_config.py b/tempest/tests/fake_config.py
index c45f6da..edd7186 100644
--- a/tempest/tests/fake_config.py
+++ b/tempest/tests/fake_config.py
@@ -46,7 +46,7 @@
             lock_path=str(os.environ.get('OS_TEST_LOCK_PATH')),
         )
         self.conf.set_default('auth_version', 'v2', group='identity')
-        for config_option in ['username', 'password', 'tenant_name']:
+        for config_option in ['username', 'password', 'project_name']:
             # Identity group items
             for prefix in ['', 'alt_', 'admin_']:
                 if prefix == 'admin_':
diff --git a/tempest/tests/negative/test_negative_auto_test.py b/tempest/tests/negative/test_negative_auto_test.py
index 7a127cd..c666bd3 100644
--- a/tempest/tests/negative/test_negative_auto_test.py
+++ b/tempest/tests/negative/test_negative_auto_test.py
@@ -15,8 +15,8 @@
 
 from tempest import config
 import tempest.test as test
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class TestNegativeAutoTest(base.TestCase):
diff --git a/tempest/tests/negative/test_negative_generators.py b/tempest/tests/negative/test_negative_generators.py
index 78fd80d..e0d7f42 100644
--- a/tempest/tests/negative/test_negative_generators.py
+++ b/tempest/tests/negative/test_negative_generators.py
@@ -22,7 +22,7 @@
 from tempest.common.generator import base_generator
 from tempest.common.generator import negative_generator
 from tempest.common.generator import valid_generator
-from tempest.tests import base
+from tempest.tests.lib import base
 
 
 class TestNegativeBasicGenerator(base.TestCase):
diff --git a/tempest/tests/services/compute/base.py b/tempest/tests/services/compute/base.py
deleted file mode 100644
index a35a87c..0000000
--- a/tempest/tests/services/compute/base.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2015 Deutsche Telekom AG.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
-from tempest.tests import base
-
-
-class BaseComputeServiceTest(base.TestCase):
-    def create_response(self, body, to_utf=False, status=200):
-        json_body = {}
-        if body:
-            json_body = json.dumps(body)
-            if to_utf:
-                json_body = json_body.encode('utf-8')
-        response = (httplib2.Response({'status': status}), json_body)
-        return response
-
-    def check_service_client_function(self, function, function2mock,
-                                      body, to_utf=False, status=200,
-                                      **kwargs):
-        mocked_response = self.create_response(body, to_utf, status)
-        self.useFixture(mockpatch.Patch(
-            function2mock, return_value=mocked_response))
-        if kwargs:
-            resp = function(**kwargs)
-        else:
-            resp = function()
-        self.assertEqual(body, resp)
diff --git a/tempest/tests/services/compute/test_keypairs_client.py b/tempest/tests/services/compute/test_keypairs_client.py
deleted file mode 100644
index e8f8280..0000000
--- a/tempest/tests/services/compute/test_keypairs_client.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright 2015 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import copy
-
-from tempest.services.compute.json import keypairs_client
-from tempest.tests.lib import fake_auth_provider
-from tempest.tests.services.compute import base
-
-
-class TestKeyPairsClient(base.BaseComputeServiceTest):
-
-    FAKE_KEYPAIR = {"keypair": {
-        "public_key": "ssh-rsa foo Generated-by-Nova",
-        "name": u'\u2740(*\xb4\u25e1`*)\u2740',
-        "user_id": "525d55f98980415ba98e634972fa4a10",
-        "fingerprint": "76:24:66:49:d7:ca:6e:5c:77:ea:8e:bb:9c:15:5f:98"
-        }}
-
-    def setUp(self):
-        super(TestKeyPairsClient, self).setUp()
-        fake_auth = fake_auth_provider.FakeAuthProvider()
-        self.client = keypairs_client.KeyPairsClient(
-            fake_auth, 'compute', 'regionOne')
-
-    def _test_list_keypairs(self, bytes_body=False):
-        self.check_service_client_function(
-            self.client.list_keypairs,
-            'tempest.lib.common.rest_client.RestClient.get',
-            {"keypairs": []},
-            bytes_body)
-
-    def test_list_keypairs_with_str_body(self):
-        self._test_list_keypairs()
-
-    def test_list_keypairs_with_bytes_body(self):
-        self._test_list_keypairs(bytes_body=True)
-
-    def _test_show_keypair(self, bytes_body=False):
-        fake_keypair = copy.deepcopy(self.FAKE_KEYPAIR)
-        fake_keypair["keypair"].update({
-            "deleted": False,
-            "created_at": "2015-07-22T04:53:52.000000",
-            "updated_at": None,
-            "deleted_at": None,
-            "id": 1
-            })
-
-        self.check_service_client_function(
-            self.client.show_keypair,
-            'tempest.lib.common.rest_client.RestClient.get',
-            fake_keypair,
-            bytes_body,
-            keypair_name="test")
-
-    def test_show_keypair_with_str_body(self):
-        self._test_show_keypair()
-
-    def test_show_keypair_with_bytes_body(self):
-        self._test_show_keypair(bytes_body=True)
-
-    def _test_create_keypair(self, bytes_body=False):
-        fake_keypair = copy.deepcopy(self.FAKE_KEYPAIR)
-        fake_keypair["keypair"].update({"private_key": "foo"})
-
-        self.check_service_client_function(
-            self.client.create_keypair,
-            'tempest.lib.common.rest_client.RestClient.post',
-            fake_keypair,
-            bytes_body,
-            name="test")
-
-    def test_create_keypair_with_str_body(self):
-        self._test_create_keypair()
-
-    def test_create_keypair_with_bytes_body(self):
-        self._test_create_keypair(bytes_body=True)
-
-    def test_delete_keypair(self):
-        self.check_service_client_function(
-            self.client.delete_keypair,
-            'tempest.lib.common.rest_client.RestClient.delete',
-            {}, status=202, keypair_name='test')
diff --git a/tempest/tests/stress/test_stress.py b/tempest/tests/stress/test_stress.py
index dfe0291..a35b4d7 100644
--- a/tempest/tests/stress/test_stress.py
+++ b/tempest/tests/stress/test_stress.py
@@ -18,7 +18,7 @@
 
 from oslo_log import log as logging
 from tempest.lib import exceptions
-from tempest.tests import base
+from tempest.tests.lib import base
 
 LOG = logging.getLogger(__name__)
 
diff --git a/tempest/tests/test_base_test.py b/tempest/tests/test_base_test.py
index dc355b4..9ffb7a1 100644
--- a/tempest/tests/test_base_test.py
+++ b/tempest/tests/test_base_test.py
@@ -19,8 +19,8 @@
 from tempest.common import fixed_network
 from tempest import config
 from tempest import test
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class TestBaseTestCase(base.TestCase):
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index 98b045a..4c9a3b7 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -22,8 +22,8 @@
 from tempest import config
 from tempest import exceptions
 from tempest import test
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class BaseDecoratorsTest(base.TestCase):
@@ -201,7 +201,13 @@
         if expected_to_skip:
             self.assertRaises(testtools.TestCase.skipException, t.test_bar)
         else:
-            self.assertEqual(t.test_bar(), 0)
+            try:
+                self.assertEqual(t.test_bar(), 0)
+            except testtools.TestCase.skipException:
+                # We caught a skipException but we didn't expect to skip
+                # this test so raise a hard test failure instead.
+                raise testtools.TestCase.failureException(
+                    "Not supposed to skip")
 
     def test_requires_ext_decorator(self):
         self._test_requires_ext_helper(expected_to_skip=False,
@@ -213,7 +219,7 @@
                                        service='compute')
 
     def test_requires_ext_decorator_with_all_ext_enabled(self):
-        cfg.CONF.set_default('api_extensions', 'all',
+        cfg.CONF.set_default('api_extensions', ['all'],
                              group='compute-feature-enabled')
         self._test_requires_ext_helper(expected_to_skip=False,
                                        extension='random_ext',
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
index 1811141..10f80a7 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -22,9 +22,9 @@
 
 from tempest.common import glance_http
 from tempest import exceptions
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
 from tempest.tests import fake_http
+from tempest.tests.lib import base
 
 
 class TestGlanceHTTPClient(base.TestCase):
@@ -93,29 +93,29 @@
         self.assertEqual(httplib.HTTPConnection, conn_class)
 
     def test_get_connection_http(self):
-        self.assertTrue(isinstance(self.client._get_connection(),
-                                   httplib.HTTPConnection))
+        self.assertIsInstance(self.client._get_connection(),
+                              httplib.HTTPConnection)
 
     def test_get_connection_https(self):
         endpoint = 'https://fake_url.com'
         self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
         self.client = glance_http.HTTPClient(self.fake_auth, {})
-        self.assertTrue(isinstance(self.client._get_connection(),
-                                   glance_http.VerifiedHTTPSConnection))
+        self.assertIsInstance(self.client._get_connection(),
+                              glance_http.VerifiedHTTPSConnection)
 
     def test_get_connection_ipv4_https(self):
         endpoint = 'https://127.0.0.1'
         self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
         self.client = glance_http.HTTPClient(self.fake_auth, {})
-        self.assertTrue(isinstance(self.client._get_connection(),
-                                   glance_http.VerifiedHTTPSConnection))
+        self.assertIsInstance(self.client._get_connection(),
+                              glance_http.VerifiedHTTPSConnection)
 
     def test_get_connection_ipv6_https(self):
         endpoint = 'https://[::1]'
         self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
         self.client = glance_http.HTTPClient(self.fake_auth, {})
-        self.assertTrue(isinstance(self.client._get_connection(),
-                                   glance_http.VerifiedHTTPSConnection))
+        self.assertIsInstance(self.client._get_connection(),
+                              glance_http.VerifiedHTTPSConnection)
 
     def test_get_connection_url_not_fount(self):
         self.useFixture(mockpatch.PatchObject(self.client, 'connection_class',
diff --git a/tempest/tests/test_hacking.py b/tempest/tests/test_hacking.py
index aba2aab..6b3aa0d 100644
--- a/tempest/tests/test_hacking.py
+++ b/tempest/tests/test_hacking.py
@@ -13,7 +13,7 @@
 #    under the License.
 
 from tempest.hacking import checks
-from tempest.tests import base
+from tempest.tests.lib import base
 
 
 class HackingTestCase(base.TestCase):
diff --git a/tempest/tests/test_list_tests.py b/tempest/tests/test_list_tests.py
index 38d4c5c..69527b1 100644
--- a/tempest/tests/test_list_tests.py
+++ b/tempest/tests/test_list_tests.py
@@ -17,7 +17,7 @@
 import six
 import subprocess
 
-from tempest.tests import base
+from tempest.tests.lib import base
 
 
 class TestTestList(base.TestCase):
diff --git a/tempest/tests/test_microversions.py b/tempest/tests/test_microversions.py
index cef7975..1ac1232 100644
--- a/tempest/tests/test_microversions.py
+++ b/tempest/tests/test_microversions.py
@@ -18,8 +18,8 @@
 from tempest.api.compute import base as compute_base
 from tempest import config
 from tempest.lib import exceptions
-from tempest.tests import base
 from tempest.tests import fake_config
+from tempest.tests.lib import base
 
 
 class VersionTestNoneTolatest(compute_base.BaseV2ComputeTest):
diff --git a/tempest/tests/test_negative_rest_client.py b/tempest/tests/test_negative_rest_client.py
index ce95739..6a071b1 100644
--- a/tempest/tests/test_negative_rest_client.py
+++ b/tempest/tests/test_negative_rest_client.py
@@ -20,10 +20,10 @@
 
 from tempest.common import negative_rest_client
 from tempest import config
-from tempest.tests import base
 from tempest.tests import fake_auth_provider
 from tempest.tests import fake_config
 from tempest.tests import fake_http
+from tempest.tests.lib import base
 
 
 class TestNegativeRestClient(base.TestCase):
diff --git a/tempest/tests/test_tempest_plugin.py b/tempest/tests/test_tempest_plugin.py
index c07e98c..f66dfc8 100644
--- a/tempest/tests/test_tempest_plugin.py
+++ b/tempest/tests/test_tempest_plugin.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 from tempest.test_discover import plugins
-from tempest.tests import base
 from tempest.tests import fake_tempest_plugin as fake_plugin
+from tempest.tests.lib import base
 
 
 class TestPluginDiscovery(base.TestCase):
diff --git a/tempest/tests/test_wrappers.py b/tempest/tests/test_wrappers.py
index a4ef699..edb9061 100644
--- a/tempest/tests/test_wrappers.py
+++ b/tempest/tests/test_wrappers.py
@@ -19,7 +19,7 @@
 
 import six
 
-from tempest.tests import base
+from tempest.tests.lib import base
 
 DEVNULL = open(os.devnull, 'wb')
 
diff --git a/test-requirements.txt b/test-requirements.txt
index be3a4f1..bb4b27f 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -6,7 +6,7 @@
 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
-reno>=0.1.1 # Apache2
+reno>=1.6.2 # Apache2
 mox>=0.5.3 # Apache-2.0
 mock>=1.2 # BSD
 coverage>=3.6 # Apache-2.0
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
new file mode 100644
index 0000000..03dbd9b
--- /dev/null
+++ b/tools/generate-tempest-plugins-list.py
@@ -0,0 +1,70 @@
+#! /usr/bin/env python
+
+# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# This script is intended to be run as part of a periodic proposal bot
+# job in OpenStack infrastructure.
+#
+# In order to function correctly, the environment in which the
+# script runs must have
+#   * network access to the review.openstack.org Gerrit API
+#     working directory
+#   * network access to https://git.openstack.org/cgit
+
+import json
+import re
+import requests
+
+url = 'https://review.openstack.org/projects/'
+
+# This is what a project looks like
+'''
+  "openstack-attic/akanda": {
+    "id": "openstack-attic%2Fakanda",
+    "state": "READ_ONLY"
+  },
+'''
+
+
+def is_in_openstack_namespace(proj):
+    return proj.startswith('openstack/')
+
+# Rather than returning a 404 for a nonexistent file, cgit delivers a
+# 0-byte response to a GET request.  It also does not provide a
+# Content-Length in a HEAD response, so the way we tell if a file exists
+# is to check the length of the entire GET response body.
+
+
+def has_tempest_plugin(proj):
+    r = requests.get(
+        "https://git.openstack.org/cgit/%s/plain/setup.cfg" % proj)
+    p = re.compile('^tempest\.test_plugins', re.M)
+    if p.findall(r.text):
+        return True
+    else:
+        False
+
+r = requests.get(url)
+# Gerrit prepends 4 garbage octets to the JSON, in order to counter
+# cross-site scripting attacks.  Therefore we must discard it so the
+# json library won't choke.
+projects = sorted(filter(is_in_openstack_namespace, json.loads(r.text[4:])))
+
+found_plugins = filter(has_tempest_plugin, projects)
+
+# Every element of the found_plugins list begins with "openstack/".
+# We drop those initial 10 octets when printing the list.
+for project in found_plugins:
+    print(project[10:])
diff --git a/tools/generate-tempest-plugins-list.sh b/tools/generate-tempest-plugins-list.sh
new file mode 100755
index 0000000..ecff508
--- /dev/null
+++ b/tools/generate-tempest-plugins-list.sh
@@ -0,0 +1,64 @@
+#!/bin/bash -ex
+
+# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# This script is intended to be run as a periodic proposal bot job
+# in OpenStack infrastructure, though you can run it as a one-off.
+#
+# In order to function correctly, the environment in which the
+# script runs must have
+#   * a writable doc/source directory relative to the current
+#     working directory
+#   AND ( (
+#   * git
+#   * all git repos meant to be searched for plugins cloned and
+#     at the desired level of up-to-datedness
+#   * the environment variable git_dir pointing to the location
+#   * of said git repositories
+#   ) OR (
+#   * network access to the review.openstack.org Gerrit API
+#     working directory
+#   * network access to https://git.openstack.org/cgit
+#   ))
+#
+# If a file named data/tempest-plugins-registry.header or
+# data/tempest-plugins-registry.footer is found relative to the
+# current working directory, it will be prepended or appended to
+# the generated reStructuredText plugins table respectively.
+
+(
+declare -A plugins
+
+if [[ -r data/tempest-plugins-registry.header ]]; then
+    cat data/tempest-plugins-registry.header
+fi
+
+sorted_plugins=$(python tools/generate-tempest-plugins-list.py)
+
+for k in ${sorted_plugins}; do
+    project=${k:0:28}
+    giturl="git://git.openstack.org/openstack/${k:0:26}"
+    printf "|%-28s|%-73s|\n" "${project}" "${giturl}"
+    printf "+----------------------------+-------------------------------------------------------------------------+\n"
+done
+
+if [[ -r data/tempest-plugins-registry.footer ]]; then
+    cat data/tempest-plugins-registry.footer
+fi
+) > doc/source/plugin-registry.rst
+
+if [[ -n ${1} ]]; then
+    cp doc/source/plugin-registry.rst ${1}/doc/source/plugin-registry.rst
+fi