Merge "Remove _create_router in scenario.manager"
diff --git a/README.rst b/README.rst
index 17d4cba..c67362a 100644
--- a/README.rst
+++ b/README.rst
@@ -183,11 +183,11 @@
 Tempest also has a set of unit tests which test the Tempest code itself. These
 tests can be run by specifying the test discovery path::
 
-    $ OS_TEST_PATH=./tempest/tests testr run --parallel
+    $ stestr --test-path ./tempest/tests run
 
-By setting OS_TEST_PATH to ./tempest/tests it specifies that test discover
-should only be run on the unit test directory. The default value of OS_TEST_PATH
-is OS_TEST_PATH=./tempest/test_discover which will only run test discover on the
+By setting ``--test-path`` option to ./tempest/tests it specifies that test discover
+should only be run on the unit test directory. The default value of ``test_path``
+is ``test_path=./tempest/test_discover`` which will only run test discover on the
 Tempest suite.
 
 Alternatively, there are the py27 and py35 tox jobs which will run the unit
diff --git a/doc/source/plugin.rst b/doc/source/plugin.rst
index 77ef9ed..2afb1e5 100644
--- a/doc/source/plugin.rst
+++ b/doc/source/plugin.rst
@@ -29,6 +29,8 @@
 * tempest.config
 * tempest.test_discover.plugins
 * tempest.common.credentials_factory
+* tempest.clients
+* tempest.test
 
 If there is an interface from tempest that you need to rely on in your plugin
 which is not listed above, it likely needs to be migrated to tempest.lib. In
diff --git a/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml b/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml
new file mode 100644
index 0000000..87a6af9
--- /dev/null
+++ b/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml
@@ -0,0 +1,17 @@
+---
+fixes:
+  - |
+    Allow to specify new domain parameters:
+
+    * `user_domain_name`
+    * `user_domain_id`
+    * `project_domain_name`
+    * `project_domain_id`
+
+    for CLIClient class, whose values will be substituted to
+    ``--os-user-domain-name``, ``--os-user-domain-id``,
+    ``--os-project-domain-name`` and ``--os-project-domain-id`` respectively
+    during command execution.
+
+    This allows to prevent possible test failures with authentication in
+    Keystone v3. Bug: #1719687
diff --git a/releasenotes/notes/add-load-list-cmd-35a4a2e6ea0a36fd.yaml b/releasenotes/notes/add-load-list-cmd-35a4a2e6ea0a36fd.yaml
new file mode 100644
index 0000000..403bbad
--- /dev/null
+++ b/releasenotes/notes/add-load-list-cmd-35a4a2e6ea0a36fd.yaml
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    Adds a new cli option to tempest run, --load-list <list-file>
+    to specify target tests to run from a list-file. The list-file
+    supports the output format of the tempest run --list-tests
+    command.
diff --git a/releasenotes/notes/add_proxy_url_get_credentials-aef66b085450513f.yaml b/releasenotes/notes/add_proxy_url_get_credentials-aef66b085450513f.yaml
new file mode 100644
index 0000000..94ab462
--- /dev/null
+++ b/releasenotes/notes/add_proxy_url_get_credentials-aef66b085450513f.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Add the proxy_url optional parameter to the get_credentials method in
+    tempest/lib/auth.py so that that helper can be used when going through
+    and HTTP proxy.
diff --git a/releasenotes/notes/disable-identity-v2-testing-4ef1565d1a5aedcf.yaml b/releasenotes/notes/disable-identity-v2-testing-4ef1565d1a5aedcf.yaml
new file mode 100644
index 0000000..e5d4ab7
--- /dev/null
+++ b/releasenotes/notes/disable-identity-v2-testing-4ef1565d1a5aedcf.yaml
@@ -0,0 +1,7 @@
+---
+upgrade:
+  - |
+    As of the Queens release, tempest no longer tests the identity v2.0 API
+    because the majority of the v2.0 API have been removed from the identity
+    project. Once the Queens release reaches end-of-life, we can remove the
+    v2.0 tempest tests and clean up v2.0 testing cruft.
diff --git a/releasenotes/notes/drop-DEFAULT_PARAMS-bfcc2e7b74ef880b.yaml b/releasenotes/notes/drop-DEFAULT_PARAMS-bfcc2e7b74ef880b.yaml
new file mode 100644
index 0000000..c9a49a7
--- /dev/null
+++ b/releasenotes/notes/drop-DEFAULT_PARAMS-bfcc2e7b74ef880b.yaml
@@ -0,0 +1,13 @@
+---
+upgrade:
+  - |
+    Replace any call in your code to credentials_factory.DEFAULT_PARAMS with
+    a call to config.service_client_config().
+fixes:
+  - |
+    The credentials_factory module used to load configuration at import time
+    which caused configuration being loaded at test discovery time.
+    This was fixed by removing the DEFAULT_PARAMS variable. This variable
+    was redundant (and outdated), the same dictionary (but up to date) can
+    be obtained via invoking config.service_client_config() with no service
+    parameter.
diff --git a/releasenotes/notes/http_proxy_config-cb39b55520e84db5.yaml b/releasenotes/notes/http_proxy_config-cb39b55520e84db5.yaml
new file mode 100644
index 0000000..56969de
--- /dev/null
+++ b/releasenotes/notes/http_proxy_config-cb39b55520e84db5.yaml
@@ -0,0 +1,9 @@
+---
+features:
+  - Adds a new config options, ``proxy_url``. This options is used to configure
+    running tempest through a proxy server.
+  - The RestClient class in tempest.lib.rest_client has a new kwarg parameters,
+    ``proxy_url``, that is used to set a proxy server.
+  - A new class was added to tempest.lib.http, ClosingProxyHttp. This behaves
+    identically to ClosingHttp except that it requires a proxy url and will
+    establish a connection through a proxy
diff --git a/releasenotes/notes/intermediate-queens-release-2f9f305775fca454.yaml b/releasenotes/notes/intermediate-queens-release-2f9f305775fca454.yaml
new file mode 100644
index 0000000..1493b0b
--- /dev/null
+++ b/releasenotes/notes/intermediate-queens-release-2f9f305775fca454.yaml
@@ -0,0 +1,4 @@
+---
+prelude: >
+    This is an intermediate release during the Queens development cycle to
+    make new functionality available to plugins and other consumers.
diff --git a/releasenotes/notes/make-account-client-as-stable-interface-d1b07c7e8f17bef6.yaml b/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
similarity index 84%
rename from releasenotes/notes/make-account-client-as-stable-interface-d1b07c7e8f17bef6.yaml
rename to releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
index 9d5a1f5..2bba952 100644
--- a/releasenotes/notes/make-account-client-as-stable-interface-d1b07c7e8f17bef6.yaml
+++ b/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
@@ -7,3 +7,5 @@
     without any maintenance changes.
 
       * account_client
+      * container_client
+      * object_client
diff --git a/releasenotes/notes/remove-get-ipv6-addr-by-EUI64-c79972d799c7a430.yaml b/releasenotes/notes/remove-get-ipv6-addr-by-EUI64-c79972d799c7a430.yaml
new file mode 100644
index 0000000..609000c
--- /dev/null
+++ b/releasenotes/notes/remove-get-ipv6-addr-by-EUI64-c79972d799c7a430.yaml
@@ -0,0 +1,5 @@
+---
+upgrade:
+  - |
+    Remove deprecated get_ipv6_addr_by_EUI64 method from data_utils.
+    Use the same method from oslo_utils.netutils.
diff --git a/releasenotes/notes/test-clients-stable-for-plugin-90b1e7dc83f28ccd.yaml b/releasenotes/notes/test-clients-stable-for-plugin-90b1e7dc83f28ccd.yaml
new file mode 100644
index 0000000..e27ee33
--- /dev/null
+++ b/releasenotes/notes/test-clients-stable-for-plugin-90b1e7dc83f28ccd.yaml
@@ -0,0 +1,8 @@
+---
+features:
+  - |
+    Two extra modules are now marked as stable for plugins, test.py and clients.py.
+    The former includes the test base class with its automatic credentials
+    provisioning and test resource managing fixtures.
+    The latter is built on top of ServiceClients and it adds aliases and a few custom
+    configurations to it.
diff --git a/requirements.txt b/requirements.txt
index 911f0e5..8a2fa99 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,7 +2,7 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 pbr!=2.1.0,>=2.0.0 # Apache-2.0
-cliff>=2.8.0 # Apache-2.0
+cliff!=2.9.0,>=2.8.0 # Apache-2.0
 jsonschema<3.0.0,>=2.6.0 # MIT
 testtools>=1.4.0 # MIT
 paramiko>=2.0.0 # LGPLv2.1+
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index 41be620..36ff09e 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -27,7 +27,6 @@
     def setup_clients(cls):
         super(AggregatesAdminNegativeTestJSON, cls).setup_clients()
         cls.client = cls.os_admin.aggregates_client
-        cls.user_client = cls.aggregates_client
 
     @classmethod
     def resource_setup(cls):
@@ -52,7 +51,7 @@
         # Regular user is not allowed to create an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.create_aggregate,
+                          self.aggregates_client.create_aggregate,
                           name=aggregate_name)
 
     @decorators.attr(type=['negative'])
@@ -87,7 +86,7 @@
         # Regular user is not allowed to delete an aggregate.
         aggregate = self._create_test_aggregate()
         self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.delete_aggregate,
+                          self.aggregates_client.delete_aggregate,
                           aggregate['id'])
 
     @decorators.attr(type=['negative'])
@@ -95,7 +94,7 @@
     def test_aggregate_list_as_user(self):
         # Regular user is not allowed to list aggregates.
         self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.list_aggregates)
+                          self.aggregates_client.list_aggregates)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('557cad12-34c9-4ff4-95f0-22f0dfbaf7dc')
@@ -103,7 +102,7 @@
         # Regular user is not allowed to get aggregate details.
         aggregate = self._create_test_aggregate()
         self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.show_aggregate,
+                          self.aggregates_client.show_aggregate,
                           aggregate['id'])
 
     @decorators.attr(type=['negative'])
@@ -140,7 +139,7 @@
         # Regular user is not allowed to add a host to an aggregate.
         aggregate = self._create_test_aggregate()
         self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.add_host,
+                          self.aggregates_client.add_host,
                           aggregate['id'], host=self.host)
 
     @decorators.attr(type=['negative'])
@@ -168,7 +167,7 @@
                         host=self.host)
 
         self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.remove_host,
+                          self.aggregates_client.remove_host,
                           aggregate['id'], host=self.host)
 
     @decorators.attr(type=['negative'])
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 14be947..411159b 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -46,6 +46,18 @@
                 "Less than 2 compute nodes, skipping migration test.")
 
     @classmethod
+    def setup_credentials(cls):
+        # These tests don't attempt any SSH validation nor do they use
+        # floating IPs on the instance, so all we need is a network and
+        # a subnet so the instance being migrated has a single port, but
+        # we need that to make sure we are properly updating the port
+        # host bindings during the live migration.
+        # TODO(mriedem): SSH validation before and after the instance is
+        # live migrated would be a nice test wrinkle addition.
+        cls.set_network_resources(network=True, subnet=True)
+        super(LiveMigrationTest, cls).setup_credentials()
+
+    @classmethod
     def setup_clients(cls):
         super(LiveMigrationTest, cls).setup_clients()
         cls.admin_migration_client = cls.os_admin.migrations_client
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 5c4767c..705814c 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -301,7 +301,7 @@
         return image
 
     @classmethod
