Merge "Remove the Glance HTTP client. Use the common Rest Client instead."
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
deleted file mode 100644
index 00062de..0000000
--- a/tempest/common/glance_http.py
+++ /dev/null
@@ -1,361 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-# Originally copied from python-glanceclient
-
-import copy
-import hashlib
-import posixpath
-import re
-import socket
-import struct
-
-import OpenSSL
-from oslo_log import log as logging
-import six
-from six import moves
-from six.moves import http_client as httplib
-from six.moves.urllib import parse as urlparse
-
-from tempest import exceptions as exc
-
-LOG = logging.getLogger(__name__)
-USER_AGENT = 'tempest'
-CHUNKSIZE = 1024 * 64  # 64kB
-TOKEN_CHARS_RE = re.compile('^[-A-Za-z0-9+/=]*$')
-
-
-class HTTPClient(object):
-
-    def __init__(self, auth_provider, filters, **kwargs):
-        self.auth_provider = auth_provider
-        self.filters = filters
-        self.endpoint = auth_provider.base_url(filters)
-        endpoint_parts = urlparse.urlparse(self.endpoint)
-        self.endpoint_scheme = endpoint_parts.scheme
-        self.endpoint_hostname = endpoint_parts.hostname
-        self.endpoint_port = endpoint_parts.port
-
-        self.connection_class = self._get_connection_class(
-            self.endpoint_scheme)
-        self.connection_kwargs = self._get_connection_kwargs(
-            self.endpoint_scheme, **kwargs)
-
-    @staticmethod
-    def _get_connection_class(scheme):
-        if scheme == 'https':
-            return VerifiedHTTPSConnection
-        else:
-            return httplib.HTTPConnection
-
-    @staticmethod
-    def _get_connection_kwargs(scheme, **kwargs):
-        _kwargs = {'timeout': float(kwargs.get('timeout', 600))}
-
-        if scheme == 'https':
-            _kwargs['ca_certs'] = kwargs.get('ca_certs', None)
-            _kwargs['cert_file'] = kwargs.get('cert_file', None)
-            _kwargs['key_file'] = kwargs.get('key_file', None)
-            _kwargs['insecure'] = kwargs.get('insecure', False)
-            _kwargs['ssl_compression'] = kwargs.get('ssl_compression', True)
-
-        return _kwargs
-
-    def _get_connection(self):
-        _class = self.connection_class
-        try:
-            return _class(self.endpoint_hostname, self.endpoint_port,
-                          **self.connection_kwargs)
-        except httplib.InvalidURL:
-            raise exc.EndpointNotFound
-
-    def _http_request(self, url, method, **kwargs):
-        """Send an http request with the specified characteristics.
-
-        Wrapper around httplib.HTTP(S)Connection.request to handle tasks such
-        as setting headers and error handling.
-        """
-        # Copy the kwargs so we can reuse the original in case of redirects
-        kwargs['headers'] = copy.deepcopy(kwargs.get('headers', {}))
-        kwargs['headers'].setdefault('User-Agent', USER_AGENT)
-
-        self._log_request(method, url, kwargs['headers'])
-
-        conn = self._get_connection()
-
-        try:
-            url_parts = urlparse.urlparse(url)
-            conn_url = posixpath.normpath(url_parts.path)
-            LOG.debug('Actual Path: {path}'.format(path=conn_url))
-            if kwargs['headers'].get('Transfer-Encoding') == 'chunked':
-                conn.putrequest(method, conn_url)
-                for header, value in kwargs['headers'].items():
-                    conn.putheader(header, value)
-                conn.endheaders()
-                chunk = kwargs['body'].read(CHUNKSIZE)
-                # Chunk it, baby...
-                while chunk:
-                    conn.send('%x\r\n%s\r\n' % (len(chunk), chunk))
-                    chunk = kwargs['body'].read(CHUNKSIZE)
-                conn.send('0\r\n\r\n')
-            else:
-                conn.request(method, conn_url, **kwargs)
-            resp = conn.getresponse()
-        except socket.gaierror as e:
-            message = ("Error finding address for %(url)s: %(e)s" %
-                       {'url': url, 'e': e})
-            raise exc.EndpointNotFound(message)
-        except (socket.error, socket.timeout) as e:
-            message = ("Error communicating with %(endpoint)s %(e)s" %
-                       {'endpoint': self.endpoint, 'e': e})
-            raise exc.TimeoutException(message)
-
-        body_iter = ResponseBodyIterator(resp)
-        # Read body into string if it isn't obviously image data
-        if resp.getheader('content-type', None) != 'application/octet-stream':
-            body_str = ''.join([body_chunk for body_chunk in body_iter])
-            body_iter = six.StringIO(body_str)
-            self._log_response(resp, None)
-        else:
-            self._log_response(resp, body_iter)
-
-        return resp, body_iter
-
-    def _log_request(self, method, url, headers):
-        LOG.info('Request: ' + method + ' ' + url)
-        if headers:
-            headers_out = headers
-            if 'X-Auth-Token' in headers and headers['X-Auth-Token']:
-                token = headers['X-Auth-Token']
-                if len(token) > 64 and TOKEN_CHARS_RE.match(token):
-                    headers_out = headers.copy()
-                    headers_out['X-Auth-Token'] = "<Token omitted>"
-                LOG.info('Request Headers: ' + str(headers_out))
-
-    def _log_response(self, resp, body):
-        status = str(resp.status)
-        LOG.info("Response Status: " + status)
-        if resp.getheaders():
-            LOG.info('Response Headers: ' + str(resp.getheaders()))
-        if body:
-            str_body = str(body)
-            length = len(body)
-            LOG.info('Response Body: ' + str_body[:2048])
-            if length >= 2048:
-                self.LOG.debug("Large body (%d) md5 summary: %s", length,
-                               hashlib.md5(str_body).hexdigest())
-
-    def raw_request(self, method, url, **kwargs):
-        kwargs.setdefault('headers', {})
-        kwargs['headers'].setdefault('Content-Type',
-                                     'application/octet-stream')
-        if 'body' in kwargs:
-            if (hasattr(kwargs['body'], 'read')
-                    and method.lower() in ('post', 'put')):
-                # We use 'Transfer-Encoding: chunked' because
-                # body size may not always be known in advance.
-                kwargs['headers']['Transfer-Encoding'] = 'chunked'
-
-        # Decorate the request with auth
-        req_url, kwargs['headers'], kwargs['body'] = \
-            self.auth_provider.auth_request(
-                method=method, url=url, headers=kwargs['headers'],
-                body=kwargs.get('body', None), filters=self.filters)
-        return self._http_request(req_url, method, **kwargs)
-
-
-class OpenSSLConnectionDelegator(object):
-    """An OpenSSL.SSL.Connection delegator.
-
-    Supplies an additional 'makefile' method which httplib requires
-    and is not present in OpenSSL.SSL.Connection.
-
-    Note: Since it is not possible to inherit from OpenSSL.SSL.Connection
-    a delegator must be used.
-    """
-    def __init__(self, *args, **kwargs):
-        self.connection = OpenSSL.SSL.Connection(*args, **kwargs)
-
-    def __getattr__(self, name):
-        return getattr(self.connection, name)
-
-    def makefile(self, *args, **kwargs):
-        # Ensure the socket is closed when this file is closed
-        kwargs['close'] = True
-        return socket._fileobject(self.connection, *args, **kwargs)
-
-
-class VerifiedHTTPSConnection(httplib.HTTPSConnection):
-    """Extended HTTPSConnection which uses OpenSSL library for enhanced SSL
-
-    Note: Much of this functionality can eventually be replaced
-          with native Python 3.3 code.
-    """
-    def __init__(self, host, port=None, key_file=None, cert_file=None,
-                 ca_certs=None, timeout=None, insecure=False,
-                 ssl_compression=True):
-        httplib.HTTPSConnection.__init__(self, host, port,
-                                         key_file=key_file,
-                                         cert_file=cert_file)
-        self.key_file = key_file
-        self.cert_file = cert_file
-        self.timeout = timeout
-        self.insecure = insecure
-        self.ssl_compression = ssl_compression
-        self.ca_certs = ca_certs
-        self.setcontext()
-
-    @staticmethod
-    def host_matches_cert(host, x509):
-        """Verify that the x509 certificate we have received from 'host'
-
-        Identifies the server we are connecting to, ie that the certificate's
-        Common Name or a Subject Alternative Name matches 'host'.
-        """
-        # First see if we can match the CN
-        if x509.get_subject().commonName == host:
-            return True
-
-        # Also try Subject Alternative Names for a match
-        san_list = None
-        for i in moves.xrange(x509.get_extension_count()):
-            ext = x509.get_extension(i)
-            if ext.get_short_name() == 'subjectAltName':
-                san_list = str(ext)
-                for san in ''.join(san_list.split()).split(','):
-                    if san == "DNS:%s" % host:
-                        return True
-
-        # Server certificate does not match host
-        msg = ('Host "%s" does not match x509 certificate contents: '
-               'CommonName "%s"' % (host, x509.get_subject().commonName))
-        if san_list is not None:
-            msg = msg + ', subjectAltName "%s"' % san_list
-        raise exc.SSLCertificateError(msg)
-
-    def verify_callback(self, connection, x509, errnum,
-                        depth, preverify_ok):
-        if x509.has_expired():
-            msg = "SSL Certificate expired on '%s'" % x509.get_notAfter()
-            raise exc.SSLCertificateError(msg)
-
-        if depth == 0 and preverify_ok is True:
-            # We verify that the host matches against the last
-            # certificate in the chain
-            return self.host_matches_cert(self.host, x509)
-        else:
-            # Pass through OpenSSL's default result
-            return preverify_ok
-
-    def setcontext(self):
-        """Set up the OpenSSL context."""
-        self.context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
-
-        if self.ssl_compression is False:
-            self.context.set_options(0x20000)  # SSL_OP_NO_COMPRESSION
-
-        if self.insecure is not True:
-            self.context.set_verify(OpenSSL.SSL.VERIFY_PEER,
-                                    self.verify_callback)
-        else:
-            self.context.set_verify(OpenSSL.SSL.VERIFY_NONE,
-                                    self.verify_callback)
-
-        if self.cert_file:
-            try:
-                self.context.use_certificate_file(self.cert_file)
-            except Exception as e:
-                msg = 'Unable to load cert from "%s" %s' % (self.cert_file, e)
-                raise exc.SSLConfigurationError(msg)
-            if self.key_file is None:
-                # We support having key and cert in same file
-                try:
-                    self.context.use_privatekey_file(self.cert_file)
-                except Exception as e:
-                    msg = ('No key file specified and unable to load key '
-                           'from "%s" %s' % (self.cert_file, e))
-                    raise exc.SSLConfigurationError(msg)
-
-        if self.key_file:
-            try:
-                self.context.use_privatekey_file(self.key_file)
-            except Exception as e:
-                msg = 'Unable to load key from "%s" %s' % (self.key_file, e)
-                raise exc.SSLConfigurationError(msg)
-
-        if self.ca_certs:
-            try:
-                self.context.load_verify_locations(self.ca_certs)
-            except Exception as e:
-                msg = 'Unable to load CA from "%s" %s' % (self.ca_certs, e)
-                raise exc.SSLConfigurationError(msg)
-        else:
-            self.context.set_default_verify_paths()
-
-    def connect(self):
-        """Connect to SSL port and apply per-connection parameters."""
-        try:
-            addresses = socket.getaddrinfo(self.host,
-                                           self.port,
-                                           socket.AF_UNSPEC,
-                                           socket.SOCK_STREAM)
-        except OSError as msg:
-            raise exc.RestClientException(msg)
-        for res in addresses:
-            af, socktype, proto, canonname, sa = res
-            sock = socket.socket(af, socket.SOCK_STREAM)
-
-            if self.timeout is not None:
-                # '0' microseconds
-                sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO,
-                                struct.pack('LL', self.timeout, 0))
-            self.sock = OpenSSLConnectionDelegator(self.context, sock)
-            try:
-                self.sock.connect(sa)
-            except OSError as msg:
-                if self.sock:
-                    self.sock = None
-                    continue
-            break
-        if self.sock is None:
-            # Happen only when all results have failed.
-            raise exc.RestClientException('Cannot connect to %s' % self.host)
-
-    def close(self):
-        if self.sock:
-            # Remove the reference to the socket but don't close it yet.
-            # Response close will close both socket and associated
-            # file. Closing socket too soon will cause response
-            # reads to fail with socket IO error 'Bad file descriptor'.
-            self.sock = None
-        httplib.HTTPSConnection.close(self)
-
-
-class ResponseBodyIterator(object):
-    """A class that acts as an iterator over an HTTP response."""
-
-    def __init__(self, resp):
-        self.resp = resp
-
-    def __iter__(self):
-        while True:
-            yield self.next()
-
-    def next(self):
-        chunk = self.resp.read(CHUNKSIZE)
-        if chunk:
-            return chunk
-        else:
-            raise StopIteration()
diff --git a/tempest/services/image/v1/json/images_client.py b/tempest/services/image/v1/json/images_client.py
index a36075f..922b626 100644
--- a/tempest/services/image/v1/json/images_client.py
+++ b/tempest/services/image/v1/json/images_client.py
@@ -15,6 +15,7 @@
 
 import copy
 import errno
