Get rid of httplib2, use urllib3 instead

httplib2 has been abandonned by its author [1] and is less going
to be updated and maintained than urllib3. So, let's replace httplib2
with urllib3.

Note that this patch mostly rework the unit tests.

I removed the files `tempest.tests.fake_identity` and
`tempest.tests.fake_http` to use their `tempest.tests.lib` counterpart.

Also, I tried to "encapsulated" HTTP calls and use
`tempest/lib/common/http.py` everywhere so that we only import
urllib3 once. This makes us not so dependent on a specific HTTP
library.

[1] http://bitworking.org/news/2016/03/an_update_on_httplib2
Change-Id: Id469e78afdb69a404144568a454d98d20a924231
diff --git a/requirements.txt b/requirements.txt
index 7c426e6..a2ec16e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,7 +4,6 @@
 pbr>=1.6 # Apache-2.0
 cliff!=1.16.0,!=1.17.0,>=1.15.0 # Apache-2.0
 anyjson>=0.3.3 # BSD
-httplib2>=0.7.5 # MIT
 jsonschema!=2.5.0,<3.0.0,>=2.0.0 # MIT
 testtools>=1.4.0 # MIT
 paramiko>=1.16.0 # LGPL
@@ -25,3 +24,4 @@
 stevedore>=1.5.0 # Apache-2.0
 PrettyTable<0.8,>=0.7 # BSD
 os-testr>=0.4.1 # Apache-2.0
+urllib3>=1.8.3  # MIT
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 0ba322d..f29973d 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -15,7 +15,6 @@
 #    under the License.
 
 import argparse
-import httplib2
 import os
 import sys
 import traceback
@@ -29,6 +28,7 @@
 from tempest import clients
 from tempest.common import credentials_factory as credentials
 from tempest import config
+import tempest.lib.common.http
 
 
 CONF = config.CONF
@@ -91,11 +91,12 @@
     }
     client_dict[service].skip_path()
     endpoint = _get_unversioned_endpoint(client_dict[service].base_url)
-    dscv = CONF.identity.disable_ssl_certificate_validation
-    ca_certs = CONF.identity.ca_certificates_file
-    raw_http = httplib2.Http(disable_ssl_certificate_validation=dscv,
-                             ca_certs=ca_certs)
-    __, body = raw_http.request(endpoint, 'GET')
+
+    http = tempest.lib.common.http.ClosingHttp(
+        CONF.identity.disable_ssl_certificate_validation,
+        CONF.identity.ca_certificates_file)
+
+    __, body = http.request(endpoint, 'GET')
     client_dict[service].reset_path()
     try:
         body = json.loads(body)
diff --git a/tempest/lib/common/http.py b/tempest/lib/common/http.py
index b3793bc..dffc5f9 100644
--- a/tempest/lib/common/http.py
+++ b/tempest/lib/common/http.py
@@ -1,5 +1,4 @@
-# Copyright 2013 OpenStack Foundation
-# Copyright 2013 Citrix Systems, Inc.
+# Copyright 2016 OpenStack Foundation
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -14,12 +13,43 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import httplib2
+import urllib3
 
 
-class ClosingHttp(httplib2.Http):
-    def request(self, *args, **kwargs):
+class ClosingHttp(urllib3.poolmanager.PoolManager):
+    def __init__(self, disable_ssl_certificate_validation=False,
+                 ca_certs=None):
+        kwargs = {}
+
+        if disable_ssl_certificate_validation:
+            urllib3.disable_warnings()
+            kwargs['cert_reqs'] = 'CERT_NONE'
+
+        if ca_certs:
+            kwargs['cert_reqs'] = 'CERT_REQUIRED'
+            kwargs['ca_certs'] = ca_certs
+
+        super(ClosingHttp, self).__init__(**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)
-        return super(ClosingHttp, self).request(*args, **new_kwargs)
+
+        # 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(ClosingHttp, self).request(method, url, retries=retry,
+                                             *args, **new_kwargs)
+        return Response(r), r.data
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 5d050d1..9df07a1 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -49,8 +49,9 @@
             return_value='http://fake_endpoint:5000'))
         fake_resp = {'versions': {'values': [{'id': 'v2.0'}, {'id': 'v3.0'}]}}
         fake_resp = json.dumps(fake_resp)
-        self.useFixture(mockpatch.Patch('httplib2.Http.request',
-                                        return_value=(None, fake_resp)))
+        self.useFixture(mockpatch.Patch(
+            'tempest.lib.common.http.ClosingHttp.request',
+            return_value=(None, fake_resp)))
         fake_os = mock.MagicMock()
         versions = verify_tempest_config._get_api_versions(fake_os, 'keystone')
         self.assertIn('v2.0', versions)
@@ -62,8 +63,9 @@
             return_value='http://fake_endpoint:5000'))
         fake_resp = {'versions': [{'id': 'v1.0'}, {'id': 'v2.0'}]}
         fake_resp = json.dumps(fake_resp)
-        self.useFixture(mockpatch.Patch('httplib2.Http.request',
-                                        return_value=(None, fake_resp)))
+        self.useFixture(mockpatch.Patch(
+            'tempest.lib.common.http.ClosingHttp.request',
+            return_value=(None, fake_resp)))
         fake_os = mock.MagicMock()
         versions = verify_tempest_config._get_api_versions(fake_os, 'cinder')
         self.assertIn('v1.0', versions)
@@ -75,8 +77,9 @@
             return_value='http://fake_endpoint:5000'))
         fake_resp = {'versions': [{'id': 'v2.0'}, {'id': 'v3.0'}]}
         fake_resp = json.dumps(fake_resp)
-        self.useFixture(mockpatch.Patch('httplib2.Http.request',
-                                        return_value=(None, fake_resp)))
+        self.useFixture(mockpatch.Patch(
+            'tempest.lib.common.http.ClosingHttp.request',
+            return_value=(None, fake_resp)))
         fake_os = mock.MagicMock()
         versions = verify_tempest_config._get_api_versions(fake_os, 'nova')
         self.assertIn('v2.0', versions)