-    def rebuild_server(cls, server_id, validatable=False, **kwargs):
+    def recreate_server(cls, server_id, validatable=False, **kwargs):
         """Destroy an existing class level server and creates a new one
 
         Some test classes use a test server that can be used by multiple
@@ -422,6 +422,23 @@
                                                 volume['id'], 'available')
         return volume
 
+    def _detach_volume(self, server, volume):
+        """Helper method to detach a volume.
+
+        Ignores 404 responses if the volume or server do not exist, or the
+        volume is already detached from the server.
+        """
+        try:
+            volume = self.volumes_client.show_volume(volume['id'])['volume']
+            # Check the status. You can only detach an in-use volume, otherwise
+            # the compute API will return a 400 response.
+            if volume['status'] == 'in-use':
+                self.servers_client.detach_volume(server['id'], volume['id'])
+        except exceptions.NotFound:
+            # Ignore 404s on detach in case the server is deleted or the volume
+            # is already detached.
+            pass
+
     def attach_volume(self, server, volume, device=None, check_reserved=False):
         """Attaches volume to server and waits for 'in-use' volume status.
 
@@ -449,9 +466,7 @@
                         self.volumes_client, volume['id'], 'available')
         # Ignore 404s on detach in case the server is deleted or the volume
         # is already detached.
-        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
-                        self.servers_client.detach_volume,
-                        server['id'], volume['id'])
+        self.addCleanup(self._detach_volume, server, volume)
         statuses = ['in-use']
         if check_reserved:
             statuses.append('reserved')
diff --git a/tempest/api/compute/floating_ips/base.py b/tempest/api/compute/floating_ips/base.py
index 142eaec..262a3c1 100644
--- a/tempest/api/compute/floating_ips/base.py
+++ b/tempest/api/compute/floating_ips/base.py
@@ -14,6 +14,10 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest.common import utils
+from tempest import config
+
+CONF = config.CONF
 
 
 class BaseFloatingIPsTest(base.BaseV2ComputeTest):
@@ -24,3 +28,17 @@
         cls.set_network_resources(network=True, subnet=True,
                                   router=True, dhcp=True)
         super(BaseFloatingIPsTest, cls).setup_credentials()
+
+    @classmethod
+    def skip_checks(cls):
+        super(BaseFloatingIPsTest, cls).skip_checks()
+        if not utils.get_service_list()['network']:
+            raise cls.skipException("network service not enabled.")
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseFloatingIPsTest, cls).setup_clients()
+        cls.client = cls.floating_ips_client
+        cls.pools_client = cls.floating_ip_pools_client
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index 8938570..2adc482 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -16,7 +16,6 @@
 import testtools
 
 from tempest.api.compute.floating_ips import base
-from tempest.common import utils
 from tempest import config
 from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
@@ -27,32 +26,7 @@
 
 class FloatingIPsTestJSON(base.BaseFloatingIPsTest):
 
-    @classmethod
-    def skip_checks(cls):
-        super(FloatingIPsTestJSON, cls).skip_checks()
-        if not utils.get_service_list()['network']:
-            raise cls.skipException("network service not enabled.")
-        if not CONF.network_feature_enabled.floating_ips:
-            raise cls.skipException("Floating ips are not available")
-
-    @classmethod
-    def setup_clients(cls):
-        super(FloatingIPsTestJSON, cls).setup_clients()
-        cls.client = cls.floating_ips_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(FloatingIPsTestJSON, cls).resource_setup()
-
-        # Server creation
-        server = cls.create_test_server(wait_until='ACTIVE')
-        cls.server_id = server['id']
-        # Floating IP creation
-        body = cls.client.create_floating_ip(
-            pool=CONF.network.floating_network_name)['floating_ip']
-        cls.addClassResourceCleanup(cls.client.delete_floating_ip, body['id'])
-        cls.floating_ip_id = body['id']
-        cls.floating_ip = body['ip']
+    max_microversion = '2.35'
 
     @decorators.idempotent_id('f7bfb946-297e-41b8-9e8c-aba8e9bb5194')
     def test_allocate_floating_ip(self):
@@ -83,6 +57,25 @@
         # Check it was really deleted.
         self.client.wait_for_resource_deletion(floating_ip_body['id'])
 
+
+class FloatingIPsAssociationTestJSON(base.BaseFloatingIPsTest):
+
+    max_microversion = '2.43'
+
+    @classmethod
+    def resource_setup(cls):
+        super(FloatingIPsAssociationTestJSON, cls).resource_setup()
+
+        # Server creation
+        cls.server = cls.create_test_server(wait_until='ACTIVE')
+        cls.server_id = cls.server['id']
+        # Floating IP creation
+        body = cls.client.create_floating_ip(
+            pool=CONF.network.floating_network_name)['floating_ip']
+        cls.addClassResourceCleanup(cls.client.delete_floating_ip, body['id'])
+        cls.floating_ip_id = body['id']
+        cls.floating_ip = body['ip']
+
     @decorators.idempotent_id('307efa27-dc6f-48a0-8cd2-162ce3ef0b52')
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index c3d7816..9257458 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -16,7 +16,6 @@
 import testtools
 
 from tempest.api.compute.floating_ips import base
-from tempest.common import utils
 from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
@@ -27,26 +26,12 @@
 
 class FloatingIPsNegativeTestJSON(base.BaseFloatingIPsTest):
 
