summaryrefslogtreecommitdiff
path: root/nova/tests/image
diff options
context:
space:
mode:
authorJay Pipes <jaypipes@gmail.com>2014-03-11 17:29:37 -0400
committerJay Pipes <jaypipes@gmail.com>2014-03-11 21:42:32 -0400
commit8babd6a99014ccaf51d955769eaec085e037cc76 (patch)
tree593832cbe2dcf4acb75ea95db2d1dd9060c2beff /nova/tests/image
parent556ab844c823dd364032d59ab1b61780243cbfd1 (diff)
downloadnova-8babd6a99014ccaf51d955769eaec085e037cc76.tar.gz
Ensure is_image_available handles V2 Glance API
The V2 Glance API uses warlock to validate returned models from calls such as GET /images/{id}. The get_locations() call in the Nova Glance image driver was using the V2 Glance API call to GET /images/{id} (which is correct, since image locations only exist in the V2 API), but the GlanceImageService._is_image_available() method was checking the is_public attribute of the supplied image model. This caused warlock to throw an exception since is_public is not an attribute on the V2 API's returned image model in glanceclient. This change adds some checks that can handle both the V2 and V1 returned image models from glanceclient and a bunch of unit tests to thoroughly exercise the is_image_available method. Change-Id: I35b5af8331c5972bd89e1a674091fa2e3bde28a7 Closes-bug: #1291014
Diffstat (limited to 'nova/tests/image')
-rw-r--r--nova/tests/image/test_glance.py123
1 files changed, 123 insertions, 0 deletions
diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py
index abb69e10cf..4250566cc6 100644
--- a/nova/tests/image/test_glance.py
+++ b/nova/tests/image/test_glance.py
@@ -767,6 +767,129 @@ def _create_failing_glance_client(info):
return MyGlanceStubClient()
+class TestIsImageAvailable(test.NoDBTestCase):
+ """Tests the internal _is_image_available method on the Glance service."""
+
+ class ImageSpecV2(object):
+ visibility = None
+ properties = None
+
+ class ImageSpecV1(object):
+ is_public = None
+ properties = None
+
+ def test_auth_token_override(self):
+ ctx = mock.MagicMock(auth_token=True)
+ img = mock.MagicMock()
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+ img.assert_not_called()
+
+ def test_admin_override(self):
+ ctx = mock.MagicMock(auth_token=False, is_admin=True)
+ img = mock.MagicMock()
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+ img.assert_not_called()
+
+ def test_v2_visibility(self):
+ ctx = mock.MagicMock(auth_token=False, is_admin=False)
+ # We emulate warlock validation that throws an AttributeError
+ # if you try to call is_public on an image model returned by
+ # a call to V2 image.get(). Here, the ImageSpecV2 does not have
+ # an is_public attribute and MagicMock will throw an AttributeError.
+ img = mock.MagicMock(visibility='PUBLIC',
+ spec=TestIsImageAvailable.ImageSpecV2)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+
+ def test_v1_is_public(self):
+ ctx = mock.MagicMock(auth_token=False, is_admin=False)
+ img = mock.MagicMock(is_public=True,
+ spec=TestIsImageAvailable.ImageSpecV1)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+
+ def test_project_is_owner(self):
+ ctx = mock.MagicMock(auth_token=False, is_admin=False,
+ project_id='123')
+ props = {
+ 'owner_id': '123'
+ }
+ img = mock.MagicMock(visibility='private', properties=props,
+ spec=TestIsImageAvailable.ImageSpecV2)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+
+ ctx.reset_mock()
+ img = mock.MagicMock(is_public=False, properties=props,
+ spec=TestIsImageAvailable.ImageSpecV1)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+
+ def test_project_context_matches_project_prop(self):
+ ctx = mock.MagicMock(auth_token=False, is_admin=False,
+ project_id='123')
+ props = {
+ 'project_id': '123'
+ }
+ img = mock.MagicMock(visibility='private', properties=props,
+ spec=TestIsImageAvailable.ImageSpecV2)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+
+ ctx.reset_mock()
+ img = mock.MagicMock(is_public=False, properties=props,
+ spec=TestIsImageAvailable.ImageSpecV1)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+
+ def test_no_user_in_props(self):
+ ctx = mock.MagicMock(auth_token=False, is_admin=False,
+ project_id='123')
+ props = {
+ }
+ img = mock.MagicMock(visibility='private', properties=props,
+ spec=TestIsImageAvailable.ImageSpecV2)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertFalse(res)
+
+ ctx.reset_mock()
+ img = mock.MagicMock(is_public=False, properties=props,
+ spec=TestIsImageAvailable.ImageSpecV1)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertFalse(res)
+
+ def test_user_matches_context(self):
+ ctx = mock.MagicMock(auth_token=False, is_admin=False,
+ user_id='123')
+ props = {
+ 'user_id': '123'
+ }
+ img = mock.MagicMock(visibility='private', properties=props,
+ spec=TestIsImageAvailable.ImageSpecV2)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+
+ ctx.reset_mock()
+ img = mock.MagicMock(is_public=False, properties=props,
+ spec=TestIsImageAvailable.ImageSpecV1)
+
+ res = glance.GlanceImageService._is_image_available(ctx, img)
+ self.assertTrue(res)
+
+
class TestGlanceClientWrapper(test.NoDBTestCase):
def setUp(self):