@@ -95,8 +98,9 @@
         sample_body = (
             '<html><head>Sample Response</head><body>This is the sample page '
             'for the web server. Why are you requesting it?</body></html>')
-        self.useFixture(mockpatch.Patch('httplib2.Http.request',
-                                        return_value=(None, sample_body)))
+        self.useFixture(mockpatch.Patch(
+            'tempest.lib.common.http.ClosingHttp.request',
+            return_value=(None, sample_body)))
 
         # service value doesn't matter, just needs to match what
         # _get_api_versions puts in its client_dict.
@@ -122,14 +126,14 @@
                 verify_tempest_config.verify_api_versions(fake_os, 'foo', True)
                 self.assertFalse(verify_mock.called)
 
-    def test_verify_keystone_api_versions_no_v3(self):
+    @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+    def test_verify_keystone_api_versions_no_v3(self, mock_request):
         self.useFixture(mockpatch.PatchObject(
             verify_tempest_config, '_get_unversioned_endpoint',
             return_value='http://fake_endpoint:5000'))
         fake_resp = {'versions': {'values': [{'id': 'v2.0'}]}}
         fake_resp = json.dumps(fake_resp)
-        self.useFixture(mockpatch.Patch('httplib2.Http.request',
-                                        return_value=(None, 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:
@@ -138,14 +142,14 @@
                                            'identity-feature-enabled',
                                            False, True)
 
-    def test_verify_keystone_api_versions_no_v2(self):
+    @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+    def test_verify_keystone_api_versions_no_v2(self, mock_request):
         self.useFixture(mockpatch.PatchObject(
             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)
-        self.useFixture(mockpatch.Patch('httplib2.Http.request',
-                                        return_value=(None, 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:
@@ -154,14 +158,14 @@
                                            'identity-feature-enabled',
                                            False, True)
 
-    def test_verify_cinder_api_versions_no_v2(self):
+    @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+    def test_verify_cinder_api_versions_no_v2(self, mock_request):
         self.useFixture(mockpatch.PatchObject(
             verify_tempest_config, '_get_unversioned_endpoint',
             return_value='http://fake_endpoint:5000'))
         fake_resp = {'versions': [{'id': 'v1.0'}]}
         fake_resp = json.dumps(fake_resp)
-        self.useFixture(mockpatch.Patch('httplib2.Http.request',
-                                        return_value=(None, 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:
@@ -169,14 +173,14 @@
         print_mock.assert_called_once_with('api_v2', 'volume-feature-enabled',
                                            False, True)
 
-    def test_verify_cinder_api_versions_no_v1(self):
+    @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+    def test_verify_cinder_api_versions_no_v1(self, mock_request):
         self.useFixture(mockpatch.PatchObject(
             verify_tempest_config, '_get_unversioned_endpoint',
             return_value='http://fake_endpoint:5000'))
         fake_resp = {'versions': [{'id': 'v2.0'}]}
         fake_resp = json.dumps(fake_resp)
-        self.useFixture(mockpatch.Patch('httplib2.Http.request',
-                                        return_value=(None, 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:
diff --git a/tempest/tests/common/test_configured_creds.py b/tempest/tests/common/test_configured_creds.py
index 8c721e6..3c104b2 100644
--- a/tempest/tests/common/test_configured_creds.py
+++ b/tempest/tests/common/test_configured_creds.py
@@ -22,8 +22,8 @@
 from tempest.lib.services.identity.v2 import token_client as v2_client
 from tempest.lib.services.identity.v3 import token_client as v3_client
 from tempest.tests import fake_config
-from tempest.tests import fake_identity
 from tempest.tests.lib import base
+from tempest.tests.lib import fake_identity
 
 
 class ConfiguredV2CredentialsTests(base.TestCase):
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index f2052dc..e1d9023 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -32,9 +32,9 @@
     json_users_client
 from tempest.services.network.json import routers_client
 from tempest.tests import fake_config
-from tempest.tests import fake_http
-from tempest.tests import fake_identity
 from tempest.tests.lib import base
+from tempest.tests.lib import fake_http
+from tempest.tests.lib import fake_identity
 
 
 class TestDynamicCredentialProvider(base.TestCase):
@@ -47,7 +47,6 @@
         super(TestDynamicCredentialProvider, self).setUp()
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
-        self.fake_http = fake_http.fake_httplib2(return_type=200)
         self.stubs.Set(json_token_client.TokenClient, 'raw_request',
                        fake_identity._fake_v2_response)
         cfg.CONF.set_default('operator_role', 'FakeRole',
@@ -402,7 +401,7 @@
             side_effect=side_effect)
         secgroup_list_mock.start()
 
-        return_values = (fake_http.fake_httplib({}, status=204), {})
+        return_values = fake_http.fake_http_response({}, status=204), ''
         remove_secgroup_mock = self.patch(
             'tempest.lib.services.network.security_groups_client.'
             'SecurityGroupsClient.delete', return_value=return_values)
diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py
index efc5ef6..36d6c3d 100644
--- a/tempest/tests/common/test_preprov_creds.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -29,9 +29,8 @@
 from tempest.lib import exceptions as lib_exc
 from tempest.lib.services.identity.v2 import token_client
 from tempest.tests import fake_config
-from tempest.tests import fake_http
-from tempest.tests import fake_identity
 from tempest.tests.lib import base
+from tempest.tests.lib import fake_identity
 
 
 class TestPreProvisionedCredentials(base.TestCase):
@@ -48,7 +47,6 @@
         super(TestPreProvisionedCredentials, self).setUp()
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
-        self.fake_http = fake_http.fake_httplib2(return_type=200)
         self.stubs.Set(token_client.TokenClient, 'raw_request',
                        fake_identity._fake_v2_response)
         self.useFixture(lockutils_fixtures.ExternalLockFixture())
diff --git a/tempest/tests/fake_http.py b/tempest/tests/fake_http.py
deleted file mode 100644
index d714055..0000000
--- a/tempest/tests/fake_http.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import copy
-
-import httplib2
-
-
-class fake_httplib2(object):
-
-    def __init__(self, return_type=None, *args, **kwargs):
-        self.return_type = return_type
-
-    def request(self, uri, method="GET", body=None, headers=None,
-                redirections=5, connection_type=None):
-        if not self.return_type:
-            fake_headers = httplib2.Response(headers)
-            return_obj = {
-                'uri': uri,
-                'method': method,
-                'body': body,
-                'headers': headers
-            }
-            return (fake_headers, return_obj)
-        elif isinstance(self.return_type, int):
-            body = "fake_body"
-            header_info = {
-                'content-type': 'text/plain',
-                'status': str(self.return_type),
-                'content-length': len(body)
-            }
-            resp_header = httplib2.Response(header_info)
-            return (resp_header, body)
-        else:
-            msg = "unsupported return type %s" % self.return_type
-            raise TypeError(msg)
-
-
-class fake_httplib(object):
-    def __init__(self, headers, body=None,
-                 version=1.0, status=200, reason="Ok"):
-        """Initialization of fake httplib
-
-        :param headers: dict representing HTTP response headers
-        :param body: file-like object
-        :param version: HTTP Version
-        :param status: Response status code
-        :param reason: Status code related message.
-        """
-        self.body = body
-        self.status = status
-        self.reason = reason
-        self.version = version
-        self.headers = headers
-
-    def getheaders(self):
-        return copy.deepcopy(self.headers).items()
-
-    def getheader(self, key, default):
-        return self.headers.get(key, default)
-
-    def read(self, amt):
-        return self.body.read(amt)
diff --git a/tempest/tests/fake_identity.py b/tempest/tests/fake_identity.py
deleted file mode 100644
index d0de927..0000000
--- a/tempest/tests/fake_identity.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright 2014 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 httplib2
-from oslo_serialization import jsonutils as json
-
-FAKE_AUTH_URL = 'http://fake_uri.com/auth'
-
-TOKEN = "fake_token"
-ALT_TOKEN = "alt_fake_token"
-
-# Fake Identity v2 constants
-COMPUTE_ENDPOINTS_V2 = {
-    "endpoints": [
-        {
-            "adminURL": "http://fake_url/v2/first_endpoint/admin",
-            "region": "NoMatchRegion",
-            "internalURL": "http://fake_url/v2/first_endpoint/internal",
-            "publicURL": "http://fake_url/v2/first_endpoint/public"
-        },
-        {
-            "adminURL": "http://fake_url/v2/second_endpoint/admin",
-            "region": "FakeRegion",
-            "internalURL": "http://fake_url/v2/second_endpoint/internal",
-            "publicURL": "http://fake_url/v2/second_endpoint/public"
-        },
-    ],
-    "type": "compute",
-    "name": "nova"
-}
-
-CATALOG_V2 = [COMPUTE_ENDPOINTS_V2, ]
-
-ALT_IDENTITY_V2_RESPONSE = {
-    "access": {
-        "token": {
-            "expires": "2020-01-01T00:00:10Z",
-            "id": ALT_TOKEN,
-            "tenant": {
-                "id": "fake_tenant_id"
-            },
-        },
-        "user": {
-            "id": "fake_user_id",
-        },
-        "serviceCatalog": CATALOG_V2,
-    },
-}
-
-IDENTITY_V2_RESPONSE = {
-    "access": {
-        "token": {
-            "expires": "2020-01-01T00:00:10Z",
-            "id": TOKEN,
-            "tenant": {
-                "id": "fake_tenant_id"
-            },
-        },
-        "user": {
-            "id": "fake_user_id",
-        },
-        "serviceCatalog": CATALOG_V2,
-    },
-}
-
-# Fake Identity V3 constants
-COMPUTE_ENDPOINTS_V3 = {
-    "endpoints": [
-        {
-            "id": "first_compute_fake_service",
-            "interface": "public",
-            "region": "NoMatchRegion",
-            "url": "http://fake_url/v3/first_endpoint/api"
-        },
-        {
-            "id": "second_fake_service",
-            "interface": "public",
-            "region": "FakeRegion",
-            "url": "http://fake_url/v3/second_endpoint/api"
-        },
-        {
-            "id": "third_fake_service",
-            "interface": "admin",
-            "region": "MiddleEarthRegion",
-            "url": "http://fake_url/v3/third_endpoint/api"
-        }
-
-    ],
-    "type": "compute",
-    "id": "fake_compute_endpoint"
-}
-
-CATALOG_V3 = [COMPUTE_ENDPOINTS_V3, ]
-
-IDENTITY_V3_RESPONSE = {
-    "token": {
-        "methods": [
-            "token",
-            "password"
-        ],
-        "expires_at": "2020-01-01T00:00:10.000123Z",
-        "project": {
-            "domain": {
-                "id": "fake_domain_id",
-                "name": "fake"
-            },
-            "id": "project_id",
-            "name": "project_name"
-        },
-        "user": {
-            "domain": {
-                "id": "fake_domain_id",
-                "name": "domain_name"
-            },
-            "id": "fake_user_id",
-            "name": "username"
-        },
-        "issued_at": "2013-05-29T16:55:21.468960Z",
-        "catalog": CATALOG_V3
-    }
-}
-
-ALT_IDENTITY_V3 = IDENTITY_V3_RESPONSE
-
-
-def _fake_v3_response(self, uri, method="GET", body=None, headers=None,
-                      redirections=5, connection_type=None):
-    fake_headers = {
-        "status": "201",
-        "x-subject-token": TOKEN
-    }
-    return (httplib2.Response(fake_headers),
-            json.dumps(IDENTITY_V3_RESPONSE))
-
-
-def _fake_v2_response(self, uri, method="GET", body=None, headers=None,
-                      redirections=5, connection_type=None):
-    return (httplib2.Response({"status": "200"}),
-            json.dumps(IDENTITY_V2_RESPONSE))
-
-
-def _fake_auth_failure_response():
-    # the response body isn't really used in this case, but lets send it anyway
-    # to have a safe check in some future change on the rest client.
-    body = {
-        "unauthorized": {
-            "message": "Unauthorized",
-            "code": "401"
-        }
-    }
-    return httplib2.Response({"status": "401"}), json.dumps(body)
diff --git a/tempest/tests/lib/fake_http.py b/tempest/tests/lib/fake_http.py
index eda202d..397c856 100644
--- a/tempest/tests/lib/fake_http.py
+++ b/tempest/tests/lib/fake_http.py
@@ -14,8 +14,6 @@
 
 import copy
 
-import httplib2
-
 
 class fake_httplib2(object):
 
@@ -25,7 +23,7 @@
     def request(self, uri, method="GET", body=None, headers=None,
                 redirections=5, connection_type=None):
         if not self.return_type:
-            fake_headers = httplib2.Response(headers)
+            fake_headers = fake_http_response(headers)
             return_obj = {
                 'uri': uri,
                 'method': method,
@@ -37,20 +35,20 @@
             body = body or "fake_body"
             header_info = {
                 'content-type': 'text/plain',
-                'status': str(self.return_type),
                 'content-length': len(body)
             }
-            resp_header = httplib2.Response(header_info)
+            resp_header = fake_http_response(header_info,
+                                             status=self.return_type)
             return (resp_header, body)
         else:
             msg = "unsupported return type %s" % self.return_type
             raise TypeError(msg)
 
 
-class fake_httplib(object):
+class fake_http_response(dict):
     def __init__(self, headers, body=None,
                  version=1.0, status=200, reason="Ok"):
-        """Fake httplib implementation
+        """Initialization of fake HTTP Response
 
         :param headers: dict representing HTTP response headers
         :param body: file-like object
@@ -60,10 +58,15 @@
         """
         self.body = body
         self.status = status
+        self['status'] = str(self.status)
         self.reason = reason
         self.version = version
         self.headers = headers
 
+        if headers:
+            for key, value in headers.items():
+                self[key.lower()] = value
+
     def getheaders(self):
         return copy.deepcopy(self.headers).items()
 
diff --git a/tempest/tests/lib/fake_identity.py b/tempest/tests/lib/fake_identity.py
index bac2676..5732065 100644
--- a/tempest/tests/lib/fake_identity.py
+++ b/tempest/tests/lib/fake_identity.py
@@ -13,9 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import json
+from oslo_serialization import jsonutils as json
 
-import httplib2
+from tempest.tests.lib import fake_http
 
 FAKE_AUTH_URL = 'http://fake_uri.com/auth'
 
@@ -139,16 +139,15 @@
 def _fake_v3_response(self, uri, method="GET", body=None, headers=None,
                       redirections=5, connection_type=None):
     fake_headers = {
-        "status": "201",
         "x-subject-token": TOKEN
     }
-    return (httplib2.Response(fake_headers),
+    return (fake_http.fake_http_response(fake_headers, status=201),
             json.dumps(IDENTITY_V3_RESPONSE))
 
 
 def _fake_v2_response(self, uri, method="GET", body=None, headers=None,
                       redirections=5, connection_type=None):
-    return (httplib2.Response({"status": "200"}),
+    return (fake_http.fake_http_response({}, status=200),
             json.dumps(IDENTITY_V2_RESPONSE))
 
 
@@ -161,4 +160,4 @@
             "code": "401"
         }
     }
-    return httplib2.Response({"status": "401"}), json.dumps(body)
+    return fake_http.fake_http_response({}, status=401), json.dumps(body)
diff --git a/tempest/tests/lib/services/compute/base.py b/tempest/tests/lib/services/compute/base.py
index 5602044..c805de2 100644
--- a/tempest/tests/lib/services/compute/base.py
+++ b/tempest/tests/lib/services/compute/base.py
@@ -12,11 +12,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import httplib2
 from oslo_serialization import jsonutils as json
 from oslotest import mockpatch
 
 from tempest.tests.lib import base
+from tempest.tests.lib import fake_http
 
 
 class BaseComputeServiceTest(base.TestCase):
@@ -26,11 +26,8 @@
             json_body = json.dumps(body)
             if to_utf:
                 json_body = json_body.encode('utf-8')
-        resp_dict = {'status': status}
-        if headers:
-            resp_dict.update(headers)
-        response = (httplib2.Response(resp_dict), json_body)
-        return response
+        resp = fake_http.fake_http_response(headers, status=status), json_body
+        return resp
 
     def check_service_client_function(self, function, function2mock,
                                       body, to_utf=False, status=200,
diff --git a/tempest/tests/lib/services/compute/test_base_compute_client.py b/tempest/tests/lib/services/compute/test_base_compute_client.py
index f552ef5..49d29b3 100644
--- a/tempest/tests/lib/services/compute/test_base_compute_client.py
+++ b/tempest/tests/lib/services/compute/test_base_compute_client.py
@@ -12,14 +12,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import httplib2
 import mock
-from oslotest import mockpatch
 
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions
 from tempest.lib.services.compute import base_compute_client
 from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib import fake_http
 from tempest.tests.lib.services.compute import base
 
 
@@ -36,28 +35,29 @@
         super(TestMicroversionHeaderCheck, self).tearDown()
         base_compute_client.COMPUTE_MICROVERSION = None
 
-    def _check_microverion_header_in_response(self, fake_response):
-        def request(*args, **kwargs):
-            return (httplib2.Response(fake_response), {})
-
-        self.useFixture(mockpatch.PatchObject(
-            rest_client.RestClient,
-            'request',
-            side_effect=request))
-
-    def test_correct_microverion_in_response(self):
-        fake_response = {self.client.api_microversion_header_name: '2.2'}
-        self._check_microverion_header_in_response(fake_response)
+    @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+    def test_correct_microverion_in_response(self, mock_request):
+        response = fake_http.fake_http_response(
+            headers={self.client.api_microversion_header_name: '2.2'},
+        )
+        mock_request.return_value = response, ''
         self.client.get('fake_url')
 
-    def test_incorrect_microverion_in_response(self):
-        fake_response = {self.client.api_microversion_header_name: '2.3'}
-        self._check_microverion_header_in_response(fake_response)
+    @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+    def test_incorrect_microverion_in_response(self, mock_request):
+        response = fake_http.fake_http_response(
+            headers={self.client.api_microversion_header_name: '2.3'},
+        )
+        mock_request.return_value = response, ''
         self.assertRaises(exceptions.InvalidHTTPResponseHeader,
                           self.client.get, 'fake_url')
 
-    def test_no_microverion_header_in_response(self):
-        self._check_microverion_header_in_response({})
+    @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+    def test_no_microverion_header_in_response(self, mock_request):
+        response = fake_http.fake_http_response(
+            headers={},
+        )
+        mock_request.return_value = response, ''
         self.assertRaises(exceptions.InvalidHTTPResponseHeader,
                           self.client.get, 'fake_url')
 
@@ -164,7 +164,7 @@
     def test_no_microverion_header_in_raw_request(self):
         def raw_request(*args, **kwargs):
             self.assertNotIn('X-OpenStack-Nova-API-Version', kwargs['headers'])
-            return (httplib2.Response({'status': 200}), {})
+            return (fake_http.fake_http_response({}, status=200), '')
 
         with mock.patch.object(rest_client.RestClient,
                                'raw_request') as mock_get:
@@ -196,9 +196,9 @@
             self.assertIn('X-OpenStack-Nova-API-Version', kwargs['headers'])
             self.assertEqual('2.2',
                              kwargs['headers']['X-OpenStack-Nova-API-Version'])
-            return (httplib2.Response(
-                {'status': 200,
-                 self.client.api_microversion_header_name: '2.2'}), {})
+            return (fake_http.fake_http_response(
+                headers={self.client.api_microversion_header_name: '2.2'},
+                status=200), '')
 
         with mock.patch.object(rest_client.RestClient,
                                'raw_request') as mock_get:
diff --git a/tempest/tests/lib/services/compute/test_flavors_client.py b/tempest/tests/lib/services/compute/test_flavors_client.py
index 795aff7..e22b4fe 100644
--- a/tempest/tests/lib/services/compute/test_flavors_client.py
+++ b/tempest/tests/lib/services/compute/test_flavors_client.py
@@ -13,13 +13,13 @@
 #    under the License.
 
 import copy
-import httplib2
 
 from oslo_serialization import jsonutils as json
 from oslotest import mockpatch
 
 from tempest.lib.services.compute import flavors_client
 from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib import fake_http
 from tempest.tests.lib.services.compute import base
 
 
@@ -117,7 +117,7 @@
         body = json.dumps({'flavors': [TestFlavorsClient.FAKE_FLAVOR]})
         if bytes_body:
             body = body.encode('utf-8')
-        response = (httplib2.Response({'status': 200}), body)
+        response = fake_http.fake_http_response({}, status=200), body
         self.useFixture(mockpatch.Patch(
             'tempest.lib.common.rest_client.RestClient.get',
             return_value=response))
diff --git a/tempest/tests/lib/services/compute/test_server_groups_client.py b/tempest/tests/lib/services/compute/test_server_groups_client.py
index f1f2906..cb163a8 100644
--- a/tempest/tests/lib/services/compute/test_server_groups_client.py
+++ b/tempest/tests/lib/services/compute/test_server_groups_client.py
@@ -12,12 +12,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import httplib2
-
 from oslotest import mockpatch
 from tempest.tests.lib import fake_auth_provider
 
 from tempest.lib.services.compute import server_groups_client
+from tempest.tests.lib import fake_http
 from tempest.tests.lib.services.compute import base
 
 
@@ -50,7 +49,7 @@
         self._test_create_server_group(bytes_body=True)
 
     def test_delete_server_group(self):
-        response = (httplib2.Response({'status': 204}), None)
+        response = fake_http.fake_http_response({}, status=204), ''
         self.useFixture(mockpatch.Patch(
             'tempest.lib.common.rest_client.RestClient.delete',
             return_value=response))
diff --git a/tempest/tests/lib/services/identity/v2/test_token_client.py b/tempest/tests/lib/services/identity/v2/test_token_client.py
index dd3533a..d91ecdc 100644
--- a/tempest/tests/lib/services/identity/v2/test_token_client.py
+++ b/tempest/tests/lib/services/identity/v2/test_token_client.py
@@ -14,8 +14,7 @@
 
 import json
 
-import httplib2
-from oslotest import mockpatch
+import mock
 
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions
@@ -28,7 +27,6 @@
 
     def setUp(self):
         super(TestTokenClientV2, self).setUp()
-        self.fake_200_http = fake_http.fake_httplib2(return_type=200)
 
     def test_init_without_authurl(self):
         self.assertRaises(exceptions.IdentityError,
@@ -36,10 +34,15 @@
 
     def test_auth(self):
         token_client_v2 = token_client.TokenClient('fake_url')
-        post_mock = self.useFixture(mockpatch.PatchObject(
-            token_client_v2, 'post', return_value=self.fake_200_http.request(
-                'fake_url', body={'access': {'token': 'fake_token'}})))
-        resp = token_client_v2.auth('fake_user', 'fake_pass')
+        response = fake_http.fake_http_response(
+            None, status=200,
+        )
+        body = {'access': {'token': 'fake_token'}}
+
+        with mock.patch.object(token_client_v2, 'post') as post_mock:
+            post_mock.return_value = response, body
+            resp = token_client_v2.auth('fake_user', 'fake_pass')
+
         self.assertIsInstance(resp, rest_client.ResponseBody)
         req_dict = json.dumps({
             'auth': {
@@ -49,15 +52,21 @@
                 },
             }
         }, sort_keys=True)
-        post_mock.mock.assert_called_once_with('fake_url/tokens',
-                                               body=req_dict)
+        post_mock.assert_called_once_with('fake_url/tokens',
+                                          body=req_dict)
 
     def test_auth_with_tenant(self):
         token_client_v2 = token_client.TokenClient('fake_url')
-        post_mock = self.useFixture(mockpatch.PatchObject(
-            token_client_v2, 'post', return_value=self.fake_200_http.request(
-                'fake_url', body={'access': {'token': 'fake_token'}})))
-        resp = token_client_v2.auth('fake_user', 'fake_pass', 'fake_tenant')
+        response = fake_http.fake_http_response(
+            None, status=200,
+        )
+        body = {'access': {'token': 'fake_token'}}
+
+        with mock.patch.object(token_client_v2, 'post') as post_mock:
+            post_mock.return_value = response, body
+            resp = token_client_v2.auth('fake_user', 'fake_pass',
+                                        'fake_tenant')
+
         self.assertIsInstance(resp, rest_client.ResponseBody)
         req_dict = json.dumps({
             'auth': {
@@ -68,25 +77,31 @@
                 },
             }
         }, sort_keys=True)
-        post_mock.mock.assert_called_once_with('fake_url/tokens',
-                                               body=req_dict)
+        post_mock.assert_called_once_with('fake_url/tokens',
+                                          body=req_dict)
 
     def test_request_with_str_body(self):
         token_client_v2 = token_client.TokenClient('fake_url')
-        self.useFixture(mockpatch.PatchObject(
-            token_client_v2, 'raw_request', return_value=(
-                httplib2.Response({'status': '200'}),
-                str('{"access": {"token": "fake_token"}}'))))
-        resp, body = token_client_v2.request('GET', 'fake_uri')
-        self.assertIsInstance(resp, httplib2.Response)
+        response = fake_http.fake_http_response(
+            None, status=200,
+        )
+        body = str('{"access": {"token": "fake_token"}}')
+
+        with mock.patch.object(token_client_v2, 'raw_request') as mock_raw_r:
+            mock_raw_r.return_value = response, body
+            resp, body = token_client_v2.request('GET', 'fake_uri')
         self.assertIsInstance(body, dict)
 
     def test_request_with_bytes_body(self):
         token_client_v2 = token_client.TokenClient('fake_url')
-        self.useFixture(mockpatch.PatchObject(
-            token_client_v2, 'raw_request', return_value=(
-                httplib2.Response({'status': '200'}),
-                bytes(b'{"access": {"token": "fake_token"}}'))))
-        resp, body = token_client_v2.request('GET', 'fake_uri')
-        self.assertIsInstance(resp, httplib2.Response)
+
+        response = fake_http.fake_http_response(
+            None, status=200,
+        )
+        body = b'{"access": {"token": "fake_token"}}'
+
+        with mock.patch.object(token_client_v2, 'raw_request') as mock_raw_r:
+            mock_raw_r.return_value = response, body
+            resp, body = token_client_v2.request('GET', 'fake_uri')
+
         self.assertIsInstance(body, dict)
diff --git a/tempest/tests/lib/services/identity/v3/test_token_client.py b/tempest/tests/lib/services/identity/v3/test_token_client.py
index bb4dae3..52b8e01 100644
--- a/tempest/tests/lib/services/identity/v3/test_token_client.py
+++ b/tempest/tests/lib/services/identity/v3/test_token_client.py
@@ -14,8 +14,7 @@
 
 import json
 
-import httplib2
-from oslotest import mockpatch
+import mock
 
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions
@@ -24,11 +23,10 @@
 from tempest.tests.lib import fake_http
 
 
-class TestTokenClientV2(base.TestCase):
+class TestTokenClientV3(base.TestCase):
 
     def setUp(self):
-        super(TestTokenClientV2, self).setUp()
-        self.fake_201_http = fake_http.fake_httplib2(return_type=201)
+        super(TestTokenClientV3, self).setUp()
 
     def test_init_without_authurl(self):
         self.assertRaises(exceptions.IdentityError,
@@ -36,10 +34,16 @@
 
     def test_auth(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
-        post_mock = self.useFixture(mockpatch.PatchObject(
-            token_client_v3, 'post', return_value=self.fake_201_http.request(
-                'fake_url', body={'access': {'token': 'fake_token'}})))
-        resp = token_client_v3.auth(username='fake_user', password='fake_pass')
+        response = fake_http.fake_http_response(
+            None, status=201,
+        )
+        body = {'access': {'token': 'fake_token'}}
+
+        with mock.patch.object(token_client_v3, 'post') as post_mock:
+            post_mock.return_value = response, body
+            resp = token_client_v3.auth(username='fake_user',
+                                        password='fake_pass')
+
         self.assertIsInstance(resp, rest_client.ResponseBody)
         req_dict = json.dumps({
             'auth': {
@@ -54,19 +58,24 @@
                 },
             }
         }, sort_keys=True)
-        post_mock.mock.assert_called_once_with('fake_url/auth/tokens',
-                                               body=req_dict)
+        post_mock.assert_called_once_with('fake_url/auth/tokens',
+                                          body=req_dict)
 
     def test_auth_with_project_id_and_domain_id(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
-        post_mock = self.useFixture(mockpatch.PatchObject(
-            token_client_v3, 'post', return_value=self.fake_201_http.request(
-                'fake_url', body={'access': {'token': 'fake_token'}})))
-        resp = token_client_v3.auth(
-            username='fake_user', password='fake_pass',
-            project_id='fcac2a055a294e4c82d0a9c21c620eb4',
-            user_domain_id='14f4a9a99973404d8c20ba1d2af163ff',
-            project_domain_id='291f63ae9ac54ee292ca09e5f72d9676')
+        response = fake_http.fake_http_response(
+            None, status=201,
+        )
+        body = {'access': {'token': 'fake_token'}}
+
+        with mock.patch.object(token_client_v3, 'post') as post_mock:
+            post_mock.return_value = response, body
+            resp = token_client_v3.auth(
+                username='fake_user', password='fake_pass',
+                project_id='fcac2a055a294e4c82d0a9c21c620eb4',
+                user_domain_id='14f4a9a99973404d8c20ba1d2af163ff',
+                project_domain_id='291f63ae9ac54ee292ca09e5f72d9676')
+
         self.assertIsInstance(resp, rest_client.ResponseBody)
         req_dict = json.dumps({
             'auth': {
@@ -92,16 +101,22 @@
                 }
             }
         }, sort_keys=True)
-        post_mock.mock.assert_called_once_with('fake_url/auth/tokens',
-                                               body=req_dict)
+        post_mock.assert_called_once_with('fake_url/auth/tokens',
+                                          body=req_dict)
 
     def test_auth_with_tenant(self):
-        token_client_v2 = token_client.V3TokenClient('fake_url')
-        post_mock = self.useFixture(mockpatch.PatchObject(
-            token_client_v2, 'post', return_value=self.fake_201_http.request(
-                'fake_url', body={'access': {'token': 'fake_token'}})))
-        resp = token_client_v2.auth(username='fake_user', password='fake_pass',
-                                    project_name='fake_tenant')
+        token_client_v3 = token_client.V3TokenClient('fake_url')
+        response = fake_http.fake_http_response(
+            None, status=201,
+        )
+        body = {'access': {'token': 'fake_token'}}
+
+        with mock.patch.object(token_client_v3, 'post') as post_mock:
+            post_mock.return_value = response, body
+            resp = token_client_v3.auth(username='fake_user',
+                                        password='fake_pass',
+                                        project_name='fake_tenant')
+
         self.assertIsInstance(resp, rest_client.ResponseBody)
         req_dict = json.dumps({
             'auth': {
@@ -121,25 +136,32 @@
             }
         }, sort_keys=True)
 
-        post_mock.mock.assert_called_once_with('fake_url/auth/tokens',
-                                               body=req_dict)
+        post_mock.assert_called_once_with('fake_url/auth/tokens',
+                                          body=req_dict)
 
     def test_request_with_str_body(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
-        self.useFixture(mockpatch.PatchObject(
-            token_client_v3, 'raw_request', return_value=(
-                httplib2.Response({"status": "200"}),
-                str('{"access": {"token": "fake_token"}}'))))
-        resp, body = token_client_v3.request('GET', 'fake_uri')
-        self.assertIsInstance(resp, httplib2.Response)
+        response = fake_http.fake_http_response(
+            None, status=200,
+        )
+        body = str('{"access": {"token": "fake_token"}}')
+
+        with mock.patch.object(token_client_v3, 'raw_request') as mock_raw_r:
+            mock_raw_r.return_value = response, body
+            resp, body = token_client_v3.request('GET', 'fake_uri')
+
         self.assertIsInstance(body, dict)
 
     def test_request_with_bytes_body(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
-        self.useFixture(mockpatch.PatchObject(
-            token_client_v3, 'raw_request', return_value=(
-                httplib2.Response({"status": "200"}),
-                bytes(b'{"access": {"token": "fake_token"}}'))))
-        resp, body = token_client_v3.request('GET', 'fake_uri')
-        self.assertIsInstance(resp, httplib2.Response)
+
+        response = fake_http.fake_http_response(
+            None, status=200,
+        )
+        body = b'{"access": {"token": "fake_token"}}'
+
+        with mock.patch.object(token_client_v3, 'raw_request') as mock_raw_r:
+            mock_raw_r.return_value = response, body
+            resp, body = token_client_v3.request('GET', 'fake_uri')
+
         self.assertIsInstance(body, dict)
diff --git a/tempest/tests/lib/test_auth.py b/tempest/tests/lib/test_auth.py
index 55f0c4e..5aeb47c 100644
--- a/tempest/tests/lib/test_auth.py
+++ b/tempest/tests/lib/test_auth.py
@@ -24,7 +24,6 @@
 from tempest.lib.services.identity.v3 import token_client as v3_client
 from tempest.tests.lib import base
 from tempest.tests.lib import fake_credentials
-from tempest.tests.lib import fake_http
 from tempest.tests.lib import fake_identity
 
 
@@ -42,7 +41,6 @@
 
     def setUp(self):
         super(BaseAuthTestsSetUp, self).setUp()
-        self.fake_http = fake_http.fake_httplib2(return_type=200)
         self.stubs.Set(auth, 'get_credentials', fake_get_credentials)
         self.auth_provider = self._auth(self.credentials,
                                         fake_identity.FAKE_AUTH_URL)
diff --git a/tempest/tests/lib/test_rest_client.py b/tempest/tests/lib/test_rest_client.py
index 87af455..90651b0 100644
--- a/tempest/tests/lib/test_rest_client.py
+++ b/tempest/tests/lib/test_rest_client.py
@@ -15,11 +15,11 @@
 import copy
 import json
 
-import httplib2
 import jsonschema
 from oslotest import mockpatch
 import six
 
+from tempest.lib.common import http
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions
 from tempest.tests.lib import base
@@ -37,7 +37,9 @@
         self.fake_auth_provider = fake_auth_provider.FakeAuthProvider()
         self.rest_client = rest_client.RestClient(
             self.fake_auth_provider, None, None)
-        self.stubs.Set(httplib2.Http, 'request', self.fake_http.request)
+        self.stubs.Set(http.ClosingHttp, 'request',
+                       self.fake_http.request)
+
         self.useFixture(mockpatch.PatchObject(self.rest_client,
                                               '_log_request'))
 
@@ -292,7 +294,9 @@
         if absolute_limit is False:
             resp_dict.update({'retry-after': 120})
             resp_body.update({'overLimit': {'message': 'fake_message'}})
-        resp = httplib2.Response(resp_dict)
+        resp = fake_http.fake_http_response(headers=resp_dict,
+                                            status=int(r_code),
+                                            body=json.dumps(resp_body))
         data = {
             "method": "fake_method",
             "url": "fake_url",
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
index 10f80a7..fdbc2d2 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -23,19 +23,14 @@
 from tempest.common import glance_http
 from tempest import exceptions
 from tempest.tests import fake_auth_provider
-from tempest.tests import fake_http
 from tempest.tests.lib import base
+from tempest.tests.lib import fake_http
 
 
 class TestGlanceHTTPClient(base.TestCase):
 
     def setUp(self):
         super(TestGlanceHTTPClient, self).setUp()
-        self.fake_http = fake_http.fake_httplib2(return_type=200)
-        # NOTE(maurosr): using http here implies that we will be using httplib
-        # directly. With https glance_client would use an httpS version, but
-        # the real backend would still be httplib anyway and since we mock it
-        # that there is no reason to care.
         self.endpoint = 'http://fake_url.com'
         self.fake_auth = fake_auth_provider.FakeAuthProvider()
 
@@ -44,12 +39,12 @@
         self.useFixture(mockpatch.PatchObject(
             httplib.HTTPConnection,
             'request',
-            side_effect=self.fake_http.request(self.endpoint)[1]))
+            side_effect=b'fake_body'))
         self.client = glance_http.HTTPClient(self.fake_auth, {})
 
     def _set_response_fixture(self, header, status, resp_body):
-        resp = fake_http.fake_httplib(header, status=status,
-                                      body=six.StringIO(resp_body))
+        resp = fake_http.fake_http_response(header, status=status,
+                                            body=six.StringIO(resp_body))
         self.useFixture(mockpatch.PatchObject(httplib.HTTPConnection,
                         'getresponse', return_value=resp))
         return resp
@@ -223,7 +218,7 @@
 class TestResponseBodyIterator(base.TestCase):
 
     def test_iter_default_chunk_size_64k(self):
-        resp = fake_http.fake_httplib({}, six.StringIO(
+        resp = fake_http.fake_http_response({}, six.StringIO(
             'X' * (glance_http.CHUNKSIZE + 1)))
         iterator = glance_http.ResponseBodyIterator(resp)
         chunks = list(iterator)
diff --git a/tempest/tests/test_negative_rest_client.py b/tempest/tests/test_negative_rest_client.py
index 6a071b1..a1b5f0e 100644
--- a/tempest/tests/test_negative_rest_client.py
+++ b/tempest/tests/test_negative_rest_client.py
@@ -15,14 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import httplib2
+import mock
 from oslotest import mockpatch
 
 from tempest.common import negative_rest_client
 from tempest import config
 from tempest.tests import fake_auth_provider
 from tempest.tests import fake_config
-from tempest.tests import fake_http
 from tempest.tests.lib import base
 
 
@@ -31,59 +30,69 @@
     url = 'fake_endpoint'
 
     def setUp(self):
-        self.fake_http = fake_http.fake_httplib2()
         super(TestNegativeRestClient, self).setUp()
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
-        self.stubs.Set(httplib2.Http, 'request', self.fake_http.request)
         self.negative_rest_client = negative_rest_client.NegativeRestClient(
             fake_auth_provider.FakeAuthProvider(), None)
         self.useFixture(mockpatch.PatchObject(self.negative_rest_client,
                                               '_log_request'))
 
-    def test_post(self):
+    @mock.patch('tempest.lib.common.rest_client.RestClient.post',
+                return_value=(mock.Mock(), mock.Mock()))
+    def test_post(self, mock_post):
         __, return_dict = self.negative_rest_client.send_request('POST',
                                                                  self.url,
                                                                  [], {})
-        self.assertEqual('POST', return_dict['method'])
+        mock_post.assert_called_once_with(self.url, {})
 
-    def test_get(self):
+    @mock.patch('tempest.lib.common.rest_client.RestClient.get',
+                return_value=(mock.Mock(), mock.Mock()))
+    def test_get(self, mock_get):
         __, return_dict = self.negative_rest_client.send_request('GET',
                                                                  self.url,
                                                                  [])
-        self.assertEqual('GET', return_dict['method'])
+        mock_get.assert_called_once_with(self.url)
 
-    def test_delete(self):
+    @mock.patch('tempest.lib.common.rest_client.RestClient.delete',
+                return_value=(mock.Mock(), mock.Mock()))
+    def test_delete(self, mock_delete):
         __, return_dict = self.negative_rest_client.send_request('DELETE',
                                                                  self.url,
                                                                  [])
-        self.assertEqual('DELETE', return_dict['method'])
+        mock_delete.assert_called_once_with(self.url)
 
-    def test_patch(self):
+    @mock.patch('tempest.lib.common.rest_client.RestClient.patch',
+                return_value=(mock.Mock(), mock.Mock()))
+    def test_patch(self, mock_patch):
         __, return_dict = self.negative_rest_client.send_request('PATCH',
                                                                  self.url,
                                                                  [], {})
-        self.assertEqual('PATCH', return_dict['method'])
+        mock_patch.assert_called_once_with(self.url, {})
 
-    def test_put(self):
+    @mock.patch('tempest.lib.common.rest_client.RestClient.put',
+                return_value=(mock.Mock(), mock.Mock()))
+    def test_put(self, mock_put):
         __, return_dict = self.negative_rest_client.send_request('PUT',
                                                                  self.url,
                                                                  [], {})
-        self.assertEqual('PUT', return_dict['method'])
+        mock_put.assert_called_once_with(self.url, {})
 
-    def test_head(self):
-        self.useFixture(mockpatch.PatchObject(self.negative_rest_client,
-                                              'response_checker'))
+    @mock.patch('tempest.lib.common.rest_client.RestClient.head',
+                return_value=(mock.Mock(), mock.Mock()))
+    def test_head(self, mock_head):
         __, return_dict = self.negative_rest_client.send_request('HEAD',
                                                                  self.url,
                                                                  [])
-        self.assertEqual('HEAD', return_dict['method'])
+        mock_head.assert_called_once_with(self.url)
 
-    def test_copy(self):
+    @mock.patch('tempest.lib.common.rest_client.RestClient.copy',
+                return_value=(mock.Mock(), mock.Mock()))
+    def test_copy(self, mock_copy):
         __, return_dict = self.negative_rest_client.send_request('COPY',
                                                                  self.url,
                                                                  [])
-        self.assertEqual('COPY', return_dict['method'])
+        mock_copy.assert_called_once_with(self.url)
 
     def test_other(self):
         self.assertRaises(AssertionError,