-    @classmethod
-    def skip_checks(cls):
-        super(FloatingIPsNegativeTestJSON, cls).skip_checks()
-        if not utils.get_service_list()['network']:
-            raise cls.skipException("network service not enabled.")
-        if not CONF.network_feature_enabled.floating_ips:
-            raise cls.skipException("Floating ips are not available")
-
-    @classmethod
-    def setup_clients(cls):
-        super(FloatingIPsNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.floating_ips_client
+    max_microversion = '2.35'
 
     @classmethod
     def resource_setup(cls):
         super(FloatingIPsNegativeTestJSON, cls).resource_setup()
 
-        # Server creation
-        server = cls.create_test_server(wait_until='ACTIVE')
-        cls.server_id = server['id']
         # Generating a nonexistent floatingIP id
         body = cls.client.list_floating_ips()['floating_ips']
         floating_ip_ids = [floating_ip['id'] for floating_ip in body]
@@ -77,6 +62,17 @@
         self.assertRaises(lib_exc.NotFound, self.client.delete_floating_ip,
                           self.non_exist_id)
 
+
+class FloatingIPsAssociationNegativeTestJSON(base.BaseFloatingIPsTest):
+
+    max_microversion = '2.43'
+
+    @classmethod
+    def resource_setup(cls):
+        super(FloatingIPsAssociationNegativeTestJSON, cls).resource_setup()
+        cls.server = cls.create_test_server(wait_until='ACTIVE')
+        cls.server_id = cls.server['id']
+
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('595fa616-1a71-4670-9614-46564ac49a4c')
     def test_associate_nonexistent_floating_ip(self):
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 516c544..944f798 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -13,29 +13,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.compute import base
-from tempest.common import utils
+from tempest.api.compute.floating_ips import base
 from tempest import config
 from tempest.lib import decorators
 
 CONF = config.CONF
 
 
-class FloatingIPDetailsTestJSON(base.BaseV2ComputeTest):
+class FloatingIPDetailsTestJSON(base.BaseFloatingIPsTest):
 
-    @classmethod
-    def skip_checks(cls):
-        super(FloatingIPDetailsTestJSON, cls).skip_checks()
-        if not utils.get_service_list()['network']:
-            raise cls.skipException("network service not enabled.")
-        if not CONF.network_feature_enabled.floating_ips:
-            raise cls.skipException("Floating ips are not available")
-
-    @classmethod
-    def setup_clients(cls):
-        super(FloatingIPDetailsTestJSON, cls).setup_clients()
-        cls.client = cls.floating_ips_client
-        cls.pools_client = cls.floating_ip_pools_client
+    max_microversion = '2.35'
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
index 0ade872..d69248c 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
@@ -13,8 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.compute import base
-from tempest.common import utils
+from tempest.api.compute.floating_ips import base
 from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
@@ -23,20 +22,9 @@
 CONF = config.CONF
 
 
-class FloatingIPDetailsNegativeTestJSON(base.BaseV2ComputeTest):
+class FloatingIPDetailsNegativeTestJSON(base.BaseFloatingIPsTest):
 
-    @classmethod
-    def skip_checks(cls):
-        super(FloatingIPDetailsNegativeTestJSON, cls).skip_checks()
-        if not utils.get_service_list()['network']:
-            raise cls.skipException("network service not enabled.")
-        if not CONF.network_feature_enabled.floating_ips:
-            raise cls.skipException("Floating ips are not available")
-
-    @classmethod
-    def setup_clients(cls):
-        super(FloatingIPDetailsNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.floating_ips_client
+    max_microversion = '2.35'
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7ab18834-4a4b-4f28-a2c5-440579866695')
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 4de00ce..a2e58c9 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -52,7 +52,7 @@
             self._reset_server()
 
     def _reset_server(self):
-        self.__class__.server_id = self.rebuild_server(self.server_id)
+        self.__class__.server_id = self.recreate_server(self.server_id)
 
     @classmethod
     def skip_checks(cls):
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 4cfc665..6fe4d82 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -55,7 +55,7 @@
             self.__class__.server_id = server['id']
         except Exception:
             # Rebuild server if something happened to it during a test
-            self.__class__.server_id = self.rebuild_server(
+            self.__class__.server_id = self.recreate_server(
                 self.server_id, validatable=True)
 
     def tearDown(self):
@@ -75,7 +75,7 @@
     @classmethod
     def resource_setup(cls):
         super(ServerActionsTestJSON, cls).resource_setup()
-        cls.server_id = cls.rebuild_server(None, validatable=True)
+        cls.server_id = cls.recreate_server(None, validatable=True)
 
     @decorators.idempotent_id('6158df09-4b82-4ab3-af6d-29cf36af858d')
     @testtools.skipUnless(CONF.compute_feature_enabled.change_password,
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index 2f0f5ee..6f32b46 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -44,7 +44,6 @@
     def setup_clients(cls):
         super(ServerPersonalityTestJSON, cls).setup_clients()
         cls.client = cls.servers_client
-        cls.user_client = cls.limits_client
 
     @decorators.idempotent_id('3cfe87fd-115b-4a02-b942-7dc36a337fdf')
     def test_create_server_with_personality(self):
@@ -104,7 +103,7 @@
         # number of files are injected into the server.
         file_contents = 'This is a test file.'
         personality = []
-        limits = self.user_client.show_limits()['limits']
+        limits = self.limits_client.show_limits()['limits']
         max_file_limit = limits['absolute']['maxPersonality']
         if max_file_limit == -1:
             raise self.skipException("No limit for personality files")
@@ -123,7 +122,7 @@
         # Server should be created successfully if maximum allowed number of
         # files is injected into the server during creation.
         file_contents = 'This is a test file.'
-        limits = self.user_client.show_limits()['limits']
+        limits = self.limits_client.show_limits()['limits']
         max_file_limit = limits['absolute']['maxPersonality']
         if max_file_limit == -1:
             raise self.skipException("No limit for personality files")
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 8170b28..d067bb3 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -37,7 +37,7 @@
             waiters.wait_for_server_status(self.client, self.server_id,
                                            'ACTIVE')
         except Exception:
-            self.__class__.server_id = self.rebuild_server(self.server_id)
+            self.__class__.server_id = self.recreate_server(self.server_id)
 
     def tearDown(self):
         self.server_check_teardown()
@@ -551,7 +551,7 @@
             waiters.wait_for_server_status(self.servers_client, self.server_id,
                                            'ACTIVE')
         except Exception:
-            self.__class__.server_id = self.rebuild_server(self.server_id)
+            self.__class__.server_id = self.recreate_server(self.server_id)
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/identity/admin/v3/test_oauth_consumers.py b/tempest/api/identity/admin/v3/test_oauth_consumers.py
index 970ead3..062cce5 100644
--- a/tempest/api/identity/admin/v3/test_oauth_consumers.py
+++ b/tempest/api/identity/admin/v3/test_oauth_consumers.py
@@ -17,7 +17,7 @@
 from tempest.lib.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
-from tempest.lib import exceptions as exceptions
+from tempest.lib import exceptions
 
 
 class OAUTHConsumersV3Test(base.BaseIdentityV3AdminTest):
diff --git a/tempest/api/object_storage/test_object_expiry.py b/tempest/api/object_storage/test_object_expiry.py
index ed1be90..86f7c8c 100644
--- a/tempest/api/object_storage/test_object_expiry.py
+++ b/tempest/api/object_storage/test_object_expiry.py
@@ -40,10 +40,10 @@
     def _test_object_expiry(self, metadata):
         # update object metadata
         resp, _ = \
-            self.object_client.update_object_metadata(self.container_name,
-                                                      self.object_name,
-                                                      metadata,
-                                                      metadata_prefix='')
+            self.object_client.create_or_update_object_metadata(
+                self.container_name,
+                self.object_name,
+                headers=metadata)
         # verify object metadata
         resp, _ = \
             self.object_client.list_object_metadata(self.container_name,
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 61cbe30..acb578d 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -48,8 +48,9 @@
         data_segments = [data + str(i) for i in range(segments)]
         # uploading segments
         for i in range(segments):
-            self.object_client.create_object_segments(
-                self.container_name, object_name, i, data_segments[i])
+            obj_name = "%s/%s" % (object_name, i)
+            self.object_client.create_object(
+                self.container_name, obj_name, data_segments[i])
 
         return object_name, data_segments
 
@@ -184,12 +185,15 @@
         # create object with transfer_encoding
         object_name = data_utils.rand_name(name='TestObject')
         data = data_utils.random_bytes(1024)
-        _, _, resp_headers = self.object_client.put_object_with_chunk(
-            container=self.container_name,
-            name=object_name,
-            contents=data_utils.chunkify(data, 512)
-        )
-        self.assertHeaders(resp_headers, 'Object', 'PUT')
+        headers = {'Transfer-Encoding': 'chunked'}
+        resp, _ = self.object_client.create_object(
+            self.container_name,
+            object_name,
+            data=data_utils.chunkify(data, 512),
+            headers=headers,
+            chunked=True)
+
+        self.assertHeaders(resp, 'Object', 'PUT')
 
         # check uploaded content
         _, body = self.object_client.get_object(self.container_name,
@@ -325,11 +329,10 @@
         object_name, _ = self.create_object(self.container_name)
 
         metadata = {'X-Object-Meta-test-meta': 'Meta'}
-        resp, _ = self.object_client.update_object_metadata(
+        resp, _ = self.object_client.create_or_update_object_metadata(
             self.container_name,
             object_name,
-            metadata,
-            metadata_prefix='')
+            headers=metadata)
         self.assertHeaders(resp, 'Object', 'POST')
 
         resp, _ = self.object_client.list_object_metadata(
@@ -350,11 +353,10 @@
                                          metadata=create_metadata)
 
         update_metadata = {'X-Remove-Object-Meta-test-meta1': 'Meta1'}
-        resp, _ = self.object_client.update_object_metadata(
+        resp, _ = self.object_client.create_or_update_object_metadata(
             self.container_name,
             object_name,
-            update_metadata,
-            metadata_prefix='')
+            headers=update_metadata)
         self.assertHeaders(resp, 'Object', 'POST')
 
         resp, _ = self.object_client.list_object_metadata(
@@ -375,11 +377,10 @@
 
         update_metadata = {'X-Object-Meta-test-meta2': 'Meta2',
                            'X-Remove-Object-Meta-test-meta1': 'Meta1'}
-        resp, _ = self.object_client.update_object_metadata(
+        resp, _ = self.object_client.create_or_update_object_metadata(
             self.container_name,
             object_name,
-            update_metadata,
-            metadata_prefix='')
+            headers=update_metadata)
         self.assertHeaders(resp, 'Object', 'POST')
 
         resp, _ = self.object_client.list_object_metadata(
@@ -403,11 +404,10 @@
                                          metadata=None)
         object_prefix = '%s/%s' % (self.container_name, object_name)
         update_metadata = {'X-Object-Manifest': object_prefix}
-        resp, _ = self.object_client.update_object_metadata(
+        resp, _ = self.object_client.create_or_update_object_metadata(
             self.container_name,
             object_name,
-            update_metadata,
-            metadata_prefix='')
+            headers=update_metadata)
         self.assertHeaders(resp, 'Object', 'POST')
 
         resp, _ = self.object_client.list_object_metadata(
@@ -422,11 +422,10 @@
         object_name, _ = self.create_object(self.container_name)
 
         update_metadata = {'X-Object-Meta-test-meta': ''}
-        resp, _ = self.object_client.update_object_metadata(
+        resp, _ = self.object_client.create_or_update_object_metadata(
             self.container_name,
             object_name,
-            update_metadata,
-            metadata_prefix='')
+            headers=update_metadata)
         self.assertHeaders(resp, 'Object', 'POST')
 
         resp, _ = self.object_client.list_object_metadata(
@@ -447,11 +446,10 @@
                                          metadata=create_metadata)
 
         update_metadata = {'X-Remove-Object-Meta-test-meta': ''}
-        resp, _ = self.object_client.update_object_metadata(
+        resp, _ = self.object_client.create_or_update_object_metadata(
             self.container_name,
             object_name,
-            update_metadata,
-            metadata_prefix='')
+            headers=update_metadata)
         self.assertHeaders(resp, 'Object', 'POST')
 
         resp, _ = self.object_client.list_object_metadata(
@@ -728,8 +726,13 @@
                                                    dst_object_name,
                                                    dst_data)
         # copy source object to destination
-        resp, _ = self.object_client.copy_object_in_same_container(
-            self.container_name, src_object_name, dst_object_name)
+        headers = {}
+        headers['X-Copy-From'] = "%s/%s" % (str(self.container_name),
+                                            str(src_object_name))
+        resp, body = self.object_client.create_object(self.container_name,
+                                                      dst_object_name,
+                                                      data=None,
+                                                      headers=headers)
         self.assertHeaders(resp, 'Object', 'PUT')
 
         # check data
@@ -749,8 +752,14 @@
         # change the content type of the object
         metadata = {'content-type': 'text/plain; charset=UTF-8'}
         self.assertNotEqual(resp_tmp['content-type'], metadata['content-type'])
-        resp, _ = self.object_client.copy_object_in_same_container(
-            self.container_name, object_name, object_name, metadata)
+        headers = {}
+        headers['X-Copy-From'] = "%s/%s" % (str(self.container_name),
+                                            str(object_name))
+        resp, body = self.object_client.create_object(self.container_name,
+                                                      object_name,
+                                                      data=None,
+                                                      metadata=metadata,
+                                                      headers=headers)
         self.assertHeaders(resp, 'Object', 'PUT')
 
         # check the content type
@@ -801,16 +810,21 @@
         # set object metadata
         meta_key = data_utils.rand_name(name='test')
         meta_value = data_utils.rand_name(name='MetaValue')
-        orig_metadata = {meta_key: meta_value}
-        resp, _ = self.object_client.update_object_metadata(src_container_name,
-                                                            object_name,
-                                                            orig_metadata)
+        orig_metadata = {'X-Object-Meta-' + meta_key: meta_value}
+        resp, _ = self.object_client.create_or_update_object_metadata(
+            src_container_name,
+            object_name,
+            headers=orig_metadata)
         self.assertHeaders(resp, 'Object', 'POST')
 
         # copy object from source container to destination container
-        resp, _ = self.object_client.copy_object_across_containers(
-            src_container_name, object_name, dst_container_name,
-            object_name)
+        headers = {}
+        headers['X-Copy-From'] = "%s/%s" % (str(src_container_name),
+                                            str(object_name))
+        resp, body = self.object_client.create_object(dst_container_name,
+                                                      object_name,
+                                                      data=None,
+                                                      headers=headers)
         self.assertHeaders(resp, 'Object', 'PUT')
 
         # check if object is present in destination container
@@ -897,8 +911,9 @@
         data_segments = [data + str(i) for i in range(segments)]
         # uploading segments
         for i in range(segments):
-            resp, _ = self.object_client.create_object_segments(
-                self.container_name, object_name, i, data_segments[i])
+            obj_name = "%s/%s" % (object_name, i)
+            resp, _ = self.object_client.create_object(
+                self.container_name, obj_name, data_segments[i])
         # creating a manifest file
         metadata = {'X-Object-Manifest': '%s/%s/'
                     % (self.container_name, object_name)}
@@ -906,8 +921,8 @@
                                                    object_name, data='')
         self.assertHeaders(resp, 'Object', 'PUT')
 
-        resp, _ = self.object_client.update_object_metadata(
-            self.container_name, object_name, metadata, metadata_prefix='')
+        resp, _ = self.object_client.create_or_update_object_metadata(
+            self.container_name, object_name, headers=metadata)
         self.assertHeaders(resp, 'Object', 'POST')
 
         resp, _ = self.object_client.list_object_metadata(
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index b5a2fb7..730acdf 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -46,14 +46,32 @@
             self.volume_type['id'], extra_specs)['extra_specs']
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly created")
+
+        # Only update an extra spec
         spec_key = "spec2"
         extra_spec = {spec_key: "val2"}
         body = self.admin_volume_types_client.update_volume_type_extra_specs(
             self.volume_type['id'], spec_key, extra_spec)
         self.assertIn(spec_key, body)
+        self.assertEqual(extra_spec[spec_key], body[spec_key])
+        body = self.admin_volume_types_client.show_volume_type_extra_specs(
+            self.volume_type['id'], spec_key)
+        self.assertIn(spec_key, body)
         self.assertEqual(extra_spec[spec_key], body[spec_key],
                          "Volume type extra spec incorrectly updated")
 
+        # Update an existing extra spec and create a new extra spec
+        extra_specs = {spec_key: "val3", "spec4": "val4"}
+        body = self.admin_volume_types_client.create_volume_type_extra_specs(
+            self.volume_type['id'], extra_specs)['extra_specs']
+        self.assertEqual(extra_specs, body)
+        body = self.admin_volume_types_client.list_volume_types_extra_specs(
+            self.volume_type['id'])['extra_specs']
+        for key in extra_specs:
+            self.assertIn(key, body)
+            self.assertEqual(extra_specs[key], body[key],
+                             "Volume type extra spec incorrectly created")
+
     @decorators.idempotent_id('d4772798-601f-408a-b2a5-29e8a59d1220')
     def test_volume_type_extra_spec_create_get_delete(self):
         # Create/Get/Delete volume type extra spec.
diff --git a/tempest/clients.py b/tempest/clients.py
index e617c3c..ca205c8 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -17,7 +17,6 @@
 from tempest.lib import auth
 from tempest.lib import exceptions as lib_exc
 from tempest.lib.services import clients
-from tempest.services import object_storage
 
 CONF = config.CONF
 
@@ -25,8 +24,6 @@
 class Manager(clients.ServiceClients):
     """Top level manager for OpenStack tempest clients"""
 
-    default_params = config.service_client_config()
-
     def __init__(self, credentials, scope='project'):
         """Initialization of Manager class.
 
@@ -47,6 +44,10 @@
         self._set_object_storage_clients()
         self._set_image_clients()
         self._set_network_clients()
+        # TODO(andreaf) This is maintained for backward compatibility
+        # with plugins, but it should removed eventually, since it was
+        # never a stable interface and it's not useful anyways
+        self.default_params = config.service_client_config()
 
     def _set_network_clients(self):
         self.network_agents_client = self.network.AgentsClient()
@@ -281,21 +282,11 @@
             self.snapshots_client_latest = self.snapshots_v3_client
 
     def _set_object_storage_clients(self):
-        # NOTE(andreaf) Load configuration from config. Once object storage
-        # is in lib, configuration will be pulled directly from the registry
-        # and this will not be required anymore.
-        params = config.service_client_config('object-storage')
-
-        self.account_client = object_storage.AccountClient(self.auth_provider,
-                                                           **params)
-        self.bulk_client = object_storage.BulkMiddlewareClient(
-            self.auth_provider, **params)
-        self.capabilities_client = object_storage.CapabilitiesClient(
-            self.auth_provider, **params)
-        self.container_client = object_storage.ContainerClient(
-            self.auth_provider, **params)
-        self.object_client = object_storage.ObjectClient(self.auth_provider,
-                                                         **params)
+        self.account_client = self.object_storage.AccountClient()
+        self.bulk_client = self.object_storage.BulkMiddlewareClient()
+        self.capabilities_client = self.object_storage.CapabilitiesClient()
+        self.container_client = self.object_storage.ContainerClient()
+        self.object_client = self.object_storage.ObjectClient()
 
 
 def get_auth_provider_class(credentials):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index a72493d..fdf28d5 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -76,7 +76,6 @@
 from tempest import config
 import tempest.lib.common.http
 from tempest.lib import exceptions as lib_exc
-from tempest.services import object_storage
 
 
 CONF = config.CONF
@@ -197,10 +196,6 @@
 def verify_keystone_api_versions(os, update):
     # Check keystone api versions
     versions = _get_api_versions(os, 'keystone')
-    if (CONF.identity_feature_enabled.api_v2 !=
-            contains_version('v2.', versions)):
-        print_and_or_update('api_v2', 'identity-feature-enabled',
-                            not CONF.identity_feature_enabled.api_v2, update)
     if (CONF.identity_feature_enabled.api_v3 !=
             contains_version('v3.', versions)):
         print_and_or_update('api_v3', 'identity-feature-enabled',
@@ -236,11 +231,10 @@
 
 
 def get_extension_client(os, service):
-    params = config.service_client_config('object-storage')
     extensions_client = {
         'nova': os.compute.ExtensionsClient(),
         'neutron': os.network.ExtensionsClient(),
-        'swift': object_storage.CapabilitiesClient(os.auth_provider, **params),
+        'swift': os.object_storage.CapabilitiesClient(),
         # NOTE: Cinder v3 API is current and v2 and v1 are deprecated.
         # V3 extension API is the same as v2, so we reuse the v2 client
         # for v3 API also.
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index a340531..da34975 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -219,13 +219,6 @@
     'alt_user': ('identity', 'alt')
 }
 
-DEFAULT_PARAMS = {
-    'disable_ssl_certificate_validation':
-        CONF.identity.disable_ssl_certificate_validation,
-    'ca_certs': CONF.identity.ca_certificates_file,
-    'trace_requests': CONF.debug.trace_requests
-}
-
 
 def get_configured_admin_credentials(fill_in=True, identity_version=None):
     """Get admin credentials from the config file
@@ -252,7 +245,7 @@
     if identity_version == 'v3':
         conf_attributes.append('domain_name')
     # Read the parts of credentials from config
-    params = DEFAULT_PARAMS.copy()
+    params = config.service_client_config()
     for attr in conf_attributes:
         params[attr] = getattr(CONF.auth, 'admin_' + attr)
     # Build and validate credentials. We are reading configured credentials,
@@ -282,7 +275,7 @@
     :param kwargs: Attributes to be used to build the Credentials object.
     :returns: An object of a sub-type of `auth.Credentials`
     """
-    params = dict(DEFAULT_PARAMS, **kwargs)
+    params = dict(config.service_client_config(), **kwargs)
     identity_version = identity_version or CONF.identity.auth_version
     # In case of "v3" add the domain from config if not specified
     # To honour the "default_credentials_domain_name", if not domain
diff --git a/tempest/config.py b/tempest/config.py
index 024a638..0743220 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -194,6 +194,8 @@
                default=60,
                help='Timeout in seconds to wait for the http request to '
                     'return'),
+    cfg.StrOpt('proxy_url',
+               help='Specify an http proxy to use.')
 ]
 
 identity_feature_group = cfg.OptGroup(name='identity-feature-enabled',
@@ -205,8 +207,14 @@
                 help='Does the identity service have delegation and '
                      'impersonation enabled'),
     cfg.BoolOpt('api_v2',
-                default=True,
-                help='Is the v2 identity API enabled'),
+                default=False,
+                help='Is the v2 identity API enabled',
+                deprecated_for_removal=True,
+                deprecated_reason='The identity v2.0 API was removed in the '
+                                  'Queens release. Tests that exercise the '
+                                  'v2.0 API will be removed from tempest in '
+                                  'the v22.0.0 release. They are kept only to '
+                                  'test stable branches.'),
     cfg.BoolOpt('api_v2_admin',
                 default=True,
                 help="Is the v2 identity admin API available? This setting "
@@ -1308,6 +1316,7 @@
         * `ca_certs`
         * `trace_requests`
         * `http_timeout`
+        * `proxy_url`
 
     The dict returned by this does not fit a few service clients:
 
@@ -1330,7 +1339,8 @@
             CONF.identity.disable_ssl_certificate_validation,
         'ca_certs': CONF.identity.ca_certificates_file,
         'trace_requests': CONF.debug.trace_requests,
-        'http_timeout': CONF.service_clients.http_timeout
+        'http_timeout': CONF.service_clients.http_timeout,
+        'proxy_url': CONF.service_clients.proxy_url,
     }
 
     if service_client_name is None:
@@ -1384,7 +1394,7 @@
         module = service_clients[service_client]
         configs = service_client.split('.')[0]
         service_client_data = dict(
-            name=service_client.replace('.', '_'),
+            name=service_client.replace('.', '_').replace('-', '_'),
             service_version=service_client,
             module_path=module.__name__,
             client_names=module.__all__,
diff --git a/tempest/lib/auth.py b/tempest/lib/auth.py
index ab4308f..2dd9d00 100644
--- a/tempest/lib/auth.py
+++ b/tempest/lib/auth.py
@@ -261,12 +261,13 @@
     def __init__(self, credentials, auth_url,
                  disable_ssl_certificate_validation=None,
                  ca_certs=None, trace_requests=None, scope='project',
-                 http_timeout=None):
+                 http_timeout=None, proxy_url=None):
         super(KeystoneAuthProvider, self).__init__(credentials, scope)
         self.dscv = disable_ssl_certificate_validation
         self.ca_certs = ca_certs
         self.trace_requests = trace_requests
         self.http_timeout = http_timeout
+        self.proxy_url = proxy_url
         self.auth_url = auth_url
         self.auth_client = self._auth_client(auth_url)
 
@@ -345,7 +346,7 @@
         return json_v2id.TokenClient(
             auth_url, disable_ssl_certificate_validation=self.dscv,
             ca_certs=self.ca_certs, trace_requests=self.trace_requests,
-            http_timeout=self.http_timeout)
+            http_timeout=self.http_timeout, proxy_url=self.proxy_url)
 
     def _auth_params(self):
         """Auth parameters to be passed to the token request
@@ -433,7 +434,7 @@
         return json_v3id.V3TokenClient(
             auth_url, disable_ssl_certificate_validation=self.dscv,
             ca_certs=self.ca_certs, trace_requests=self.trace_requests,
-            http_timeout=self.http_timeout)
+            http_timeout=self.http_timeout, proxy_url=self.proxy_url)
 
     def _auth_params(self):
         """Auth parameters to be passed to the token request
@@ -599,7 +600,8 @@
 
 def get_credentials(auth_url, fill_in=True, identity_version='v2',
                     disable_ssl_certificate_validation=None, ca_certs=None,
-                    trace_requests=None, http_timeout=None, **kwargs):
+                    trace_requests=None, http_timeout=None, proxy_url=None,
+                    **kwargs):
     """Builds a credentials object based on the configured auth_version
 
     :param auth_url (string): Full URI of the OpenStack Identity API(Keystone)
@@ -617,6 +619,7 @@
     :param trace_requests: trace in log API requests to the auth system
     :param http_timeout: timeout in seconds to wait for the http request to
            return
+    :param proxy_url: URL of HTTP(s) proxy used when fill_in is True
     :param kwargs (dict): Dict of credential key/value pairs
 
     Examples:
@@ -641,7 +644,7 @@
         auth_provider = auth_provider_class(
             creds, auth_url, disable_ssl_certificate_validation=dscv,
             ca_certs=ca_certs, trace_requests=trace_requests,
-            http_timeout=http_timeout)
+            http_timeout=http_timeout, proxy_url=proxy_url)
         creds = auth_provider.fill_credentials()
     return creds
 
diff --git a/tempest/lib/cli/base.py b/tempest/lib/cli/base.py
index 5468a7b..f39ecbc 100644
--- a/tempest/lib/cli/base.py
+++ b/tempest/lib/cli/base.py
@@ -93,10 +93,20 @@
     :type insecure: boolean
     :param prefix: prefix to insert before commands
     :type prefix: string
+    :param user_domain_name: User's domain name
+    :type user_domain_name: string
+    :param user_domain_id: User's domain ID
+    :type user_domain_id: string
+    :param project_domain_name: Project's domain name
+    :type project_domain_name: string
+    :param project_domain_id: Project's domain ID
+    :type project_domain_id: string
     """
 
     def __init__(self, username='', password='', tenant_name='', uri='',
-                 cli_dir='', insecure=False, prefix='', *args, **kwargs):
+                 cli_dir='', insecure=False, prefix='', user_domain_name=None,
+                 user_domain_id=None, project_domain_name=None,
+                 project_domain_id=None, *args, **kwargs):
         """Initialize a new CLIClient object."""
         super(CLIClient, self).__init__()
         self.cli_dir = cli_dir if cli_dir else '/usr/bin'
@@ -106,6 +116,10 @@
         self.uri = uri
         self.insecure = insecure
         self.prefix = prefix
+        self.user_domain_name = user_domain_name
+        self.user_domain_id = user_domain_id
+        self.project_domain_name = project_domain_name
+        self.project_domain_id = project_domain_id
 
     def nova(self, action, flags='', params='', fail_ok=False,
              endpoint_type='publicURL', merge_stderr=False):
@@ -366,6 +380,14 @@
                   self.tenant_name,
                   self.password,
                   self.uri))
+        if self.user_domain_name is not None:
+            creds += ' --os-user-domain-name %s' % self.user_domain_name
+        if self.user_domain_id is not None:
+            creds += ' --os-user-domain-id %s' % self.user_domain_id
+        if self.project_domain_name is not None:
+            creds += ' --os-project-domain-name %s' % self.project_domain_name
+        if self.project_domain_id is not None:
+            creds += ' --os-project-domain-id %s' % self.project_domain_id
         if self.insecure:
             flags = creds + ' --insecure ' + flags
         else:
diff --git a/tempest/lib/common/http.py b/tempest/lib/common/http.py
index b4b1fc9..738c37f 100644
--- a/tempest/lib/common/http.py
+++ b/tempest/lib/common/http.py
@@ -17,6 +17,47 @@
 import urllib3
 
 
+class ClosingProxyHttp(urllib3.ProxyManager):
+    def __init__(self, proxy_url, disable_ssl_certificate_validation=False,
+                 ca_certs=None, timeout=None):
+        kwargs = {}
+
+        if disable_ssl_certificate_validation:
+            urllib3.disable_warnings()
+            kwargs['cert_reqs'] = 'CERT_NONE'
+        elif ca_certs:
+            kwargs['cert_reqs'] = 'CERT_REQUIRED'
+            kwargs['ca_certs'] = ca_certs
+
+        if timeout:
+            kwargs['timeout'] = timeout
+
+        super(ClosingProxyHttp, self).__init__(proxy_url, **kwargs)
+
+    def request(self, url, method, *args, **kwargs):
+
+        class Response(dict):
+            def __init__(self, info):
+                for key, value in info.getheaders().items():
+                    self[key.lower()] = value
+                self.status = info.status
+                self['status'] = str(self.status)
+                self.reason = info.reason
+                self.version = info.version
+                self['content-location'] = url
+
+        original_headers = kwargs.get('headers', {})
+        new_headers = dict(original_headers, connection='close')
+        new_kwargs = dict(kwargs, headers=new_headers)
+
+        # Follow up to 5 redirections. Don't raise an exception if
+        # it's exceeded but return the HTTP 3XX response instead.
+        retry = urllib3.util.Retry(raise_on_redirect=False, redirect=5)
+        r = super(ClosingProxyHttp, self).request(method, url, retries=retry,
+                                                  *args, **new_kwargs)
+        return Response(r), r.data
+
+
 class ClosingHttp(urllib3.poolmanager.PoolManager):
     def __init__(self, disable_ssl_certificate_validation=False,
                  ca_certs=None, timeout=None):
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index f58d737..22276d4 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -69,6 +69,7 @@
                               of the request and response payload
     :param str http_timeout: Timeout in seconds to wait for the http request to
                              return
+    :param str proxy_url: http proxy url to use.
     """
 
     # The version of the API this client implements
@@ -80,7 +81,8 @@
                  endpoint_type='publicURL',
                  build_interval=1, build_timeout=60,
                  disable_ssl_certificate_validation=False, ca_certs=None,
-                 trace_requests='', name=None, http_timeout=None):
+                 trace_requests='', name=None, http_timeout=None,
+                 proxy_url=None):
         self.auth_provider = auth_provider
         self.service = service
         self.region = region
@@ -100,9 +102,16 @@
                                        'retry-after', 'server',
                                        'vary', 'www-authenticate'))
         dscv = disable_ssl_certificate_validation
-        self.http_obj = http.ClosingHttp(
-            disable_ssl_certificate_validation=dscv, ca_certs=ca_certs,
-            timeout=http_timeout)
+
+        if proxy_url:
+            self.http_obj = http.ClosingProxyHttp(
+                proxy_url,
+                disable_ssl_certificate_validation=dscv, ca_certs=ca_certs,
+                timeout=http_timeout)
+        else:
+            self.http_obj = http.ClosingHttp(
+                disable_ssl_certificate_validation=dscv, ca_certs=ca_certs,
+                timeout=http_timeout)
 
     def get_headers(self, accept_type=None, send_type=None):
         """Return the default headers which will be used with outgoing requests
diff --git a/tempest/lib/common/utils/data_utils.py b/tempest/lib/common/utils/data_utils.py
index a0941ef..c5df590 100644
--- a/tempest/lib/common/utils/data_utils.py
+++ b/tempest/lib/common/utils/data_utils.py
@@ -18,9 +18,6 @@
 import string
 import uuid
 
-from debtcollector import removals
-import netaddr
-from oslo_utils import netutils
 from oslo_utils import uuidutils
 import six.moves
 
@@ -177,36 +174,6 @@
                     for i in range(size)])
 
 
-@removals.remove(
-    message="use get_ipv6_addr_by_EUI64 from oslo_utils.netutils",
-    version="Newton",
-    removal_version="Ocata")
-def get_ipv6_addr_by_EUI64(cidr, mac):
-    """Generate a IPv6 addr by EUI-64 with CIDR and MAC
-
-    :param str cidr: a IPv6 CIDR
-    :param str mac: a MAC address
-    :return: an IPv6 Address
-    :rtype: netaddr.IPAddress
-    """
-    # Check if the prefix is IPv4 address
-    is_ipv4 = netutils.is_valid_ipv4(cidr)
-    if is_ipv4:
-        msg = "Unable to generate IP address by EUI64 for IPv4 prefix"
-        raise TypeError(msg)
-    try:
-        eui64 = int(netaddr.EUI(mac).eui64())
-        prefix = netaddr.IPNetwork(cidr)
-        return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57))
-    except (ValueError, netaddr.AddrFormatError):
-        raise TypeError('Bad prefix or mac format for generating IPv6 '
-                        'address by EUI-64: %(prefix)s, %(mac)s:'
-                        % {'prefix': cidr, 'mac': mac})
-    except TypeError:
-        raise TypeError('Bad prefix type for generate IPv6 address by '
-                        'EUI-64: %s' % cidr)
-
-
 # Courtesy of http://stackoverflow.com/a/312464
 def chunkify(sequence, chunksize):
     """Yield successive chunks from `sequence`."""
diff --git a/tempest/lib/services/clients.py b/tempest/lib/services/clients.py
index 4fa7a7a..8918a8c 100644
--- a/tempest/lib/services/clients.py
+++ b/tempest/lib/services/clients.py
@@ -31,6 +31,7 @@
 from tempest.lib.services import identity
 from tempest.lib.services import image
 from tempest.lib.services import network
+from tempest.lib.services import object_storage
 from tempest.lib.services import volume
 
 warnings.simplefilter("once")
@@ -50,20 +51,13 @@
         'image.v1': image.v1,
         'image.v2': image.v2,
         'network': network,
+        'object-storage': object_storage,
         'volume.v1': volume.v1,
         'volume.v2': volume.v2,
         'volume.v3': volume.v3
     }
 
 
-def _tempest_internal_modules():
-    # Set of unstable service clients available in Tempest
-    # NOTE(andreaf) This list will exists only as long the remain clients
-    # are migrated to tempest.lib, and it will then be deleted without
-    # deprecation or advance notice
-    return set(['object-storage'])
-
-
 def available_modules():
     """Set of service client modules available in Tempest and plugins
 
@@ -101,17 +95,6 @@
                                                 plug_service_versions))
                 name_conflicts.append(exceptions.PluginRegistrationException(
                     name=plugin_name, detailed_error=detailed_error))
