summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2019-08-20 20:01:53 +0000
committerGerrit Code Review <review@openstack.org>2019-08-20 20:01:53 +0000
commite3b07919415e97b92a892d434a950b0e32027717 (patch)
tree8bdc33c4591d166c03c5ece5c070aa994e10b795
parent0d30a28cf8f280eae5d3f44ed244585a1f97f486 (diff)
parent6fd8ee46e8f1f0a5a835c2250f9f46827efd5433 (diff)
downloadpython-ironicclient-e3b07919415e97b92a892d434a950b0e32027717.tar.gz
Merge "Remove deprecated common.http.HTTPClient class"
-rw-r--r--ironicclient/common/http.py295
-rw-r--r--ironicclient/tests/unit/common/test_http.py421
-rw-r--r--ironicclient/tests/unit/test_client.py15
-rw-r--r--releasenotes/notes/remove-deprecated-http-client-c969f583573251e9.yaml5
4 files changed, 32 insertions, 704 deletions
diff --git a/ironicclient/common/http.py b/ironicclient/common/http.py
index c9ecaa7..d03faf2 100644
--- a/ironicclient/common/http.py
+++ b/ironicclient/common/http.py
@@ -13,9 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import copy
from distutils.version import StrictVersion
-import hashlib
import logging
import os
import re
@@ -27,8 +25,6 @@ import time
from keystoneauth1 import adapter
from keystoneauth1 import exceptions as kexc
from oslo_serialization import jsonutils
-from oslo_utils import strutils
-import requests
import six
from six.moves import http_client
import six.moves.urllib.parse as urlparse
@@ -305,224 +301,6 @@ def with_retries(func):
return wrapper
-class HTTPClient(VersionNegotiationMixin):
-
- def __init__(self, endpoint, **kwargs):
- LOG.warning('HTTPClient class is deprecated and will be removed '
- 'in Stein release, please use SessionClient instead.')
- self.endpoint = endpoint
- self.endpoint_trimmed = _trim_endpoint_api_version(endpoint)
- self.auth_token = kwargs.get('token')
- self.auth_ref = kwargs.get('auth_ref')
- self.os_ironic_api_version = kwargs.get('os_ironic_api_version',
- DEFAULT_VER)
- self.api_version_select_state = kwargs.get(
- 'api_version_select_state', 'default')
- self.conflict_max_retries = kwargs.pop('max_retries',
- DEFAULT_MAX_RETRIES)
- self.conflict_retry_interval = kwargs.pop('retry_interval',
- DEFAULT_RETRY_INTERVAL)
- self.session = requests.Session()
-
- parts = urlparse.urlparse(endpoint)
- if parts.scheme not in SUPPORTED_ENDPOINT_SCHEME:
- msg = _('Unsupported scheme: %s') % parts.scheme
- raise exc.EndpointException(msg)
-
- if parts.scheme == 'https':
- if kwargs.get('insecure') is True:
- self.session.verify = False
- elif kwargs.get('ca_file'):
- self.session.verify = kwargs['ca_file']
- self.session.cert = (kwargs.get('cert_file'),
- kwargs.get('key_file'))
-
- def _process_header(self, name, value):
- """Redacts any sensitive header
-
- Redact a header that contains sensitive information, by returning an
- updated header with the sha1 hash of that value. The redacted value is
- prefixed by '{SHA1}' because that's the convention used within
- OpenStack.
-
- :returns: A tuple of (name, value)
- name: the safe encoding format of name
- value: the redacted value if name is x-auth-token,
- or the safe encoding format of name
-
- """
- if name in SENSITIVE_HEADERS:
- v = value.encode('utf-8')
- h = hashlib.sha1(v)
- d = h.hexdigest()
- return (name, "{SHA1}%s" % d)
- else:
- return (name, value)
-
- def log_curl_request(self, method, url, kwargs):
- curl = ['curl -i -X %s' % method]
-
- for (key, value) in kwargs['headers'].items():
- header = '-H \'%s: %s\'' % self._process_header(key, value)
- curl.append(header)
-
- if not self.session.verify:
- curl.append('-k')
- elif isinstance(self.session.verify, six.string_types):
- curl.append('--cacert %s' % self.session.verify)
-
- if self.session.cert:
- curl.append('--cert %s' % self.session.cert[0])
- curl.append('--key %s' % self.session.cert[1])
-
- if 'body' in kwargs:
- body = strutils.mask_password(kwargs['body'])
- curl.append('-d \'%s\'' % body)
-
- curl.append(self._make_connection_url(url))
- LOG.debug(' '.join(curl))
-
- @staticmethod
- def log_http_response(resp, body=None):
- # NOTE(aarefiev): resp.raw is urllib3 response object, it's used
- # only to get 'version', response from request with 'stream = True'
- # should be used for raw reading.
- status = (resp.raw.version / 10.0, resp.status_code, resp.reason)
- dump = ['\nHTTP/%.1f %s %s' % status]
- dump.extend(['%s: %s' % (k, v) for k, v in resp.headers.items()])
- dump.append('')
- if body:
- body = strutils.mask_password(body)
- dump.extend([body, ''])
- LOG.debug('\n'.join(dump))
-
- def _make_connection_url(self, url):
- # NOTE(pas-ha) we already stripped trailing / from endpoint_trimmed
- if not url.startswith('/'):
- url = '/' + url
- return self.endpoint_trimmed + url
-
- def _parse_version_headers(self, resp):
- return self._generic_parse_version_headers(resp.headers.get)
-
- def _make_simple_request(self, conn, method, url):
- return conn.request(method, self._make_connection_url(url))
-
- @with_retries
- def _http_request(self, url, method, **kwargs):
- """Send an http request with the specified characteristics.
-
- Wrapper around request.Session.request to handle tasks such
- as setting headers and error handling.
- """
- # NOTE(TheJulia): self.os_ironic_api_version is reset in
- # the self.negotiate_version() call if negotiation occurs.
- if self.os_ironic_api_version and self._must_negotiate_version():
- self.negotiate_version(self.session, None)
- # 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)
- if self.os_ironic_api_version:
- kwargs['headers'].setdefault('X-OpenStack-Ironic-API-Version',
- self.os_ironic_api_version)
- if self.auth_token:
- kwargs['headers'].setdefault('X-Auth-Token', self.auth_token)
-
- self.log_curl_request(method, url, kwargs)
-
- # NOTE(aarefiev): This is for backwards compatibility, request
- # expected body in 'data' field, previously we used httplib,
- # which expected 'body' field.
- body = kwargs.pop('body', None)
- if body:
- kwargs['data'] = body
-
- conn_url = self._make_connection_url(url)
- try:
- resp = self.session.request(method,
- conn_url,
- **kwargs)
-
- # TODO(deva): implement graceful client downgrade when connecting
- # to servers that did not support microversions. Details here:
- # https://specs.openstack.org/openstack/ironic-specs/specs/kilo-implemented/api-microversions.html#use-case-3b-new-client-communicating-with-a-old-ironic-user-specified # noqa
-
- if resp.status_code == http_client.NOT_ACCEPTABLE:
- negotiated_ver = self.negotiate_version(self.session, resp)
- kwargs['headers']['X-OpenStack-Ironic-API-Version'] = (
- negotiated_ver)
- return self._http_request(url, method, **kwargs)
-
- except requests.exceptions.RequestException as e:
- message = (_("Error has occurred while handling "
- "request for %(url)s: %(e)s") %
- dict(url=conn_url, e=e))
- # NOTE(aarefiev): not valid request(invalid url, missing schema,
- # and so on), retrying is not needed.
- if isinstance(e, ValueError):
- raise exc.ValidationError(message)
-
- raise exc.ConnectionRefused(message)
-
- body_str = None
- if resp.headers.get('Content-Type') == 'application/octet-stream':
- body_iter = resp.iter_content(chunk_size=CHUNKSIZE)
- self.log_http_response(resp)
- else:
- # Read body into string if it isn't obviously image data
- body_str = resp.text
- self.log_http_response(resp, body_str)
- body_iter = six.StringIO(body_str)
-
- if resp.status_code >= http_client.BAD_REQUEST:
- error_json = _extract_error_json(body_str)
- raise exc.from_response(
- resp, error_json.get('error_message'),
- error_json.get('debuginfo'), method, url)
- elif resp.status_code in (http_client.MOVED_PERMANENTLY,
- http_client.FOUND,
- http_client.USE_PROXY):
- # Redirected. Reissue the request to the new location.
- return self._http_request(resp['location'], method, **kwargs)
- elif resp.status_code == http_client.MULTIPLE_CHOICES:
- raise exc.from_response(resp, method=method, url=url)
-
- return resp, body_iter
-
- def json_request(self, method, url, **kwargs):
- kwargs.setdefault('headers', {})
- kwargs['headers'].setdefault('Content-Type', 'application/json')
- kwargs['headers'].setdefault('Accept', 'application/json')
-
- if 'body' in kwargs:
- kwargs['body'] = jsonutils.dump_as_bytes(kwargs['body'])
-
- resp, body_iter = self._http_request(url, method, **kwargs)
- content_type = resp.headers.get('Content-Type')
-
- if (resp.status_code in (http_client.NO_CONTENT,
- http_client.RESET_CONTENT)
- or content_type is None):
- return resp, list()
-
- if 'application/json' in content_type:
- body = ''.join([chunk for chunk in body_iter])
- try:
- body = jsonutils.loads(body)
- except ValueError:
- LOG.error('Could not decode response body as JSON')
- else:
- body = None
-
- return resp, body
-
- def raw_request(self, method, url, **kwargs):
- kwargs.setdefault('headers', {})
- kwargs['headers'].setdefault('Content-Type',
- 'application/octet-stream')
- return self._http_request(url, method, **kwargs)
-
-
class VerifiedHTTPSConnection(six.moves.http_client.HTTPSConnection):
"""httplib-compatible connection using client-side SSL authentication
@@ -722,49 +500,30 @@ def _construct_http_client(session=None,
key_file=None,
insecure=None,
**kwargs):
- if session:
- kwargs.setdefault('service_type', 'baremetal')
- kwargs.setdefault('user_agent', 'python-ironicclient')
- kwargs.setdefault('interface', kwargs.pop('endpoint_type',
- 'publicURL'))
-
- ignored = {'token': token,
- 'auth_ref': auth_ref,
- 'timeout': timeout != 600,
- 'ca_file': ca_file,
- 'cert_file': cert_file,
- 'key_file': key_file,
- 'insecure': insecure}
-
- dvars = [k for k, v in ignored.items() if v]
-
- if dvars:
- LOG.warning('The following arguments are ignored when using '
- 'the session to construct a client: %s',
- ', '.join(dvars))
-
- return SessionClient(session=session,
- os_ironic_api_version=os_ironic_api_version,
- api_version_select_state=api_version_select_state,
- max_retries=max_retries,
- retry_interval=retry_interval,
- **kwargs)
- else:
- endpoint = None
- if kwargs:
- endpoint = kwargs.pop('endpoint_override', None)
- LOG.warning('The following arguments are being ignored when '
- 'constructing the client: %s', ', '.join(kwargs))
-
- return HTTPClient(endpoint=endpoint,
- token=token,
- auth_ref=auth_ref,
- os_ironic_api_version=os_ironic_api_version,
- api_version_select_state=api_version_select_state,
- max_retries=max_retries,
- retry_interval=retry_interval,
- timeout=timeout,
- ca_file=ca_file,
- cert_file=cert_file,
- key_file=key_file,
- insecure=insecure)
+
+ kwargs.setdefault('service_type', 'baremetal')
+ kwargs.setdefault('user_agent', 'python-ironicclient')
+ kwargs.setdefault('interface', kwargs.pop('endpoint_type',
+ 'publicURL'))
+
+ ignored = {'token': token,
+ 'auth_ref': auth_ref,
+ 'timeout': timeout != 600,
+ 'ca_file': ca_file,
+ 'cert_file': cert_file,
+ 'key_file': key_file,
+ 'insecure': insecure}
+
+ dvars = [k for k, v in ignored.items() if v]
+
+ if dvars:
+ LOG.warning('The following arguments are ignored when using '
+ 'the session to construct a client: %s',
+ ', '.join(dvars))
+
+ return SessionClient(session=session,
+ os_ironic_api_version=os_ironic_api_version,
+ api_version_select_state=api_version_select_state,
+ max_retries=max_retries,
+ retry_interval=retry_interval,
+ **kwargs)
diff --git a/ironicclient/tests/unit/common/test_http.py b/ironicclient/tests/unit/common/test_http.py
index 7828bfc..f775632 100644
--- a/ironicclient/tests/unit/common/test_http.py
+++ b/ironicclient/tests/unit/common/test_http.py
@@ -17,7 +17,6 @@ import time
import mock
from oslo_serialization import jsonutils
-import requests
import six
from six.moves import http_client
@@ -348,296 +347,6 @@ class VersionNegotiationMixinTest(utils.BaseTestCase):
self.assertEqual((host, port), http.get_server(endpoint))
-class HttpClientTest(utils.BaseTestCase):
-
- @mock.patch.object(http.LOG, 'warning', autospec=True)
- def test_http_client_deprecation(self, log_mock):
- http.HTTPClient('http://localhost')
- self.assertIn('deprecated', log_mock.call_args[0][0])
-
- def test_url_generation_trailing_slash_in_base(self):
- client = http.HTTPClient('http://localhost/')
- url = client._make_connection_url('/v1/resources')
- self.assertEqual('http://localhost/v1/resources', url)
-
- def test_url_generation_without_trailing_slash_in_base(self):
- client = http.HTTPClient('http://localhost')
- url = client._make_connection_url('/v1/resources')
- self.assertEqual('http://localhost/v1/resources', url)
-
- def test_url_generation_without_prefix_slash_in_path(self):
- client = http.HTTPClient('http://localhost')
- url = client._make_connection_url('v1/resources')
- self.assertEqual('http://localhost/v1/resources', url)
-
- def test_server_https_request_with_application_octet_stream(self):
- client = http.HTTPClient('https://localhost/')
- client.session = utils.mockSession(
- {'Content-Type': 'application/octet-stream'},
- "Body",
- version=1,
- status_code=http_client.OK)
-
- response, body = client.json_request('GET', '/v1/resources')
- self.assertEqual(client.session.request.return_value, response)
- self.assertIsNone(body)
-
- def test_server_exception_empty_body(self):
- error_body = _get_error_body()
- client = http.HTTPClient('http://localhost/')
- client.session = utils.mockSession(
- {'Content-Type': 'application/json'},
- error_body,
- version=1,
- status_code=http_client.INTERNAL_SERVER_ERROR)
-
- self.assertRaises(exc.InternalServerError,
- client.json_request,
- 'GET', '/v1/resources')
-
- def test_server_exception_msg_only(self):
- error_msg = 'test error msg'
- error_body = _get_error_body(error_msg)
- client = http.HTTPClient('http://localhost/')
- client.session = utils.mockSession(
- {'Content-Type': 'application/json'},
- error_body,
- version=1,
- status_code=http_client.INTERNAL_SERVER_ERROR)
-
- self.assertRaises(exc.InternalServerError,
- client.json_request,
- 'GET', '/v1/resources')
-
- def test_server_exception_description_only(self):
- error_msg = 'test error msg'
- error_body = _get_error_body(description=error_msg)
- client = http.HTTPClient('http://localhost/')
- client.session = utils.mockSession(
- {'Content-Type': 'application/json'},
- error_body,
- version=1,
- status_code=http_client.BAD_REQUEST)
-
- self.assertRaisesRegex(exc.BadRequest, 'test error msg',
- client.json_request,
- 'GET', '/v1/resources')
-
- def test_server_https_request_ok(self):
- client = http.HTTPClient('https://localhost/')
- client.session = utils.mockSession(
- {'Content-Type': 'application/json'},
- "Body",
- version=1,
- status_code=http_client.OK)
-
- client.json_request('GET', '/v1/resources')
-
- def test_server_https_empty_body(self):
- error_body = _get_error_body()
-
- client = http.HTTPClient('https://localhost/')
- client.session = utils.mockSession(
- {'Content-Type': 'application/json'},
- error_body,
- version=1,
- status_code=http_client.INTERNAL_SERVER_ERROR)
-
- self.assertRaises(exc.InternalServerError,
- client.json_request,
- 'GET', '/v1/resources')
-
- def test_401_unauthorized_exception(self):
- error_body = _get_error_body()
- client = http.HTTPClient('http://localhost/')
- client.session = utils.mockSession(
- {'Content-Type': 'text/plain'},
- error_body,
- version=1,
- status_code=http_client.UNAUTHORIZED)
-
- self.assertRaises(exc.Unauthorized, client.json_request,
- 'GET', '/v1/resources')
-
- def test_http_request_not_valid_request(self):
- client = http.HTTPClient('http://localhost/')
- client.session.request = mock.Mock(
- side_effect=http.requests.exceptions.InvalidSchema)
-
- self.assertRaises(exc.ValidationError, client._http_request,
- 'http://localhost/', 'GET')
-
- def test__parse_version_headers(self):
- # Test parsing of version headers from HTTPClient
- error_body = _get_error_body()
- expected_result = ('1.1', '1.6')
-
- client = http.HTTPClient('http://localhost/')
- fake_resp = utils.mockSessionResponse(
- {'X-OpenStack-Ironic-API-Minimum-Version': '1.1',
- 'X-OpenStack-Ironic-API-Maximum-Version': '1.6',
- 'Content-Type': 'text/plain',
- },
- error_body,
- version=1,
- status_code=http_client.NOT_ACCEPTABLE)
- result = client._parse_version_headers(fake_resp)
- self.assertEqual(expected_result, result)
-
- @mock.patch.object(filecache, 'save_data', autospec=True)
- def test__http_request_client_fallback_fail(self, mock_save_data):
- # Test when fallback to a supported version fails
- host, port, latest_ver = 'localhost', '1234', '1.6'
- error_body = _get_error_body()
-
- client = http.HTTPClient('http://%s:%s/' % (host, port))
- client.session = utils.mockSession(
- {'X-OpenStack-Ironic-API-Minimum-Version': '1.1',
- 'X-OpenStack-Ironic-API-Maximum-Version': latest_ver,
- 'content-type': 'text/plain',
- },
- error_body,
- version=1,
- status_code=http_client.NOT_ACCEPTABLE)
- self.assertRaises(
- exc.UnsupportedVersion,
- client._http_request,
- '/v1/resources',
- 'GET')
- mock_save_data.assert_called_once_with(host=host, data=latest_ver,
- port=port)
-
- @mock.patch.object(http.VersionNegotiationMixin, 'negotiate_version',
- autospec=False)
- def test__http_request_client_fallback_success(self, mock_negotiate):
- # Test when fallback to a supported version succeeds
- mock_negotiate.return_value = '1.6'
- error_body = _get_error_body()
- bad_resp = utils.mockSessionResponse(
- {'X-OpenStack-Ironic-API-Minimum-Version': '1.1',
- 'X-OpenStack-Ironic-API-Maximum-Version': '1.6',
- 'content-type': 'text/plain',
- },
- error_body,
- version=1,
- status_code=http_client.NOT_ACCEPTABLE)
- good_resp = utils.mockSessionResponse(
- {'X-OpenStack-Ironic-API-Minimum-Version': '1.1',
- 'X-OpenStack-Ironic-API-Maximum-Version': '1.6',
- 'content-type': 'text/plain',
- },
- "We got some text",
- version=1,
- status_code=http_client.OK)
- client = http.HTTPClient('http://localhost/')
-
- with mock.patch.object(client, 'session',
- autospec=True) as mock_session:
-
- mock_session.request.side_effect = iter([bad_resp, good_resp])
- response, body_iter = client._http_request('/v1/resources', 'GET')
-
- self.assertEqual(http_client.OK, response.status_code)
- self.assertEqual(1, mock_negotiate.call_count)
-
- @mock.patch.object(requests.Session, 'request', autospec=True)
- @mock.patch.object(http.VersionNegotiationMixin, 'negotiate_version',
- autospec=False)
- def test__http_request_explicit_version(self, mock_negotiate,
- mock_session):
- headers = {'User-Agent': 'python-ironicclient',
- 'X-OpenStack-Ironic-API-Version': '1.28'}
- kwargs = {'os_ironic_api_version': '1.30',
- 'api_version_select_state': 'negotiated'}
- mock_session.return_value = utils.mockSessionResponse(
- {}, status_code=http_client.NO_CONTENT, version=1)
- client = http.HTTPClient('http://localhost/', **kwargs)
- response, body_iter = client._http_request('/v1/resources', 'GET',
- headers=headers)
- mock_session.assert_called_once_with(mock.ANY, 'GET',
- 'http://localhost/v1/resources',
- headers=headers)
-
- @mock.patch.object(http.LOG, 'debug', autospec=True)
- def test_log_curl_request_mask_password(self, mock_log):
- client = http.HTTPClient('http://localhost/')
- kwargs = {'headers': {'foo-header': 'bar-header'},
- 'body': '{"password": "foo"}'}
- client.log_curl_request('foo', '/v1/nodes', kwargs)
- expected_log = ("curl -i -X foo -H 'foo-header: bar-header' "
- "-d '{\"password\": \"***\"}' "
- "http://localhost/v1/nodes")
- mock_log.assert_called_once_with(expected_log)
-
- @mock.patch.object(http.LOG, 'debug', autospec=True)
- def test_log_http_response_mask_password(self, mock_log):
- client = http.HTTPClient('http://localhost/')
- fake_response = utils.FakeResponse({}, version=1, reason='foo',
- status=200)
- body = '{"password": "foo"}'
- client.log_http_response(fake_response, body=body)
- expected_log = ("\nHTTP/0.1 200 foo\n\n{\"password\": \"***\"}\n")
- mock_log.assert_called_once_with(expected_log)
-
- def test__https_init_ssl_args_insecure(self):
- client = http.HTTPClient('https://localhost/', insecure=True)
-
- self.assertEqual(False, client.session.verify)
-
- def test__https_init_ssl_args_secure(self):
- client = http.HTTPClient('https://localhost/', ca_file='test_ca',
- key_file='test_key', cert_file='test_cert')
-
- self.assertEqual('test_ca', client.session.verify)
- self.assertEqual(('test_cert', 'test_key'), client.session.cert)
-
- @mock.patch.object(http.LOG, 'debug', autospec=True)
- def test_log_curl_request_with_body_and_header(self, mock_log):
- client = http.HTTPClient('http://test')
- headers = {'header1': 'value1'}
- body = 'example body'
-
- client.log_curl_request('GET', '/v1/nodes',
- {'headers': headers, 'body': body})
-
- self.assertTrue(mock_log.called)
- self.assertTrue(mock_log.call_args[0])
- self.assertEqual("curl -i -X GET -H 'header1: value1'"
- " -d 'example body' http://test/v1/nodes",
- mock_log.call_args[0][0])
-
- @mock.patch.object(http.LOG, 'debug', autospec=True)
- def test_log_curl_request_with_certs(self, mock_log):
- headers = {'header1': 'value1'}
- client = http.HTTPClient('https://test', key_file='key',
- cert_file='cert', cacert='cacert',
- token='fake-token')
-
- client.log_curl_request('GET', '/v1/test', {'headers': headers})
-
- self.assertTrue(mock_log.called)
- self.assertTrue(mock_log.call_args[0])
-
- self.assertEqual("curl -i -X GET -H 'header1: value1' "
- "--cert cert --key key https://test/v1/test",
- mock_log.call_args[0][0])
-
- @mock.patch.object(http.LOG, 'debug', autospec=True)
- def test_log_curl_request_with_insecure_param(self, mock_log):
- headers = {'header1': 'value1'}
- http_client_object = http.HTTPClient('https://test', insecure=True,
- token='fake-token')
-
- http_client_object.log_curl_request('GET', '/v1/test',
- {'headers': headers})
-
- self.assertTrue(mock_log.called)
- self.assertTrue(mock_log.call_args[0])
- self.assertEqual("curl -i -X GET -H 'header1: value1' -k "
- "--cert None --key None https://test/v1/test",
- mock_log.call_args[0][0])
-
-
class SessionClientTest(utils.BaseTestCase):
@mock.patch.object(http.LOG, 'warning', autospec=True)
@@ -750,136 +459,6 @@ class SessionClientTest(utils.BaseTestCase):
@mock.patch.object(time, 'sleep', lambda *_: None)
class RetriesTestCase(utils.BaseTestCase):
- def test_http_no_retry(self):
- error_body = _get_error_body()
- bad_resp = utils.mockSessionResponse(
- {'Content-Type': 'text/plain'},
- error_body,
- version=1,
- status_code=http_client.CONFLICT)
- client = http.HTTPClient('http://localhost/', max_retries=0)
-
- with mock.patch.object(client.session, 'request', autospec=True,
- return_value=bad_resp) as mock_request:
-
- self.assertRaises(exc.Conflict, client._http_request,
- '/v1/resources', 'GET')
- self.assertEqual(1, mock_request.call_count)
-
- def test_http_retry(self):
- error_body = _get_error_body()
- bad_resp = utils.mockSessionResponse(
- {'Content-Type': 'text/plain'},
- error_body,
- version=1,
- status_code=http_client.CONFLICT)
- good_resp = utils.mockSessionResponse(
- {'Content-Type': 'text/plain'},
- "meow",
- version=1,
- status_code=http_client.OK)
- client = http.HTTPClient('http://localhost/')
-
- with mock.patch.object(client, 'session',
- autospec=True) as mock_session:
-
- mock_session.request.side_effect = iter([bad_resp, good_resp])
- response, body_iter = client._http_request('/v1/resources', 'GET')
-
- self.assertEqual(http_client.OK, response.status_code)
- self.assertEqual(2, mock_session.request.call_count)
-
- def test_http_retry_503(self):
- error_body = _get_error_body()
- bad_resp = utils.mockSessionResponse(
- {'Content-Type': 'text/plain'},
- error_body,
- version=1,
- status_code=http_client.SERVICE_UNAVAILABLE)
- good_resp = utils.mockSessionResponse(
- {'Content-Type': 'text/plain'},
- "meow",
- version=1,
- status_code=http_client.OK)
- client = http.HTTPClient('http://localhost/')
-
- with mock.patch.object(client, 'session',
- autospec=True) as mock_session:
- mock_session.request.side_effect = iter([bad_resp, good_resp])
- response, body_iter = client._http_request('/v1/resources', 'GET')
-
- self.assertEqual(http_client.OK, response.status_code)
- self.assertEqual(2, mock_session.request.call_count)
-
- def test_http_retry_connection_refused(self):
- good_resp = utils.mockSessionResponse(
- {'content-type': 'text/plain'},
- "meow",
- version=1,
- status_code=http_client.OK)
- client = http.HTTPClient('http://localhost/')
-
- with mock.patch.object(client, 'session',
- autospec=True) as mock_session:
- mock_session.request.side_effect = iter([exc.ConnectionRefused(),
- good_resp])
- response, body_iter = client._http_request('/v1/resources', 'GET')
-
- self.assertEqual(http_client.OK, response.status_code)
- self.assertEqual(2, mock_session.request.call_count)
-
- def test_http_failed_retry(self):
- error_body = _get_error_body()
- bad_resp = utils.mockSessionResponse(
- {'content-type': 'text/plain'},
- error_body,
- version=1,
- status_code=http_client.CONFLICT)
- client = http.HTTPClient('http://localhost/')
-
- with mock.patch.object(client, 'session',
- autospec=True) as mock_session:
- mock_session.request.return_value = bad_resp
- self.assertRaises(exc.Conflict, client._http_request,
- '/v1/resources', 'GET')
- self.assertEqual(http.DEFAULT_MAX_RETRIES + 1,
- mock_session.request.call_count)
-
- def test_http_max_retries_none(self):
- error_body = _get_error_body()
- bad_resp = utils.mockSessionResponse(
- {'content-type': 'text/plain'},
- error_body,
- version=1,
- status_code=http_client.CONFLICT)
- client = http.HTTPClient('http://localhost/', max_retries=None)
-
- with mock.patch.object(client, 'session',
- autospec=True) as mock_session:
- mock_session.request.return_value = bad_resp
- self.assertRaises(exc.Conflict, client._http_request,
- '/v1/resources', 'GET')
- self.assertEqual(http.DEFAULT_MAX_RETRIES + 1,
- mock_session.request.call_count)
-
- def test_http_change_max_retries(self):
- error_body = _get_error_body()
- bad_resp = utils.mockSessionResponse(
- {'content-type': 'text/plain'},
- error_body,
- version=1,
- status_code=http_client.CONFLICT)
- client = http.HTTPClient('http://localhost/',
- max_retries=http.DEFAULT_MAX_RETRIES + 1)
-
- with mock.patch.object(client, 'session',
- autospec=True) as mock_session:
- mock_session.request.return_value = bad_resp
- self.assertRaises(exc.Conflict, client._http_request,
- '/v1/resources', 'GET')
- self.assertEqual(http.DEFAULT_MAX_RETRIES + 2,
- mock_session.request.call_count)
-
def test_session_retry(self):
error_body = _get_error_body()
diff --git a/ironicclient/tests/unit/test_client.py b/ironicclient/tests/unit/test_client.py
index ff10f19..d9c77f9 100644
--- a/ironicclient/tests/unit/test_client.py
+++ b/ironicclient/tests/unit/test_client.py
@@ -490,18 +490,3 @@ class ClientTest(utils.BaseTestCase):
'interface': None}
)
self.assertFalse(mock_ks_session.called)
-
- def test_safe_header_with_auth_token(self):
- (name, value) = ('X-Auth-Token', u'3b640e2e64d946ac8f55615aff221dc1')
- expected_header = (u'X-Auth-Token',
- '{SHA1}6de9fb3b0b89099030a54abfeb468e7b1b1f0f2b')
- client = http.HTTPClient('http://localhost/')
- header_redact = client._process_header(name, value)
- self.assertEqual(expected_header, header_redact)
-
- def test_safe_header_with_no_auth_token(self):
- name, value = ('Accept', 'application/json')
- header = ('Accept', 'application/json')
- client = http.HTTPClient('http://localhost/')
- header_redact = client._process_header(name, value)
- self.assertEqual(header, header_redact)
diff --git a/releasenotes/notes/remove-deprecated-http-client-c969f583573251e9.yaml b/releasenotes/notes/remove-deprecated-http-client-c969f583573251e9.yaml
new file mode 100644
index 0000000..3b768a7
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-http-client-c969f583573251e9.yaml
@@ -0,0 +1,5 @@
+---
+upgrade:
+ - |
+ Removes deprecated ``common.http.HTTPClient`` class.
+ The ``common.http.SessionClient`` class should be used instead.