+import functools
 import os
 
 from oslo_log import log as logging
@@ -22,11 +23,11 @@
 import six
 from six.moves.urllib import parse as urllib
 
-from tempest.common import glance_http
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions as lib_exc
 
 LOG = logging.getLogger(__name__)
+CHUNKSIZE = 1024 * 64  # 64kB
 
 
 class ImagesClient(rest_client.RestClient):
@@ -34,9 +35,6 @@
     def __init__(self, auth_provider, catalog_type, region, **kwargs):
         super(ImagesClient, self).__init__(
             auth_provider, catalog_type, region, **kwargs)
-        self._http = None
-        self.dscv = kwargs.get("disable_ssl_certificate_validation")
-        self.ca_certs = kwargs.get("ca_certs")
 
     def _image_meta_from_headers(self, headers):
         meta = {'properties': {}}
@@ -103,27 +101,29 @@
             # Cannot determine size of input image
             return None
 
-    def _get_http(self):
-        return glance_http.HTTPClient(auth_provider=self.auth_provider,
-                                      filters=self.filters,
-                                      insecure=self.dscv,
-                                      ca_certs=self.ca_certs)
-
     def _create_with_data(self, headers, data):
-        resp, body_iter = self.http.raw_request('POST', '/v1/images',
-                                                headers=headers, body=data)
+        # We are going to do chunked transfert, so split the input data
+        # info fixed-sized chunks.
+        headers['Content-Type'] = 'application/octet-stream'
+        data = iter(functools.partial(data.read, CHUNKSIZE), b'')
+        resp, body = self.request('POST', '/v1/images',
+                                  headers=headers, body=data, chunked=True)
         self._error_checker('POST', '/v1/images', headers, data, resp,
-                            body_iter)
-        body = json.loads(''.join([c for c in body_iter]))
+                            body)
+        body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def _update_with_data(self, image_id, headers, data):
+        # We are going to do chunked transfert, so split the input data
+        # info fixed-sized chunks.
+        headers['Content-Type'] = 'application/octet-stream'
+        data = iter(functools.partial(data.read, CHUNKSIZE), b'')
         url = '/v1/images/%s' % image_id