-            # NOTE(andreaf) Once all tempest clients are stable, the following
-            # if will have to be removed.
-            if not plug_service_versions.isdisjoint(
-                    _tempest_internal_modules()):
-                detailed_error = (
-                    'Plugin %s is trying to register a service %s already '
-                    'claimed by a Tempest one' % (plugin_name,
-                                                  _tempest_internal_modules() &
-                                                  plug_service_versions))
-                name_conflicts.append(exceptions.PluginRegistrationException(
-                    name=plugin_name, detailed_error=detailed_error))
         extra_service_versions |= plug_service_versions
     if name_conflicts:
         LOG.error(
@@ -276,7 +259,7 @@
     @removals.removed_kwarg('client_parameters')
     def __init__(self, credentials, identity_uri, region=None, scope='project',
                  disable_ssl_certificate_validation=True, ca_certs=None,
-                 trace_requests='', client_parameters=None):
+                 trace_requests='', client_parameters=None, proxy_url=None):
         """Service Clients provider
 
         Instantiate a `ServiceClients` object, from a set of credentials and an
@@ -336,6 +319,8 @@
             name, as declared in `service_clients.available_modules()` except
             for the version. Values are dictionaries of parameters that are
             going to be passed to all clients in the service client module.
+        :param proxy_url: Applies to auth and to all service clients, set a
+            proxy url for the clients to use.
         """
         self._registered_services = set([])
         self.credentials = credentials
