Move _get_locations to module level plus tests
Moves the nova.image.glance.GlanceImageService._get_locations object method into module level scope (the self argument was unused) and adds full unit tests for the nova.image.glance._get_location() function. Change-Id: Ib386330b70abe1e0353f1fafa3e68bc3e7a2d1b1 Partial-bug: #1293938
This commit is contained in:
parent
de9f5feba4
commit
9048078fcc
@ -277,25 +277,6 @@ class GlanceImageService(object):
|
||||
base_image_meta = _translate_from_glance(image)
|
||||
return base_image_meta
|
||||
|
||||
def _get_locations(self, context, image_id):
|
||||
"""Returns the direct url representing the backend storage location,
|
||||
or None if this attribute is not shown by Glance.
|
||||
"""
|
||||
try:
|
||||
client = GlanceClientWrapper()
|
||||
image_meta = client.call(context, 2, 'get', image_id)
|
||||
except Exception:
|
||||
_reraise_translated_image_exception(image_id)
|
||||
|
||||
if not _is_image_available(context, image_meta):
|
||||
raise exception.ImageNotFound(image_id=image_id)
|
||||
|
||||
locations = getattr(image_meta, 'locations', [])
|
||||
du = getattr(image_meta, 'direct_url', None)
|
||||
if du:
|
||||
locations.append({'url': du, 'metadata': {}})
|
||||
return locations
|
||||
|
||||
def _get_transfer_module(self, scheme):
|
||||
try:
|
||||
return self._download_handlers[scheme]
|
||||
@ -309,7 +290,7 @@ class GlanceImageService(object):
|
||||
def download(self, context, image_id, data=None, dst_path=None):
|
||||
"""Calls out to Glance for data and writes data."""
|
||||
if CONF.allowed_direct_url_schemes and dst_path is not None:
|
||||
locations = self._get_locations(context, image_id)
|
||||
locations = _get_locations(self._client, context, image_id)
|
||||
for entry in locations:
|
||||
loc_url = entry['url']
|
||||
loc_meta = entry['metadata']
|
||||
@ -395,6 +376,25 @@ class GlanceImageService(object):
|
||||
return True
|
||||
|
||||
|
||||
def _get_locations(client, context, image_id):
|
||||
"""Returns the direct url representing the backend storage location,
|
||||
or None if this attribute is not shown by Glance.
|
||||
"""
|
||||
try:
|
||||
image_meta = client.call(context, 2, 'get', image_id)
|
||||
except Exception:
|
||||
_reraise_translated_image_exception(image_id)
|
||||
|
||||
if not _is_image_available(context, image_meta):
|
||||
raise exception.ImageNotFound(image_id=image_id)
|
||||
|
||||
locations = getattr(image_meta, 'locations', [])
|
||||
du = getattr(image_meta, 'direct_url', None)
|
||||
if du:
|
||||
locations.append({'url': du, 'metadata': {}})
|
||||
return locations
|
||||
|
||||
|
||||
def _extract_query_params(params):
|
||||
_params = {}
|
||||
accepted_params = ('filters', 'marker', 'limit',
|
||||
|
@ -466,6 +466,68 @@ def _create_failing_glance_client(info):
|
||||
return MyGlanceStubClient()
|
||||
|
||||
|
||||
class TestGetLocations(test.NoDBTestCase):
|
||||
"""Tests the internal _get_locations function."""
|
||||
|
||||
class ImageSpecV2(object):
|
||||
visibility = None
|
||||
properties = None
|
||||
locations = None
|
||||
direct_url = None
|
||||
|
||||
@mock.patch('nova.image.glance._is_image_available')
|
||||
def test_success_has_locations(self, avail_mock):
|
||||
avail_mock.return_value = True
|
||||
locations = [
|
||||
mock.sentinel.loc1
|
||||
]
|
||||
image_meta = mock.MagicMock(locations=locations,
|
||||
spec=TestGetLocations.ImageSpecV2)
|
||||
|
||||
client_mock = mock.MagicMock()
|
||||
client_mock.call.return_value = image_meta
|
||||
locs = glance._get_locations(client_mock, mock.sentinel.ctx,
|
||||
mock.sentinel.image_id)
|
||||
client_mock.call.assert_called_once_with(mock.sentinel.ctx,
|
||||
2, 'get',
|
||||
mock.sentinel.image_id)
|
||||
self.assertEqual(locations, locs)
|
||||
avail_mock.assert_called_once_with(mock.sentinel.ctx, image_meta)
|
||||
|
||||
@mock.patch('nova.image.glance._is_image_available')
|
||||
def test_success_direct_uri_added_to_locations(self, avail_mock):
|
||||
avail_mock.return_value = True
|
||||
locations = [
|
||||
mock.sentinel.loc1
|
||||
]
|
||||
image_meta = mock.MagicMock(locations=locations,
|
||||
spec=TestGetLocations.ImageSpecV2,
|
||||
direct_uri=mock.sentinel.duri)
|
||||
|
||||
client_mock = mock.MagicMock()
|
||||
client_mock.call.return_value = image_meta
|
||||
locs = glance._get_locations(client_mock, mock.sentinel.ctx,
|
||||
mock.sentinel.image_id)
|
||||
client_mock.call.assert_called_once_with(mock.sentinel.ctx,
|
||||
2, 'get',
|
||||
mock.sentinel.image_id)
|
||||
expected = locations
|
||||
expected.append({"url": mock.sentinel.duri, "metadata": {}})
|
||||
self.assertEqual(expected, locs)
|
||||
|
||||
@mock.patch('nova.image.glance._reraise_translated_image_exception')
|
||||
@mock.patch('nova.image.glance._is_image_available')
|
||||
def test_get_locations_not_found(self, avail_mock, reraise_mock):
|
||||
raised = exception.ImageNotFound(image_id=123)
|
||||
reraise_mock.side_effect = raised
|
||||
|
||||
client_mock = mock.MagicMock()
|
||||
client_mock.call.side_effect = glanceclient.exc.NotFound
|
||||
self.assertRaises(exception.ImageNotFound, glance._get_locations,
|
||||
client_mock, mock.sentinel.ctx,
|
||||
mock.sentinel.image_id)
|
||||
|
||||
|
||||
class TestIsImageAvailable(test.NoDBTestCase):
|
||||
"""Tests the internal _is_image_available function."""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user