-        resp, body_iter = self.http.raw_request('PUT', url, headers=headers,
-                                                body=data)
+        resp, body = self.request('PUT', url, headers=headers,
+                                  body=data, chunked=True)
         self._error_checker('PUT', url, headers, data,
-                            resp, body_iter)
-        body = json.loads(''.join([c for c in body_iter]))
+                            resp, body)
+        body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     @property
diff --git a/tempest/services/image/v2/json/images_client.py b/tempest/services/image/v2/json/images_client.py
index a61f31d..88eafe1 100644
--- a/tempest/services/image/v2/json/images_client.py
+++ b/tempest/services/image/v2/json/images_client.py
@@ -13,34 +13,22 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import functools
+
 from oslo_serialization import jsonutils as json
 from six.moves.urllib import parse as urllib
 
-from tempest.common import glance_http
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions as lib_exc
 
+CHUNKSIZE = 1024 * 64  # 64kB
+
 
 class ImagesClient(rest_client.RestClient):
 
     def __init__(self, auth_provider, catalog_type, region, **kwargs):
         super(ImagesClient, self).__init__(
             auth_provider, catalog_type, region, **kwargs)
-        self._http = None
-        self.dscv = kwargs.get("disable_ssl_certificate_validation")
-        self.ca_certs = kwargs.get("ca_certs")
-
-    def _get_http(self):
-        return glance_http.HTTPClient(auth_provider=self.auth_provider,
-                                      filters=self.filters,
-                                      insecure=self.dscv,
-                                      ca_certs=self.ca_certs)
-
-    @property
-    def http(self):
-        if self._http is None:
-            self._http = self._get_http()
-        return self._http
 
     def update_image(self, image_id, patch):
         """Update an image.
@@ -118,9 +106,14 @@
 
     def store_image_file(self, image_id, data):
         url = 'v2/images/%s/file' % image_id
+
+        # We are going to do chunked transfert, so split the input data
+        # info fixed-sized chunks.
         headers = {'Content-Type': 'application/octet-stream'}
-        resp, body = self.http.raw_request('PUT', url, headers=headers,
-                                           body=data)
+        data = iter(functools.partial(data.read, CHUNKSIZE), b'')
+
+        resp, body = self.request('PUT', url, headers=headers,
+                                  body=data, chunked=True)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
deleted file mode 100644
index 768cd05..0000000
--- a/tempest/tests/test_glance_http.py
+++ /dev/null
@@ -1,225 +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 socket
-
-import mock
-from oslotest import mockpatch
-import six
-from six.moves import http_client as httplib
-
-from tempest.common import glance_http
-from tempest import exceptions
-from tempest.tests import base
-from tempest.tests import fake_auth_provider
-from tempest.tests.lib import fake_http
-
-
-class TestGlanceHTTPClient(base.TestCase):
-
-    def setUp(self):
-        super(TestGlanceHTTPClient, self).setUp()
-        self.endpoint = 'http://fake_url.com'
-        self.fake_auth = fake_auth_provider.FakeAuthProvider()
-
-        self.fake_auth.base_url = mock.MagicMock(return_value=self.endpoint)
-
-        self.useFixture(mockpatch.PatchObject(
-            httplib.HTTPConnection,
-            'request',
-            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_http_response(header, status=status,
-                                            body=six.StringIO(resp_body))
-        self.useFixture(mockpatch.PatchObject(httplib.HTTPConnection,
-                        'getresponse', return_value=resp))
-        return resp
-
-    def test_raw_request(self):
-        self._set_response_fixture({}, 200, 'fake_response_body')
-        resp, body = self.client.raw_request('GET', '/images')
-        self.assertEqual(200, resp.status)
-        self.assertEqual('fake_response_body', body.read())
-
-    def test_raw_request_with_response_chunked(self):
-        self._set_response_fixture({}, 200, 'fake_response_body')
-        self.useFixture(mockpatch.PatchObject(glance_http,
-                                              'CHUNKSIZE', 1))
-        resp, body = self.client.raw_request('GET', '/images')
-        self.assertEqual(200, resp.status)
-        self.assertEqual('fake_response_body', body.read())
-
-    def test_raw_request_chunked(self):
-        self.useFixture(mockpatch.PatchObject(glance_http,
-                                              'CHUNKSIZE', 1))
-        self.useFixture(mockpatch.PatchObject(httplib.HTTPConnection,
-                        'endheaders'))
-        self.useFixture(mockpatch.PatchObject(httplib.HTTPConnection,
-                        'send'))
-
-        self._set_response_fixture({}, 200, 'fake_response_body')
-        req_body = six.StringIO('fake_request_body')
-        resp, body = self.client.raw_request('PUT', '/images', body=req_body)
-        self.assertEqual(200, resp.status)
-        self.assertEqual('fake_response_body', body.read())
-        call_count = httplib.HTTPConnection.send.call_count
-        self.assertEqual(call_count - 1, req_body.tell())
-
-    def test_get_connection_class_for_https(self):
-        conn_class = self.client._get_connection_class('https')
-        self.assertEqual(glance_http.VerifiedHTTPSConnection, conn_class)
-
-    def test_get_connection_class_for_http(self):
-        conn_class = (self.client._get_connection_class('http'))
-        self.assertEqual(httplib.HTTPConnection, conn_class)
-
-    def test_get_connection_http(self):
-        self.assertIsInstance(self.client._get_connection(),
-                              httplib.HTTPConnection)
-
-    def test_get_connection_https(self):
-        endpoint = 'https://fake_url.com'
-        self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
-        self.client = glance_http.HTTPClient(self.fake_auth, {})
-        self.assertIsInstance(self.client._get_connection(),
-                              glance_http.VerifiedHTTPSConnection)
-
-    def test_get_connection_ipv4_https(self):
-        endpoint = 'https://127.0.0.1'
-        self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
-        self.client = glance_http.HTTPClient(self.fake_auth, {})
-        self.assertIsInstance(self.client._get_connection(),
-                              glance_http.VerifiedHTTPSConnection)
-
-    def test_get_connection_ipv6_https(self):
-        endpoint = 'https://[::1]'
-        self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
-        self.client = glance_http.HTTPClient(self.fake_auth, {})
-        self.assertIsInstance(self.client._get_connection(),
-                              glance_http.VerifiedHTTPSConnection)
-
-    def test_get_connection_url_not_fount(self):
-        self.useFixture(mockpatch.PatchObject(self.client, 'connection_class',
-                                              side_effect=httplib.InvalidURL()
-                                              ))
-        self.assertRaises(exceptions.EndpointNotFound,
-                          self.client._get_connection)
-
-    def test_get_connection_kwargs_default_for_http(self):
-        kwargs = self.client._get_connection_kwargs('http')
-        self.assertEqual(600, kwargs['timeout'])
-        self.assertEqual(1, len(kwargs.keys()))
-
-    def test_get_connection_kwargs_set_timeout_for_http(self):
-        kwargs = self.client._get_connection_kwargs('http', timeout=10,
-                                                    ca_certs='foo')
-        self.assertEqual(10, kwargs['timeout'])
-        # nothing more than timeout is evaluated for http connections
-        self.assertEqual(1, len(kwargs.keys()))
-
-    def test_get_connection_kwargs_default_for_https(self):
-        kwargs = self.client._get_connection_kwargs('https')
-        self.assertEqual(600, kwargs['timeout'])
-        self.assertIsNone(kwargs['ca_certs'])
-        self.assertIsNone(kwargs['cert_file'])
-        self.assertIsNone(kwargs['key_file'])
-        self.assertEqual(False, kwargs['insecure'])
-        self.assertEqual(True, kwargs['ssl_compression'])
-        self.assertEqual(6, len(kwargs.keys()))
-
-    def test_get_connection_kwargs_set_params_for_https(self):
-        kwargs = self.client._get_connection_kwargs('https', timeout=10,
-                                                    ca_certs='foo',
-                                                    cert_file='/foo/bar.cert',
-                                                    key_file='/foo/key.pem',
-                                                    insecure=True,
-                                                    ssl_compression=False)
-        self.assertEqual(10, kwargs['timeout'])
-        self.assertEqual('foo', kwargs['ca_certs'])
-        self.assertEqual('/foo/bar.cert', kwargs['cert_file'])
-        self.assertEqual('/foo/key.pem', kwargs['key_file'])
-        self.assertEqual(True, kwargs['insecure'])
-        self.assertEqual(False, kwargs['ssl_compression'])
-        self.assertEqual(6, len(kwargs.keys()))
-
-
-class TestVerifiedHTTPSConnection(base.TestCase):
-
-    @mock.patch('socket.socket')
-    @mock.patch('tempest.common.glance_http.OpenSSLConnectionDelegator')
-    def test_connect_ipv4(self, mock_delegator, mock_socket):
-        connection = glance_http.VerifiedHTTPSConnection('127.0.0.1')
-        connection.connect()
-
-        mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_STREAM)
-        mock_delegator.assert_called_once_with(connection.context,
-                                               mock_socket.return_value)
-        mock_delegator.return_value.connect.assert_called_once_with(
-            (connection.host, 443))
-
-    @mock.patch('socket.socket')
-    @mock.patch('tempest.common.glance_http.OpenSSLConnectionDelegator')
-    def test_connect_ipv6(self, mock_delegator, mock_socket):
-        connection = glance_http.VerifiedHTTPSConnection('[::1]')
-        connection.connect()
-
-        mock_socket.assert_called_once_with(socket.AF_INET6,
-                                            socket.SOCK_STREAM)
-        mock_delegator.assert_called_once_with(connection.context,
-                                               mock_socket.return_value)
-        mock_delegator.return_value.connect.assert_called_once_with(
-            (connection.host, 443, 0, 0))
-
-    @mock.patch('tempest.common.glance_http.OpenSSLConnectionDelegator')
-    @mock.patch('socket.getaddrinfo',
-                side_effect=OSError('Gettaddrinfo failed'))
-    def test_connect_with_address_lookup_failure(self, mock_getaddrinfo,
-                                                 mock_delegator):
-        connection = glance_http.VerifiedHTTPSConnection('127.0.0.1')
-        self.assertRaises(exceptions.RestClientException, connection.connect)
-
-        mock_getaddrinfo.assert_called_once_with(
-            connection.host, connection.port, 0, socket.SOCK_STREAM)
-
-    @mock.patch('socket.socket')
-    @mock.patch('socket.getaddrinfo',
-                return_value=[(2, 1, 6, '', ('127.0.0.1', 443))])
-    @mock.patch('tempest.common.glance_http.OpenSSLConnectionDelegator')
-    def test_connect_with_socket_failure(self, mock_delegator,
-                                         mock_getaddrinfo,
-                                         mock_socket):
-        mock_delegator.return_value.connect.side_effect = \
-            OSError('Connect failed')
-
-        connection = glance_http.VerifiedHTTPSConnection('127.0.0.1')
-        self.assertRaises(exceptions.RestClientException, connection.connect)
-
-        mock_getaddrinfo.assert_called_once_with(
-            connection.host, connection.port, 0, socket.SOCK_STREAM)
-        mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_STREAM)
-        mock_delegator.return_value.connect.\
-            assert_called_once_with((connection.host, 443))
-
-
-class TestResponseBodyIterator(base.TestCase):
-
-    def test_iter_default_chunk_size_64k(self):
-        resp = fake_http.fake_http_response({}, six.StringIO(
-            'X' * (glance_http.CHUNKSIZE + 1)))
-        iterator = glance_http.ResponseBodyIterator(resp)
-        chunks = list(iterator)
-        self.assertEqual(chunks, ['X' * glance_http.CHUNKSIZE, 'X'])