@@ -360,16 +345,20 @@
         self.dscv = disable_ssl_certificate_validation
         self.ca_certs = ca_certs
         self.trace_requests = trace_requests
+        self.proxy_url = proxy_url
         # Creates an auth provider for the credentials
         self.auth_provider = auth_provider_class(
             self.credentials, self.identity_uri, scope=scope,
             disable_ssl_certificate_validation=self.dscv,
-            ca_certs=self.ca_certs, trace_requests=self.trace_requests)
+            ca_certs=self.ca_certs, trace_requests=self.trace_requests,
+            proxy_url=proxy_url)
+
         # Setup some defaults for client parameters of registered services
         client_parameters = client_parameters or {}
         self.parameters = {}
+
         # Parameters are provided for unversioned services
-        all_modules = available_modules() | _tempest_internal_modules()
+        all_modules = available_modules()
         unversioned_services = set(
             [x.split('.')[0] for x in all_modules])
         for service in unversioned_services:
@@ -420,8 +409,8 @@
             clients in tempest.
         :param client_names: List or set of names of service client classes.
         :param kwargs: Extra optional parameters to be passed to all clients.
-            ServiceClient provides defaults for region, dscv, ca_certs and
-            trace_requests.
+            ServiceClient provides defaults for region, dscv, ca_certs, http
+            proxies and trace_requests.
         :raise ServiceClientRegistrationException: if the provided name is
             already in use or if service_version is already registered.
         :raise ImportError: if module_path cannot be imported.
