Merge "Add endpoint hook to BaseAPI"

This commit is contained in:
Jenkins 2017-05-04 13:47:44 +00:00 committed by Gerrit Code Review
commit 689c46461e
2 changed files with 142 additions and 3 deletions

View File

@ -14,6 +14,7 @@
"""Base API Library"""
import simplejson as json
import six
from keystoneauth1 import exceptions as ksa_exceptions
from keystoneauth1 import session as ksa_session
@ -69,7 +70,28 @@ class BaseAPI(object):
self.session = session
self.service_type = service_type
self.endpoint = endpoint
self.endpoint = self._munge_endpoint(endpoint)
def _munge_endpoint(self, endpoint):
"""Hook to allow subclasses to massage the passed-in endpoint
Hook to massage passed-in endpoints from arbitrary sources,
including direct user input. By default just remove trailing
'/' as all of our path info strings start with '/' and not all
services can handle '//' in their URLs.
Some subclasses will override this to do additional work, most
likely with regard to API versions.
:param string endpoint: The service endpoint, generally direct
from the service catalog.
:return: The modified endpoint
"""
if isinstance(endpoint, six.string_types):
return endpoint.rstrip('/')
else:
return endpoint
def _request(self, method, url, session=None, **kwargs):
"""Perform call into session
@ -99,6 +121,9 @@ class BaseAPI(object):
if url:
url = '/'.join([self.endpoint.rstrip('/'), url.lstrip('/')])
else:
# NOTE(dtroyer): This is left here after _munge_endpoint() is
# added because endpoint is public and there is
# no accounting for what may happen.
url = self.endpoint.rstrip('/')
else:
# Pass on the lack of URL unmolested to maintain the same error

View File

@ -13,7 +13,7 @@
"""Base API Library Tests"""
from keystoneauth1 import exceptions as ks_exceptions
from keystoneauth1 import exceptions as ksa_exceptions
from keystoneauth1 import session
from osc_lib.api import api
@ -27,6 +27,22 @@ class TestBaseAPIDefault(api_fakes.TestSession):
super(TestBaseAPIDefault, self).setUp()
self.api = api.BaseAPI()
def test_baseapi_request_no_url(self):
self.requests_mock.register_uri(
'GET',
self.BASE_URL + '/qaz',
json=api_fakes.RESP_ITEM_1,
status_code=200,
)
self.assertRaises(
ksa_exceptions.EndpointNotFound,
self.api._request,
'GET',
'',
)
self.assertIsNotNone(self.api.session)
self.assertNotEqual(self.sess, self.api.session)
def test_baseapi_request_url(self):
self.requests_mock.register_uri(
'GET',
@ -47,7 +63,7 @@ class TestBaseAPIDefault(api_fakes.TestSession):
status_code=200,
)
self.assertRaises(
ks_exceptions.EndpointNotFound,
ksa_exceptions.EndpointNotFound,
self.api._request,
'GET',
'/qaz',
@ -72,6 +88,104 @@ class TestBaseAPIDefault(api_fakes.TestSession):
self.assertNotEqual(self.sess, self.api.session)
class TestBaseAPIEndpointArg(api_fakes.TestSession):
def test_baseapi_endpoint_no_endpoint(self):
x_api = api.BaseAPI(
session=self.sess,
)
self.assertIsNotNone(x_api.session)
self.assertEqual(self.sess, x_api.session)
self.assertIsNone(x_api.endpoint)
self.requests_mock.register_uri(
'GET',
self.BASE_URL + '/qaz',
json=api_fakes.RESP_ITEM_1,
status_code=200,
)
# Normal url
self.assertRaises(
ksa_exceptions.EndpointNotFound,
x_api._request,
'GET',
'/qaz',
)
# No leading '/' url
self.assertRaises(
ksa_exceptions.EndpointNotFound,
x_api._request,
'GET',
'qaz',
)
# Extra leading '/' url
self.assertRaises(
ksa_exceptions.connection.UnknownConnectionError,
x_api._request,
'GET',
'//qaz',
)
def test_baseapi_endpoint_no_extra(self):
x_api = api.BaseAPI(
session=self.sess,
endpoint=self.BASE_URL,
)
self.assertIsNotNone(x_api.session)
self.assertEqual(self.sess, x_api.session)
self.assertEqual(self.BASE_URL, x_api.endpoint)
self.requests_mock.register_uri(
'GET',
self.BASE_URL + '/qaz',
json=api_fakes.RESP_ITEM_1,
status_code=200,
)
# Normal url
ret = x_api._request('GET', '/qaz')
self.assertEqual(api_fakes.RESP_ITEM_1, ret.json())
# No leading '/' url
ret = x_api._request('GET', 'qaz')
self.assertEqual(api_fakes.RESP_ITEM_1, ret.json())
# Extra leading '/' url
ret = x_api._request('GET', '//qaz')
self.assertEqual(api_fakes.RESP_ITEM_1, ret.json())
def test_baseapi_endpoint_extra(self):
x_api = api.BaseAPI(
session=self.sess,
endpoint=self.BASE_URL + '/',
)
self.assertIsNotNone(x_api.session)
self.assertEqual(self.sess, x_api.session)
self.assertEqual(self.BASE_URL, x_api.endpoint)
self.requests_mock.register_uri(
'GET',
self.BASE_URL + '/qaz',
json=api_fakes.RESP_ITEM_1,
status_code=200,
)
# Normal url
ret = x_api._request('GET', '/qaz')
self.assertEqual(api_fakes.RESP_ITEM_1, ret.json())
# No leading '/' url
ret = x_api._request('GET', 'qaz')
self.assertEqual(api_fakes.RESP_ITEM_1, ret.json())
# Extra leading '/' url
ret = x_api._request('GET', '//qaz')
self.assertEqual(api_fakes.RESP_ITEM_1, ret.json())
class TestBaseAPIArgs(api_fakes.TestSession):
def setUp(self):