diff --git a/glance/api/v2/image_data.py b/glance/api/v2/image_data.py index 317c7aa592..0c990ca2ed 100644 --- a/glance/api/v2/image_data.py +++ b/glance/api/v2/image_data.py @@ -199,8 +199,6 @@ class ImageDataController(object): msg = _('The requested image has been deactivated. ' 'Image data download is forbidden.') raise exception.Forbidden(message=msg) - if not image.locations: - raise exception.ImageDataNotFound() except exception.ImageDataNotFound as e: raise webob.exc.HTTPNoContent(explanation=e.msg) except exception.NotFound as e: @@ -248,7 +246,7 @@ class ResponseSerializer(wsgi.JSONResponseSerializer): response.app_iter = iter(image.get_data(offset=offset, chunk_size=chunk_size)) except glance_store.NotFound as e: - raise webob.exc.HTTPNotFound(explanation=e.msg) + raise webob.exc.HTTPNoContent(explanation=e.msg) except glance_store.RemoteServiceUnavailable as e: raise webob.exc.HTTPServiceUnavailable(explanation=e.msg) except (glance_store.StoreGetNotSupported, diff --git a/glance/location.py b/glance/location.py index 20f8f76bdd..a19d234e8c 100644 --- a/glance/location.py +++ b/glance/location.py @@ -397,7 +397,12 @@ class ImageProxy(glance.domain.proxy.Image): def get_data(self, offset=0, chunk_size=None): if not self.image.locations: - raise store.NotFound(_("No image data could be found")) + # NOTE(mclaren): This is the only set of arguments + # which work with this exception currently, see: + # https://bugs.launchpad.net/glance-store/+bug/1501443 + # When the above glance_store bug is fixed we can + # add a msg as usual. + raise store.NotFound(image=None) err = None for loc in self.image.locations: try: diff --git a/glance/tests/unit/v2/test_image_data_resource.py b/glance/tests/unit/v2/test_image_data_resource.py index b96c05342f..a453a2d0ff 100644 --- a/glance/tests/unit/v2/test_image_data_resource.py +++ b/glance/tests/unit/v2/test_image_data_resource.py @@ -122,10 +122,12 @@ class TestImagesController(base.StoreClearingUnitTest): request, str(uuid.uuid4())) def test_download_no_location(self): + # NOTE(mclaren): NoContent will be raised by the ResponseSerializer + # That's tested below. request = unit_test_utils.get_fake_request() self.image_repo.result = FakeImage('abcd') - self.assertRaises(webob.exc.HTTPNoContent, self.controller.download, - request, unit_test_utils.UUID2) + image = self.controller.download(request, unit_test_utils.UUID2) + self.assertEqual('abcd', image.image_id) def test_download_non_existent_image(self): request = unit_test_utils.get_fake_request() @@ -139,7 +141,7 @@ class TestImagesController(base.StoreClearingUnitTest): self.assertRaises(webob.exc.HTTPForbidden, self.controller.download, request, str(uuid.uuid4())) - def test_download_get_image_location_forbidden(self): + def test_download_ok_when_get_image_location_forbidden(self): class ImageLocations(object): def __len__(self): raise exception.Forbidden() @@ -148,8 +150,8 @@ class TestImagesController(base.StoreClearingUnitTest): image = FakeImage('abcd') self.image_repo.result = image image.locations = ImageLocations() - self.assertRaises(webob.exc.HTTPForbidden, self.controller.download, - request, str(uuid.uuid4())) + image = self.controller.download(request, unit_test_utils.UUID1) + self.assertEqual('abcd', image.image_id) def test_upload(self): request = unit_test_utils.get_fake_request() @@ -493,11 +495,11 @@ class TestImageDataSerializer(test_utils.BaseTestCase): self.serializer.download, response, image) - def test_download_not_found(self): - """Test image download returns HTTPNotFound. + def test_download_no_content(self): + """Test image download returns HTTPNoContent - Make sure that serializer returns 404 not found error in case of - image is not available at specified location. + Make sure that serializer returns 204 no content error in case of + image data is not available at specified location. """ with mock.patch.object(glance.api.policy.ImageProxy, 'get_data') as mock_get_data: @@ -508,7 +510,7 @@ class TestImageDataSerializer(test_utils.BaseTestCase): response.request = request image = FakeImage(size=3, data=iter('ZZZ')) image.get_data = mock_get_data - self.assertRaises(webob.exc.HTTPNotFound, + self.assertRaises(webob.exc.HTTPNoContent, self.serializer.download, response, image)