@@ -442,7 +431,8 @@
         params = dict(region=self.region,
                       disable_ssl_certificate_validation=self.dscv,
                       ca_certs=self.ca_certs,
-                      trace_requests=self.trace_requests)
+                      trace_requests=self.trace_requests,
+                      proxy_url=self.proxy_url)
         params.update(kwargs)
         # Instantiate the client factory
         _factory = ClientsFactory(module_path=module_path,
@@ -456,9 +446,7 @@
 
     @property
     def registered_services(self):
-        # NOTE(andreaf) Once all tempest modules are stable this needs to
-        # be updated to remove _tempest_internal_modules
-        return self._registered_services | _tempest_internal_modules()
+        return self._registered_services
 
     def _setup_parameters(self, parameters):
         """Setup default values for client parameters
diff --git a/tempest/lib/services/object_storage/__init__.py b/tempest/lib/services/object_storage/__init__.py
index e69de29..4303d09 100644
--- a/tempest/lib/services/object_storage/__init__.py
+++ b/tempest/lib/services/object_storage/__init__.py
@@ -0,0 +1,25 @@
+# Copyright (c) 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.
+
+from tempest.lib.services.object_storage.account_client import AccountClient
+from tempest.lib.services.object_storage.bulk_middleware_client import \
+    BulkMiddlewareClient
+from tempest.lib.services.object_storage.capabilities_client import \
+    CapabilitiesClient
+from tempest.lib.services.object_storage.container_client import \
+    ContainerClient
+from tempest.lib.services.object_storage.object_client import ObjectClient
+
+__all__ = ['AccountClient', 'BulkMiddlewareClient', 'CapabilitiesClient',
+           'ContainerClient', 'ObjectClient']
diff --git a/tempest/services/object_storage/container_client.py b/tempest/lib/services/object_storage/container_client.py
similarity index 100%
rename from tempest/services/object_storage/container_client.py
rename to tempest/lib/services/object_storage/container_client.py
diff --git a/tempest/services/object_storage/object_client.py b/tempest/lib/services/object_storage/object_client.py
similarity index 62%
rename from tempest/services/object_storage/object_client.py
rename to tempest/lib/services/object_storage/object_client.py
index 6d656ec..383aff6 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/lib/services/object_storage/object_client.py
@@ -23,7 +23,8 @@
 class ObjectClient(rest_client.RestClient):
 
     def create_object(self, container, object_name, data,
-                      params=None, metadata=None, headers=None):
+                      params=None, metadata=None, headers=None,
+                      chunked=False):
         """Create storage object."""
 
         if headers is None:
@@ -37,7 +38,7 @@
         if params:
             url += '?%s' % urlparse.urlencode(params)
 
-        resp, body = self.put(url, data, headers)
+        resp, body = self.put(url, data, headers, chunked=chunked)
         self.expected_success(201, resp.status)
         return resp, body
 
@@ -50,28 +51,27 @@
         self.expected_success([200, 204], resp.status)
         return resp, body
 
-    def update_object_metadata(self, container, object_name, metadata,
-                               metadata_prefix='X-Object-Meta-'):
+    def create_or_update_object_metadata(self, container, object_name,
+                                         headers=None):
         """Add, remove, or change X-Object-Meta metadata for storage object."""
 
-        headers = {}
-        for key in metadata:
-            headers["%s%s" % (str(metadata_prefix), str(key))] = metadata[key]
-
         url = "%s/%s" % (str(container), str(object_name))
         resp, body = self.post(url, None, headers=headers)
         self.expected_success(202, resp.status)
         return resp, body
 
-    def list_object_metadata(self, container, object_name):
+    def list_object_metadata(self, container, object_name,
+                             params=None, headers=None):
         """List all storage object X-Object-Meta- metadata."""
 
         url = "%s/%s" % (str(container), str(object_name))
-        resp, body = self.head(url)
+        if params:
+            url += '?%s' % urlparse.urlencode(params)
+        resp, body = self.head(url, headers=headers)
         self.expected_success(200, resp.status)
         return resp, body
 
-    def get_object(self, container, object_name, metadata=None):
+    def get_object(self, container, object_name, metadata=None, params=None):
         """Retrieve object's data."""
 
         headers = {}
@@ -80,45 +80,12 @@
                 headers[str(key)] = metadata[key]
 
         url = "{0}/{1}".format(container, object_name)
+        if params:
+            url += '?%s' % urlparse.urlencode(params)
         resp, body = self.get(url, headers=headers)
         self.expected_success([200, 206], resp.status)
         return resp, body
 
-    def copy_object_in_same_container(self, container, src_object_name,
-                                      dest_object_name, metadata=None):
-        """Copy storage object's data to the new object using PUT."""
-
-        url = "{0}/{1}".format(container, dest_object_name)
-        headers = {}
-        headers['X-Copy-From'] = "%s/%s" % (str(container),
-                                            str(src_object_name))
-        headers['content-length'] = '0'
-        if metadata:
-            for key in metadata:
-                headers[str(key)] = metadata[key]
-
-        resp, body = self.put(url, None, headers=headers)
-        self.expected_success(201, resp.status)
-        return resp, body
-
-    def copy_object_across_containers(self, src_container, src_object_name,
-                                      dst_container, dst_object_name,
-                                      metadata=None):
-        """Copy storage object's data to the new object using PUT."""
-
-        url = "{0}/{1}".format(dst_container, dst_object_name)
-        headers = {}
-        headers['X-Copy-From'] = "%s/%s" % (str(src_container),
-                                            str(src_object_name))
-        headers['content-length'] = '0'
-        if metadata:
-            for key in metadata:
-                headers[str(key)] = metadata[key]
-
-        resp, body = self.put(url, None, headers=headers)
-        self.expected_success(201, resp.status)
-        return resp, body
-
     def copy_object_2d_way(self, container, src_object_name, dest_object_name,
                            metadata=None):
         """Copy storage object's data to the new object using COPY."""
@@ -135,38 +102,6 @@
         self.expected_success(201, resp.status)
         return resp, body
 
-    def create_object_segments(self, container, object_name, segment, data):
-        """Creates object segments."""
-        url = "{0}/{1}/{2}".format(container, object_name, segment)
-        resp, body = self.put(url, data)
-        self.expected_success(201, resp.status)
-        return resp, body
-
-    def put_object_with_chunk(self, container, name, contents):
-        """Put an object with Transfer-Encoding header
-
-        :param container: name of the container
-        :type container: string
-        :param name: name of the object
-        :type name: string
-        :param contents: object data
-        :type contents: iterable
-        """
-        headers = {'Transfer-Encoding': 'chunked'}
-        if self.token:
-            headers['X-Auth-Token'] = self.token
-
-        url = "%s/%s" % (container, name)
-        resp, body = self.put(
-            url, headers=headers,
-            body=contents,
-            chunked=True
-        )
-
-        self._error_checker(resp, body)
-        self.expected_success(201, resp.status)
-        return resp.status, resp.reason, resp
-
     def create_object_continue(self, container, object_name,
                                data, metadata=None):
         """Put an object using Expect:100-continue"""
@@ -183,8 +118,7 @@
         path = str(parsed.path) + "/"
         path += "%s/%s" % (str(container), str(object_name))
 
-        conn = create_connection(parsed)
-
+        conn = _create_connection(parsed)
         # Send the PUT request and the headers including the "Expect" header
         conn.putrequest('PUT', path)
 
@@ -218,7 +152,7 @@
         return resp.status, resp.reason
 
 
-def create_connection(parsed_url):
+def _create_connection(parsed_url):
     """Helper function to create connection with httplib
 
     :param parsed_url: parsed url of the remote location
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 4b287b8..6a12b59 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -89,16 +89,14 @@
     # The create_[resource] functions only return body and discard the
     # resp part which is not used in scenario tests
 
-    def _create_port(self, network_id, client=None, namestart='port-quotatest',
-                     **kwargs):
+    def create_port(self, network_id, client=None, **kwargs):
         if not client:
             client = self.ports_client
-        name = data_utils.rand_name(namestart)
+        name = data_utils.rand_name(self.__class__.__name__)
         result = client.create_port(
             name=name,
             network_id=network_id,
             **kwargs)
-        self.assertIsNotNone(result, 'Unable to allocate port')
         port = result['port']
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         client.delete_port, port['id'])
@@ -147,8 +145,7 @@
         if vnic_type:
             ports = []
 
-            create_port_body = {'binding:vnic_type': vnic_type,
-                                'namestart': 'port-smoke'}
+            create_port_body = {'binding:vnic_type': vnic_type}
             if kwargs:
                 # Convert security group names to security group ids
                 # to pass to create_port
@@ -185,9 +182,9 @@
             for net in networks:
                 net_id = net.get('uuid', net.get('id'))
                 if 'port' not in net:
-                    port = self._create_port(network_id=net_id,
-                                             client=clients.ports_client,
-                                             **create_port_body)
+                    port = self.create_port(network_id=net_id,
+                                            client=clients.ports_client,
+                                            **create_port_body)
                     ports.append({'port': port['id']})
                 else:
                     ports.append({'port': net['port']})
@@ -504,24 +501,6 @@
         waiters.wait_for_volume_resource_status(self.volumes_client,
                                                 volume['id'], 'available')
 
-    def rebuild_server(self, server_id, image=None,
-                       preserve_ephemeral=False, wait=True,
-                       rebuild_kwargs=None):
-        if image is None:
-            image = CONF.compute.image_ref
-
-        rebuild_kwargs = rebuild_kwargs or {}
-
-        LOG.debug("Rebuilding server (id: %s, image: %s, preserve eph: %s)",
-                  server_id, image, preserve_ephemeral)
-        self.servers_client.rebuild_server(
-            server_id=server_id, image_ref=image,
-            preserve_ephemeral=preserve_ephemeral,
-            **rebuild_kwargs)
-        if wait:
-            waiters.wait_for_server_status(self.servers_client,
-                                           server_id, 'ACTIVE')
-
     def ping_ip_address(self, ip_address, should_succeed=True,
                         ping_timeout=None, mtu=None):
         timeout = ping_timeout or CONF.validation.ping_timeout
@@ -727,17 +706,14 @@
                         network['id'])
         return network
 
-    def _create_subnet(self, network, subnets_client=None,
-                       routers_client=None, namestart='subnet-smoke',
-                       **kwargs):
+    def create_subnet(self, network, subnets_client=None,
+                      namestart='subnet-smoke', **kwargs):
         """Create a subnet for the given network
 
         within the cidr block configured for tenant networks.
         """
         if not subnets_client:
             subnets_client = self.subnets_client
-        if not routers_client:
-            routers_client = self.routers_client
 
         def cidr_in_use(cidr, tenant_id):
             """Check cidr existence
@@ -880,11 +856,11 @@
         LOG.info("FloatingIP: {fp} is at status: {st}"
                  .format(fp=floating_ip, st=status))
 
-    def _check_tenant_network_connectivity(self, server,
-                                           username,
-                                           private_key,
-                                           should_connect=True,
-                                           servers_for_debug=None):
+    def check_tenant_network_connectivity(self, server,
+                                          username,
+                                          private_key,
+                                          should_connect=True,
+                                          servers_for_debug=None):
         if not CONF.network.project_networks_reachable:
             msg = 'Tenant networks not configured to be reachable.'
             LOG.info(msg)
@@ -904,16 +880,13 @@
             self._log_net_info(e)
             raise
 
-    def _check_remote_connectivity(self, source, dest, should_succeed=True,
-                                   nic=None):
+    def check_remote_connectivity(self, source, dest, should_succeed=True,
+                                  nic=None):
         """assert ping server via source ssh connection
 
-        Note: This is an internal method.  Use check_remote_connectivity
-        instead.
-
         :param source: RemoteClient: an ssh connection from which to ping
-        :param dest: and IP to ping against
-        :param should_succeed: boolean should ping succeed or not
+        :param dest: an IP to ping against
+        :param should_succeed: boolean: should ping succeed or not
         :param nic: specific network interface to ping from
         """
         def ping_remote():
@@ -925,21 +898,8 @@
                 return not should_succeed
             return should_succeed
 
-        return test_utils.call_until_true(ping_remote,
-                                          CONF.validation.ping_timeout,
-                                          1)
-
-    def check_remote_connectivity(self, source, dest, should_succeed=True,
-                                  nic=None):
-        """assert ping server via source ssh connection
-
-        :param source: RemoteClient: an ssh connection from which to ping
-        :param dest: and IP to ping against
-        :param should_succeed: boolean should ping succeed or not
-        :param nic: specific network interface to ping from
-        """
-        result = self._check_remote_connectivity(source, dest, should_succeed,
-                                                 nic)
+        result = test_utils.call_until_true(ping_remote,
+                                            CONF.validation.ping_timeout, 1)
         source_host = source.ssh_client.host
         if should_succeed:
             msg = "Timed out waiting for %s to become reachable from %s" \
@@ -1170,12 +1130,11 @@
             router = self._get_router(client=routers_client,
                                       tenant_id=tenant_id)
             subnet_kwargs = dict(network=network,
-                                 subnets_client=subnets_client,
-                                 routers_client=routers_client)
+                                 subnets_client=subnets_client)
             # use explicit check because empty list is a valid option
             if dns_nameservers is not None:
                 subnet_kwargs['dns_nameservers'] = dns_nameservers
