Increase UT Coverage
UT Coverage for magnumclient/common/httpclient.py is increased from 56% to 81%. Overall coverage is now 79% Change-Id: I28d0f3406ed9940cf0dee9d2fa5d238152017151 Partially-Implements: blueprint magnumclient-ut-coverage
This commit is contained in:
@@ -51,7 +51,6 @@ def _extract_error_json(body):
|
|||||||
'debuginfo': error_body['message']}
|
'debuginfo': error_body['message']}
|
||||||
else:
|
else:
|
||||||
error_body = body_json['errors'][0]
|
error_body = body_json['errors'][0]
|
||||||
raw_msg = error_body['title']
|
|
||||||
error_json = {'faultstring': error_body['title']}
|
error_json = {'faultstring': error_body['title']}
|
||||||
if 'detail' in error_body:
|
if 'detail' in error_body:
|
||||||
error_json['debuginfo'] = error_body['detail']
|
error_json['debuginfo'] = error_body['detail']
|
||||||
@@ -101,11 +100,8 @@ class HTTPClient(object):
|
|||||||
|
|
||||||
def get_connection(self):
|
def get_connection(self):
|
||||||
_class = self.connection_params[0]
|
_class = self.connection_params[0]
|
||||||
try:
|
|
||||||
return _class(*self.connection_params[1][0:2],
|
return _class(*self.connection_params[1][0:2],
|
||||||
**self.connection_params[2])
|
**self.connection_params[2])
|
||||||
except six.moves.http_client.InvalidURL:
|
|
||||||
raise exceptions.EndpointException()
|
|
||||||
|
|
||||||
def log_curl_request(self, method, url, kwargs):
|
def log_curl_request(self, method, url, kwargs):
|
||||||
curl = ['curl -i -X %s' % method]
|
curl = ['curl -i -X %s' % method]
|
||||||
|
|||||||
@@ -17,20 +17,36 @@ import json
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
import six
|
import six
|
||||||
|
import socket
|
||||||
|
|
||||||
from magnumclient.common.apiclient.exceptions import GatewayTimeout
|
from magnumclient.common.apiclient.exceptions import GatewayTimeout
|
||||||
|
from magnumclient.common.apiclient.exceptions import MultipleChoices
|
||||||
from magnumclient.common import httpclient as http
|
from magnumclient.common import httpclient as http
|
||||||
from magnumclient import exceptions as exc
|
from magnumclient import exceptions as exc
|
||||||
from magnumclient.tests import utils
|
from magnumclient.tests import utils
|
||||||
|
|
||||||
|
NORMAL_ERROR = 0
|
||||||
|
ERROR_DICT = 1
|
||||||
|
ERROR_LIST_WITH_DETAIL = 2
|
||||||
|
ERROR_LIST_WITH_DESC = 3
|
||||||
|
|
||||||
def _get_error_body(faultstring=None, debuginfo=None):
|
|
||||||
|
def _get_error_body(faultstring=None, debuginfo=None, err_type=NORMAL_ERROR):
|
||||||
|
if err_type == NORMAL_ERROR:
|
||||||
error_body = {
|
error_body = {
|
||||||
'faultstring': faultstring,
|
'faultstring': faultstring,
|
||||||
'debuginfo': debuginfo
|
'debuginfo': debuginfo
|
||||||
}
|
}
|
||||||
raw_error_body = json.dumps(error_body)
|
raw_error_body = json.dumps(error_body)
|
||||||
body = {'error_message': raw_error_body}
|
body = {'error_message': raw_error_body}
|
||||||
|
elif err_type == ERROR_DICT:
|
||||||
|
body = {'error': {'title': faultstring, 'message': debuginfo}}
|
||||||
|
elif err_type == ERROR_LIST_WITH_DETAIL:
|
||||||
|
main_body = {'title': faultstring, 'detail': debuginfo}
|
||||||
|
body = {'errors': [main_body]}
|
||||||
|
elif err_type == ERROR_LIST_WITH_DESC:
|
||||||
|
main_body = {'title': faultstring, 'description': debuginfo}
|
||||||
|
body = {'errors': [main_body]}
|
||||||
raw_body = json.dumps(body)
|
raw_body = json.dumps(body)
|
||||||
return raw_body
|
return raw_body
|
||||||
|
|
||||||
@@ -79,7 +95,7 @@ class HttpClientTest(utils.BaseTestCase):
|
|||||||
|
|
||||||
def test_server_exception_msg_only(self):
|
def test_server_exception_msg_only(self):
|
||||||
error_msg = 'test error msg'
|
error_msg = 'test error msg'
|
||||||
error_body = _get_error_body(error_msg)
|
error_body = _get_error_body(error_msg, err_type=ERROR_DICT)
|
||||||
fake_resp = utils.FakeResponse({'content-type': 'application/json'},
|
fake_resp = utils.FakeResponse({'content-type': 'application/json'},
|
||||||
six.StringIO(error_body),
|
six.StringIO(error_body),
|
||||||
version=1,
|
version=1,
|
||||||
@@ -97,7 +113,8 @@ class HttpClientTest(utils.BaseTestCase):
|
|||||||
error_msg = 'another test error'
|
error_msg = 'another test error'
|
||||||
error_trace = ("\"Traceback (most recent call last):\\n\\n "
|
error_trace = ("\"Traceback (most recent call last):\\n\\n "
|
||||||
"File \\\"/usr/local/lib/python2.7/...")
|
"File \\\"/usr/local/lib/python2.7/...")
|
||||||
error_body = _get_error_body(error_msg, error_trace)
|
error_body = _get_error_body(error_msg, error_trace,
|
||||||
|
ERROR_LIST_WITH_DESC)
|
||||||
fake_resp = utils.FakeResponse({'content-type': 'application/json'},
|
fake_resp = utils.FakeResponse({'content-type': 'application/json'},
|
||||||
six.StringIO(error_body),
|
six.StringIO(error_body),
|
||||||
version=1,
|
version=1,
|
||||||
@@ -116,15 +133,41 @@ class HttpClientTest(utils.BaseTestCase):
|
|||||||
"%(error)s\n%(details)s" % {'error': str(error),
|
"%(error)s\n%(details)s" % {'error': str(error),
|
||||||
'details': str(error.details)})
|
'details': str(error.details)})
|
||||||
|
|
||||||
def test_get_connection_params(self):
|
def test_server_exception_address(self):
|
||||||
endpoint = 'http://magnum-host:6385'
|
endpoint = 'https://magnum-host:6385'
|
||||||
expected = (HTTP_CLASS,
|
client = http.HTTPClient(endpoint, token='foobar', insecure=True,
|
||||||
('magnum-host', 6385, ''),
|
ca_file='/path/to/ca_file')
|
||||||
{'timeout': DEFAULT_TIMEOUT})
|
client.get_connection = (
|
||||||
params = http.HTTPClient.get_connection_params(endpoint)
|
lambda *a, **kw: utils.FakeConnection(exc=socket.gaierror))
|
||||||
self.assertEqual(expected, params)
|
|
||||||
|
|
||||||
def test_get_connection_params_with_trailing_slash(self):
|
self.assertRaises(exc.EndpointNotFound, client.json_request,
|
||||||
|
'GET', '/v1/resources', body='farboo')
|
||||||
|
|
||||||
|
def test_server_exception_socket(self):
|
||||||
|
client = http.HTTPClient('http://localhost/', token='foobar')
|
||||||
|
client.get_connection = (
|
||||||
|
lambda *a, **kw: utils.FakeConnection(exc=socket.error))
|
||||||
|
|
||||||
|
self.assertRaises(exc.ConnectionRefused, client.json_request,
|
||||||
|
'GET', '/v1/resources')
|
||||||
|
|
||||||
|
def test_server_exception_endpoint(self):
|
||||||
|
endpoint = 'https://magnum-host:6385'
|
||||||
|
client = http.HTTPClient(endpoint, token='foobar', insecure=True,
|
||||||
|
ca_file='/path/to/ca_file')
|
||||||
|
client.get_connection = (
|
||||||
|
lambda *a, **kw: utils.FakeConnection(exc=socket.gaierror))
|
||||||
|
|
||||||
|
self.assertRaises(exc.EndpointNotFound, client.json_request,
|
||||||
|
'GET', '/v1/resources', body='farboo')
|
||||||
|
|
||||||
|
def test_get_connection(self):
|
||||||
|
endpoint = 'https://magnum-host:6385'
|
||||||
|
client = http.HTTPClient(endpoint)
|
||||||
|
conn = client.get_connection()
|
||||||
|
self.assertTrue(conn, http.VerifiedHTTPSConnection)
|
||||||
|
|
||||||
|
def test_get_connection_exception(self):
|
||||||
endpoint = 'http://magnum-host:6385/'
|
endpoint = 'http://magnum-host:6385/'
|
||||||
expected = (HTTP_CLASS,
|
expected = (HTTP_CLASS,
|
||||||
('magnum-host', 6385, ''),
|
('magnum-host', 6385, ''),
|
||||||
@@ -219,8 +262,13 @@ class HttpClientTest(utils.BaseTestCase):
|
|||||||
params = http.HTTPClient.get_connection_params(endpoint)
|
params = http.HTTPClient.get_connection_params(endpoint)
|
||||||
self.assertEqual(expected, params)
|
self.assertEqual(expected, params)
|
||||||
|
|
||||||
|
def test_get_connection_params_with_unsupported_scheme(self):
|
||||||
|
endpoint = 'foo://magnum-host:6385/magnum/v1/'
|
||||||
|
self.assertRaises(exc.EndpointException,
|
||||||
|
http.HTTPClient.get_connection_params, endpoint)
|
||||||
|
|
||||||
def test_401_unauthorized_exception(self):
|
def test_401_unauthorized_exception(self):
|
||||||
error_body = _get_error_body()
|
error_body = _get_error_body(err_type=ERROR_LIST_WITH_DETAIL)
|
||||||
fake_resp = utils.FakeResponse({'content-type': 'text/plain'},
|
fake_resp = utils.FakeResponse({'content-type': 'text/plain'},
|
||||||
six.StringIO(error_body),
|
six.StringIO(error_body),
|
||||||
version=1,
|
version=1,
|
||||||
@@ -232,6 +280,75 @@ class HttpClientTest(utils.BaseTestCase):
|
|||||||
self.assertRaises(exc.Unauthorized, client.json_request,
|
self.assertRaises(exc.Unauthorized, client.json_request,
|
||||||
'GET', '/v1/resources')
|
'GET', '/v1/resources')
|
||||||
|
|
||||||
|
def test_server_redirect_exception(self):
|
||||||
|
fake_redirect_resp = utils.FakeResponse(
|
||||||
|
{'content-type': 'application/octet-stream'},
|
||||||
|
'foo', version=1, status=301)
|
||||||
|
fake_resp = utils.FakeResponse(
|
||||||
|
{'content-type': 'application/octet-stream'},
|
||||||
|
'bar', version=1, status=300)
|
||||||
|
client = http.HTTPClient('http://localhost/')
|
||||||
|
conn = utils.FakeConnection(fake_redirect_resp,
|
||||||
|
redirect_resp=fake_resp)
|
||||||
|
client.get_connection = (lambda *a, **kw: conn)
|
||||||
|
|
||||||
|
self.assertRaises(MultipleChoices, client.json_request,
|
||||||
|
'GET', '/v1/resources')
|
||||||
|
|
||||||
|
def test_server_body_undecode_json(self):
|
||||||
|
err = "foo"
|
||||||
|
fake_resp = utils.FakeResponse(
|
||||||
|
{'content-type': 'application/json'},
|
||||||
|
six.StringIO(err), version=1, status=200)
|
||||||
|
client = http.HTTPClient('http://localhost/')
|
||||||
|
conn = utils.FakeConnection(fake_resp)
|
||||||
|
client.get_connection = (lambda *a, **kw: conn)
|
||||||
|
|
||||||
|
resp, body = client.json_request('GET', '/v1/resources')
|
||||||
|
|
||||||
|
self.assertEqual(resp, fake_resp)
|
||||||
|
self.assertEqual(err, body)
|
||||||
|
|
||||||
|
def test_server_success_body_app(self):
|
||||||
|
fake_resp = utils.FakeResponse(
|
||||||
|
{'content-type': 'application/octet-stream'},
|
||||||
|
'bar', version=1, status=200)
|
||||||
|
client = http.HTTPClient('http://localhost/')
|
||||||
|
conn = utils.FakeConnection(fake_resp)
|
||||||
|
client.get_connection = (lambda *a, **kw: conn)
|
||||||
|
|
||||||
|
resp, body = client.json_request('GET', '/v1/resources')
|
||||||
|
|
||||||
|
self.assertEqual(resp, fake_resp)
|
||||||
|
self.assertIsNone(body)
|
||||||
|
|
||||||
|
def test_server_success_body_none(self):
|
||||||
|
fake_resp = utils.FakeResponse(
|
||||||
|
{'content-type': None},
|
||||||
|
six.StringIO('bar'), version=1, status=200)
|
||||||
|
client = http.HTTPClient('http://localhost/')
|
||||||
|
conn = utils.FakeConnection(fake_resp)
|
||||||
|
client.get_connection = (lambda *a, **kw: conn)
|
||||||
|
|
||||||
|
resp, body = client.json_request('GET', '/v1/resources')
|
||||||
|
|
||||||
|
self.assertEqual(resp, fake_resp)
|
||||||
|
self.assertTrue(isinstance(body, list))
|
||||||
|
|
||||||
|
def test_server_success_body_json(self):
|
||||||
|
err = _get_error_body()
|
||||||
|
fake_resp = utils.FakeResponse(
|
||||||
|
{'content-type': 'application/json'},
|
||||||
|
six.StringIO(err), version=1, status=200)
|
||||||
|
client = http.HTTPClient('http://localhost/')
|
||||||
|
conn = utils.FakeConnection(fake_resp)
|
||||||
|
client.get_connection = (lambda *a, **kw: conn)
|
||||||
|
|
||||||
|
resp, body = client.json_request('GET', '/v1/resources')
|
||||||
|
|
||||||
|
self.assertEqual(resp, fake_resp)
|
||||||
|
self.assertEqual(json.dumps(body), err)
|
||||||
|
|
||||||
|
|
||||||
class SessionClientTest(utils.BaseTestCase):
|
class SessionClientTest(utils.BaseTestCase):
|
||||||
|
|
||||||
|
|||||||
@@ -59,18 +59,24 @@ class FakeAPI(object):
|
|||||||
|
|
||||||
|
|
||||||
class FakeConnection(object):
|
class FakeConnection(object):
|
||||||
def __init__(self, response=None):
|
def __init__(self, response=None, **kwargs):
|
||||||
self._response = response
|
self._response = six.moves.queue.Queue()
|
||||||
|
self._response.put(response)
|
||||||
self._last_request = None
|
self._last_request = None
|
||||||
|
self._exc = kwargs['exc'] if 'exc' in kwargs else None
|
||||||
|
if 'redirect_resp' in kwargs:
|
||||||
|
self._response.put(kwargs['redirect_resp'])
|
||||||
|
|
||||||
def request(self, method, conn_url, **kwargs):
|
def request(self, method, conn_url, **kwargs):
|
||||||
self._last_request = (method, conn_url, kwargs)
|
self._last_request = (method, conn_url, kwargs)
|
||||||
|
if self._exc:
|
||||||
|
raise self._exc
|
||||||
|
|
||||||
def setresponse(self, response):
|
def setresponse(self, response):
|
||||||
self._response = response
|
self._response = response
|
||||||
|
|
||||||
def getresponse(self):
|
def getresponse(self):
|
||||||
return self._response
|
return self._response.get()
|
||||||
|
|
||||||
|
|
||||||
class FakeResponse(object):
|
class FakeResponse(object):
|
||||||
@@ -87,6 +93,12 @@ class FakeResponse(object):
|
|||||||
self.status = status
|
self.status = status
|
||||||
self.reason = reason
|
self.reason = reason
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
if key is 'location':
|
||||||
|
return 'fake_url'
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def getheaders(self):
|
def getheaders(self):
|
||||||
return copy.deepcopy(self.headers).items()
|
return copy.deepcopy(self.headers).items()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user