-            subnet = self._create_subnet(**subnet_kwargs)
+            subnet = self.create_subnet(**subnet_kwargs)
             if not routers_client:
                 routers_client = self.routers_client
             router_id = router['id']
@@ -1311,14 +1270,6 @@
             for obj in not_present_obj:
                 self.assertNotIn(obj, object_list)
 
-    def change_container_acl(self, container_name, acl):
-        metadata_param = {'metadata_prefix': 'x-container-',
-                          'metadata': {'read': acl}}
-        self.container_client.create_update_or_delete_container_metadata(
-            container_name, create_update_metadata=metadata_param)
-        resp, _ = self.container_client.list_container_metadata(container_name)
-        self.assertEqual(resp['x-container-read'], acl)
-
     def download_and_verify(self, container_name, obj_name, expected_data):
         _, obj = self.object_client.get_object(container_name, obj_name)
         self.assertEqual(obj, expected_data)
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 340c3c9..7c404ad 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -83,7 +83,7 @@
                                     should_connect=True):
         username = CONF.validation.image_ssh_user
         private_key = keypair['private_key']
-        self._check_tenant_network_connectivity(
+        self.check_tenant_network_connectivity(
             server, username, private_key,
             should_connect=should_connect,
             servers_for_debug=[server])
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 0c3bf23..6332c6d 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -113,11 +113,16 @@
         port_id = None
         if boot_with_port:
             # create a port on the network and boot with that
-            port_id = self._create_port(self.network['id'])['id']
+            port_id = self.create_port(self.network['id'])['id']
             self.ports.append({'port': port_id})
 
         server = self._create_server(self.network, port_id)
-        self._check_tenant_network_connectivity()
+        ssh_login = CONF.validation.image_ssh_user
+        for server in self.servers:
+            # call the common method in the parent class
+            self.check_tenant_network_connectivity(
+                server, ssh_login, self._get_server_key(server),
+                servers_for_debug=self.servers)
 
         floating_ip = self.create_floating_ip(server)
         self.floating_ip_tuple = Floating_IP_tuple(floating_ip, server)
@@ -170,15 +175,6 @@
     def _get_server_key(self, server):
         return self.keypairs[server['key_name']]['private_key']
 
-    def _check_tenant_network_connectivity(self):
-        ssh_login = CONF.validation.image_ssh_user
-        for server in self.servers:
-            # call the common method in the parent class
-            super(TestNetworkBasicOps, self).\
-                _check_tenant_network_connectivity(
-                    server, ssh_login, self._get_server_key(server),
-                    servers_for_debug=self.servers)
-
     def check_public_network_connectivity(
             self, should_connect=True, msg=None,
             should_check_floating_ip_status=True, mtu=None):
@@ -231,10 +227,10 @@
     def _create_new_network(self, create_gateway=False):
         self.new_net = self._create_network()
         if create_gateway:
-            self.new_subnet = self._create_subnet(
+            self.new_subnet = self.create_subnet(
                 network=self.new_net)
         else:
-            self.new_subnet = self._create_subnet(
+            self.new_subnet = self.create_subnet(
                 network=self.new_net,
                 gateway_ip=None)
 
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index b687aa0..210f0ba 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -78,9 +78,9 @@
         if dualnet:
             network_v6 = self._create_network()
 
-        sub4 = self._create_subnet(network=network,
-                                   namestart='sub4',
-                                   ip_version=4)
+        sub4 = self.create_subnet(network=network,
+                                  namestart='sub4',
+                                  ip_version=4)
 
         router = self._get_router()
         self.routers_client.add_router_interface(router['id'],
@@ -93,11 +93,11 @@
         self.subnets_v6 = []
         for _ in range(n_subnets6):
             net6 = network_v6 if dualnet else network
-            sub6 = self._create_subnet(network=net6,
-                                       namestart='sub6',
-                                       ip_version=6,
-                                       ipv6_ra_mode=address6_mode,
-                                       ipv6_address_mode=address6_mode)
+            sub6 = self.create_subnet(network=net6,
+                                      namestart='sub6',
+                                      ip_version=6,
+                                      ipv6_ra_mode=address6_mode,
+                                      ipv6_address_mode=address6_mode)
 
             self.routers_client.add_router_interface(router['id'],
                                                      subnet_id=sub6['id'])
diff --git a/tempest/scenario/test_object_storage_basic_ops.py b/tempest/scenario/test_object_storage_basic_ops.py
index da0b1e8..cbe321e 100644
--- a/tempest/scenario/test_object_storage_basic_ops.py
+++ b/tempest/scenario/test_object_storage_basic_ops.py
@@ -58,12 +58,18 @@
         5. Delete the object and container
         """
         container_name = self.create_container()
-        obj_name, _ = self.upload_object_to_container(container_name)
+        obj_name, obj_data = self.upload_object_to_container(container_name)
         obj_url = '%s/%s/%s' % (self.object_client.base_url,
                                 container_name, obj_name)
         resp, _ = self.object_client.raw_request(obj_url, 'GET')
         self.assertEqual(resp.status, 401)
-
-        self.change_container_acl(container_name, '.r:*')
-        resp, _ = self.object_client.raw_request(obj_url, 'GET')
+        metadata_param = {'X-Container-Read': '.r:*'}
+        self.container_client.create_update_or_delete_container_metadata(
+            container_name, create_update_metadata=metadata_param,
+            create_update_metadata_prefix='')
+        resp, _ = self.container_client.list_container_metadata(container_name)
+        self.assertEqual(metadata_param['X-Container-Read'],
+                         resp['x-container-read'])
+        resp, data = self.object_client.raw_request(obj_url, 'GET')
         self.assertEqual(resp.status, 200)
+        self.assertEqual(obj_data, data)
diff --git a/tempest/services/object_storage/__init__.py b/tempest/services/object_storage/__init__.py
deleted file mode 100644
index 771ed8f..0000000
--- a/tempest/services/object_storage/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (c) 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.
-
-from tempest.lib.services.object_storage.account_client import AccountClient
-from tempest.lib.services.object_storage.bulk_middleware_client import \
-    BulkMiddlewareClient
-from tempest.lib.services.object_storage.capabilities_client import \
-    CapabilitiesClient
-from tempest.services.object_storage.container_client import ContainerClient
-from tempest.services.object_storage.object_client import ObjectClient
-
-__all__ = ['AccountClient', 'BulkMiddlewareClient', 'CapabilitiesClient',
-           'ContainerClient', 'ObjectClient']
diff --git a/tempest/tests/cmd/test_account_generator.py b/tempest/tests/cmd/test_account_generator.py
index f907bd0..8bf4c5b 100644
--- a/tempest/tests/cmd/test_account_generator.py
+++ b/tempest/tests/cmd/test_account_generator.py
@@ -44,6 +44,7 @@
         self.patchobject(config, 'TempestConfigPrivate',
                          fake_config.FakePrivate)
         self.opts = FakeOpts(version=identity_version)
+        self.patch('oslo_log.log.setup', autospec=True)
 
     def mock_resource_creation(self):
         fake_resource = dict(id='id', name='name')
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 810f9e5..8641b63 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -176,22 +176,6 @@
                                            False, True)
 
     @mock.patch('tempest.lib.common.http.ClosingHttp.request')
-    def test_verify_keystone_api_versions_no_v2(self, mock_request):
-        self.useFixture(fixtures.MockPatchObject(
-            verify_tempest_config, '_get_unversioned_endpoint',
-            return_value='http://fake_endpoint:5000'))
-        fake_resp = {'versions': {'values': [{'id': 'v3.0'}]}}
-        fake_resp = json.dumps(fake_resp)
-        mock_request.return_value = (None, fake_resp)
-        fake_os = mock.MagicMock()
-        with mock.patch.object(verify_tempest_config,
-                               'print_and_or_update') as print_mock:
-            verify_tempest_config.verify_keystone_api_versions(fake_os, True)
-        print_mock.assert_called_once_with('api_v2',
-                                           'identity-feature-enabled',
-                                           False, True)
-
-    @mock.patch('tempest.lib.common.http.ClosingHttp.request')
     def test_verify_cinder_api_versions_no_v3(self, mock_request):
         self.useFixture(fixtures.MockPatchObject(
             verify_tempest_config, '_get_unversioned_endpoint',
diff --git a/tempest/tests/common/test_credentials_factory.py b/tempest/tests/common/test_credentials_factory.py
index 020818e..7cf87f8 100644
--- a/tempest/tests/common/test_credentials_factory.py
+++ b/tempest/tests/common/test_credentials_factory.py
@@ -183,7 +183,7 @@
         # Build the expected params
         expected_params = dict(
             [(field, value) for _, field, value in all_params])
-        expected_params.update(cf.DEFAULT_PARAMS)
+        expected_params.update(config.service_client_config())
         admin_creds = cf.get_configured_admin_credentials()
         mock_get_credentials.assert_called_once_with(
             fill_in=True, identity_version='v3', **expected_params)
@@ -205,7 +205,7 @@
         # Build the expected params
         expected_params = dict(
             [(field, value) for _, field, value in all_params])
-        expected_params.update(cf.DEFAULT_PARAMS)
+        expected_params.update(config.service_client_config())
         admin_creds = cf.get_configured_admin_credentials(
             fill_in=False, identity_version='v3')
         mock_get_credentials.assert_called_once_with(
@@ -232,7 +232,7 @@
         cfg.CONF.set_default('uri', expected_uri, 'identity')
         params = {'foo': 'bar'}
         expected_params = params.copy()
-        expected_params.update(cf.DEFAULT_PARAMS)
+        expected_params.update(config.service_client_config())
         result = cf.get_credentials(identity_version='v2', **params)
         self.assertEqual(expected_result, result)
         mock_auth_get_credentials.assert_called_once_with(
@@ -251,7 +251,7 @@
         params = {'foo': 'bar'}
         expected_params = params.copy()
         expected_params['domain_name'] = expected_domain
-        expected_params.update(cf.DEFAULT_PARAMS)
+        expected_params.update(config.service_client_config())
         result = cf.get_credentials(fill_in=False, identity_version='v3',
                                     **params)
         self.assertEqual(expected_result, result)
@@ -270,7 +270,7 @@
                              expected_domain, 'auth')
         params = {'foo': 'bar', 'user_domain_name': expected_domain}
         expected_params = params.copy()
-        expected_params.update(cf.DEFAULT_PARAMS)
+        expected_params.update(config.service_client_config())
         result = cf.get_credentials(fill_in=False, identity_version='v3',
                                     **params)
         self.assertEqual(expected_result, result)
diff --git a/tempest/tests/lib/cli/test_execute.py b/tempest/tests/lib/cli/test_execute.py
index 0130454..c276386 100644
--- a/tempest/tests/lib/cli/test_execute.py
+++ b/tempest/tests/lib/cli/test_execute.py
@@ -91,3 +91,37 @@
         self.assertEqual(mock_execute.call_count, 1)
         self.assertEqual(mock_execute.call_args[1],
                          {'prefix': 'env LAC_ALL=C'})
+
+    @mock.patch.object(cli_base, 'execute')
+    def test_execute_with_domain_name(self, mock_execute):
+        cli = cli_base.CLIClient(
+            user_domain_name='default',
+            project_domain_name='default'
+        )
+        cli.glance('action')
+        self.assertEqual(mock_execute.call_count, 1)
+        self.assertIn('--os-user-domain-name default',
+                      mock_execute.call_args[0][2])
+        self.assertIn('--os-project-domain-name default',
+                      mock_execute.call_args[0][2])
+        self.assertNotIn('--os-user-domain-id',
+                         mock_execute.call_args[0][2])
+        self.assertNotIn('--os-project-domain-id',
+                         mock_execute.call_args[0][2])
+
+    @mock.patch.object(cli_base, 'execute')
+    def test_execute_with_domain_id(self, mock_execute):
+        cli = cli_base.CLIClient(
+            user_domain_id='default',
+            project_domain_id='default'
+        )
+        cli.glance('action')
+        self.assertEqual(mock_execute.call_count, 1)
+        self.assertIn('--os-user-domain-id default',
+                      mock_execute.call_args[0][2])
+        self.assertIn('--os-project-domain-id default',
+                      mock_execute.call_args[0][2])
+        self.assertNotIn('--os-user-domain-name',
+                         mock_execute.call_args[0][2])
+        self.assertNotIn('--os-project-domain-name',
+                         mock_execute.call_args[0][2])
diff --git a/tempest/tests/lib/common/utils/test_data_utils.py b/tempest/tests/lib/common/utils/test_data_utils.py
index 8bdf70e..ab7fa74 100644
--- a/tempest/tests/lib/common/utils/test_data_utils.py
+++ b/tempest/tests/lib/common/utils/test_data_utils.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import netaddr
-
 from tempest.lib.common.utils import data_utils
 from tempest.tests import base
 
@@ -137,43 +135,6 @@
         actual = data_utils.random_bytes(size=2048)
         self.assertEqual(2048, len(actual))
 
-    def test_get_ipv6_addr_by_EUI64(self):
-        actual = data_utils.get_ipv6_addr_by_EUI64('2001:db8::',
-                                                   '00:16:3e:33:44:55')
-        self.assertIsInstance(actual, netaddr.IPAddress)
-        self.assertEqual(actual,
-                         netaddr.IPAddress('2001:db8::216:3eff:fe33:4455'))
-
-    def test_get_ipv6_addr_by_EUI64_with_IPv4_prefix(self):
-        ipv4_prefix = '10.0.8'
-        mac = '00:16:3e:33:44:55'
-        self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64,
-                          ipv4_prefix, mac)
-
-    def test_get_ipv6_addr_by_EUI64_bad_cidr_type(self):
-        bad_cidr = 123
-        mac = '00:16:3e:33:44:55'
-        self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64,
-                          bad_cidr, mac)
-
-    def test_get_ipv6_addr_by_EUI64_bad_cidr_value(self):
-        bad_cidr = 'bb'
-        mac = '00:16:3e:33:44:55'
-        self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64,
-                          bad_cidr, mac)
-
-    def test_get_ipv6_addr_by_EUI64_bad_mac_value(self):
-        cidr = '2001:db8::'
-        bad_mac = '00:16:3e:33:44:5Z'
-        self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64,
-                          cidr, bad_mac)
-
-    def test_get_ipv6_addr_by_EUI64_bad_mac_type(self):
-        cidr = '2001:db8::'
-        bad_mac = 99999999999999999999
-        self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64,
-                          cidr, bad_mac)
-
     def test_chunkify(self):
         data = "aaa"
         chunks = data_utils.chunkify(data, 2)
diff --git a/tempest/tests/lib/services/object_storage/test_object_client.py b/tempest/tests/lib/services/object_storage/test_object_client.py
new file mode 100644
index 0000000..a16d1d7
--- /dev/null
+++ b/tempest/tests/lib/services/object_storage/test_object_client.py
@@ -0,0 +1,108 @@
+# Copyright 2016 IBM Corp.
+# 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 mock
+
+from tempest.lib import exceptions
+from tempest.lib.services.object_storage import object_client
+from tempest.tests import base
+from tempest.tests.lib import fake_auth_provider
+
+
+class TestObjectClient(base.TestCase):
+
+    def setUp(self):
+        super(TestObjectClient, self).setUp()
+        self.fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.url = self.fake_auth.base_url(None)
+        self.object_client = object_client.ObjectClient(self.fake_auth,
+                                                        'swift', 'region1')
+
+    @mock.patch.object(object_client, '_create_connection')
+    def test_create_object_continue_no_data(self, mock_poc):
+        self._validate_create_object_continue(None, mock_poc)
+
+    @mock.patch.object(object_client, '_create_connection')
+    def test_create_object_continue_with_data(self, mock_poc):
+        self._validate_create_object_continue('hello', mock_poc)
+
+    @mock.patch.object(object_client, '_create_connection')
+    def test_create_continue_with_no_continue_received(self, mock_poc):
+        self._validate_create_object_continue('hello', mock_poc,
+                                              initial_status=201)
+
+    def _validate_create_object_continue(self, req_data,
+                                         mock_poc, initial_status=100):
+
+        expected_hdrs = {
+            'X-Auth-Token': self.fake_auth.get_token(),
+            'content-length': 0 if req_data is None else len(req_data),
+            'Expect': '100-continue'}
+
+        # Setup the Mocks prior to invoking the object creation
+        mock_resp_cls = mock.Mock()
+        mock_resp_cls._read_status.return_value = ("1", initial_status, "OK")
+
+        mock_poc.return_value.response_class.return_value = mock_resp_cls
+
+        # This is the final expected return value
+        mock_poc.return_value.getresponse.return_value.status = 201
+        mock_poc.return_value.getresponse.return_value.reason = 'OK'
+
+        # Call method to PUT object using expect:100-continue
+        cnt = "container1"
+        obj = "object1"
+        path = "/%s/%s" % (cnt, obj)
+
+        # If the expected initial status is not 100, then an exception
+        # should be thrown and the connection closed
+        if initial_status is 100:
+            status, reason = \
+                self.object_client.create_object_continue(cnt, obj, req_data)
+        else:
+            self.assertRaises(exceptions.UnexpectedResponseCode,
+                              self.object_client.create_object_continue, cnt,
+                              obj, req_data)
+            mock_poc.return_value.close.assert_called_once_with()
+
+        # Verify that putrequest is called 1 time with the appropriate values
+        mock_poc.return_value.putrequest.assert_called_once_with('PUT', path)
+
+        # Verify that headers were written, including "Expect:100-continue"
+        calls = []
+
+        for header, value in expected_hdrs.items():
+            calls.append(mock.call(header, value))
+
+        mock_poc.return_value.putheader.assert_has_calls(calls, False)
+        mock_poc.return_value.endheaders.assert_called_once_with()
+
+        # The following steps are only taken if the initial status is 100
+        if initial_status is 100:
+            # Verify that the method returned what it was supposed to
+            self.assertEqual(status, 201)
+
+            # Verify that _safe_read was called once to remove the CRLF
+            # after the 100 response
+            mock_rc = mock_poc.return_value.response_class.return_value
+            mock_rc._safe_read.assert_called_once_with(2)
+
+            # Verify the actual data was written via send
+            mock_poc.return_value.send.assert_called_once_with(req_data)
+
+            # Verify that the getresponse method was called to receive
+            # the final
+            mock_poc.return_value.getresponse.assert_called_once_with()
diff --git a/tempest/tests/lib/services/registry_fixture.py b/tempest/tests/lib/services/registry_fixture.py
index 8484209..1da2112 100644
--- a/tempest/tests/lib/services/registry_fixture.py
+++ b/tempest/tests/lib/services/registry_fixture.py
@@ -38,7 +38,7 @@
         """Initialise the registry fixture"""
         self.services = set(['compute', 'identity.v2', 'identity.v3',
                              'image.v1', 'image.v2', 'network', 'volume.v1',
-                             'volume.v2', 'volume.v3'])
+                             'volume.v2', 'volume.v3', 'object-storage'])
 
     def _setUp(self):
         # Cleanup the registry
@@ -50,7 +50,7 @@
         for sc in self.services:
             sc_module = service_clients[sc]
             sc_unversioned = sc.split('.')[0]
-            sc_name = sc.replace('.', '_')
+            sc_name = sc.replace('.', '_').replace('-', '_')
             # Pass the bare minimum params to satisfy the clients interface
             service_client_data = dict(
                 name=sc_name, service_version=sc, service=sc_unversioned,
diff --git a/tempest/tests/lib/services/test_clients.py b/tempest/tests/lib/services/test_clients.py
index 6d0f27a..43fd88f 100644
--- a/tempest/tests/lib/services/test_clients.py
+++ b/tempest/tests/lib/services/test_clients.py
@@ -189,9 +189,7 @@
     def setUp(self):
         super(TestServiceClients, self).setUp()
         self.useFixture(fixtures.MockPatch(
-            'tempest.lib.services.clients.tempest_modules', return_value={}))
-        self.useFixture(fixtures.MockPatch(
-            'tempest.lib.services.clients._tempest_internal_modules',
+            'tempest.lib.services.clients.tempest_modules',
             return_value=set(['fake_service1'])))
 
     def test___init___creds_v2_uri(self):
@@ -416,6 +414,7 @@
         _manager = self._get_manager()
         duplicate_service = 'fake_service1'
         expected_error = '.*' + duplicate_service
+        _manager._registered_services = [duplicate_service]
         with testtools.ExpectedException(
                 exceptions.ServiceClientRegistrationException, expected_error):
             _manager.register_service_client_module(
diff --git a/tempest/tests/services/__init__.py b/tempest/tests/services/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/tests/services/__init__.py
+++ /dev/null
diff --git a/tempest/tests/services/object_storage/__init__.py b/tempest/tests/services/object_storage/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/tests/services/object_storage/__init__.py
+++ /dev/null
diff --git a/tempest/tests/services/object_storage/test_object_client.py b/tempest/tests/services/object_storage/test_object_client.py
index 748614c..86535f9 100644
--- a/tempest/tests/services/object_storage/test_object_client.py
+++ b/tempest/tests/services/object_storage/test_object_client.py
@@ -31,15 +31,15 @@
         self.object_client = object_client.ObjectClient(self.fake_auth,
                                                         'swift', 'region1')
 
-    @mock.patch.object(object_client, 'create_connection')
+    @mock.patch.object(object_client, '_create_connection')
     def test_create_object_continue_no_data(self, mock_poc):
         self._validate_create_object_continue(None, mock_poc)
 
-    @mock.patch.object(object_client, 'create_connection')
+    @mock.patch.object(object_client, '_create_connection')
     def test_create_object_continue_with_data(self, mock_poc):
         self._validate_create_object_continue('hello', mock_poc)
 
-    @mock.patch.object(object_client, 'create_connection')
+    @mock.patch.object(object_client, '_create_connection')
     def test_create_continue_with_no_continue_received(self, mock_poc):
         self._validate_create_object_continue('hello', mock_poc,
                                               initial_status=201)
diff --git a/tempest/tests/test_base_test.py b/tempest/tests/test_base_test.py
index 3ece11d..011bc9b 100644
--- a/tempest/tests/test_base_test.py
+++ b/tempest/tests/test_base_test.py
@@ -17,6 +17,7 @@
 
 from tempest import clients
 from tempest.common import credentials_factory as credentials
+from tempest import config
 from tempest.lib.common import fixed_network
 from tempest import test
 from tempest.tests import base
@@ -27,6 +28,8 @@
     def setUp(self):
         super(TestBaseTestCase, self).setUp()
         self.useFixture(fake_config.ConfigFixture())
+        self.patchobject(config, 'TempestConfigPrivate',
+                         fake_config.FakePrivate)
         self.fixed_network_name = 'fixed-net'
         cfg.CONF.set_default('fixed_network_name', self.fixed_network_name,
                              'compute')