From 677a9777ecbeef4a0bfb6abc5d0a6c571d07cd42 Mon Sep 17 00:00:00 2001 From: "jaypipes@gmail.com" <> Date: Mon, 29 Nov 2010 11:00:10 -0500 Subject: [PATCH] Add files attribute to Parallax client tests --- glance/client.py | 12 ++++++ glance/parallax/controllers.py | 55 ++++++++++++------------ tests/stubs.py | 12 +++++- tests/unit/test_clients.py | 76 +++++++++++++++++++++++++++++----- 4 files changed, 116 insertions(+), 39 deletions(-) diff --git a/glance/client.py b/glance/client.py index 5f09a0fa96..4f79f4912d 100644 --- a/glance/client.py +++ b/glance/client.py @@ -148,6 +148,18 @@ class TellerClient(BaseClient): """ super(TellerClient, self).__init__(**kwargs) + def get_image(self, image_id): + """ + Returns the raw disk image as a mime-encoded blob. + + :param image_id: The opaque image identifier + + :raises exception.NotFound if image is not found + """ + res = self.do_request("GET", "image?%s" % image_id) + data = json.loads(res.read())['image'] + return data + class ParallaxClient(BaseClient): diff --git a/glance/parallax/controllers.py b/glance/parallax/controllers.py index 8dcfc52804..3bba726665 100644 --- a/glance/parallax/controllers.py +++ b/glance/parallax/controllers.py @@ -61,7 +61,7 @@ class ImageController(wsgi.Controller): """ images = db.image_get_all_public(None) - image_dicts = [self._make_image_dict(i) for i in images] + image_dicts = [make_image_dict(i) for i in images] return dict(images=image_dicts) def show(self, req, id): @@ -71,7 +71,7 @@ class ImageController(wsgi.Controller): except exception.NotFound: raise exc.HTTPNotFound() - return dict(image=self._make_image_dict(image)) + return dict(image=make_image_dict(image)) def delete(self, req, id): """Deletes an existing image with the registry. @@ -133,31 +133,6 @@ class ImageController(wsgi.Controller): except exception.NotFound: return exc.HTTPNotFound() - @staticmethod - def _make_image_dict(image): - """Create a dict representation of an image which we can use to - serialize the image. - - """ - - def _fetch_attrs(d, attrs): - return dict([(a, d[a]) for a in attrs]) - - files = [_fetch_attrs(f, db.IMAGE_FILE_ATTRS) for f in image['files']] - - # TODO(sirp): should this be a dict, or a list of dicts? - # A plain dict is more convenient, but list of dicts would provide - # access to created_at, etc - properties = dict((p['key'], p['value']) - for p in image['properties'] - if not p['deleted']) - - image_dict = _fetch_attrs(image, db.IMAGE_ATTRS) - - image_dict['files'] = files - image_dict['properties'] = properties - return image_dict - class API(wsgi.Router): """WSGI entry point for all Parallax requests.""" @@ -169,3 +144,29 @@ class API(wsgi.Router): collection={'detail': 'GET'}) mapper.connect("/", controller=ImageController(), action="index") super(API, self).__init__(mapper) + + +def make_image_dict(image): + """ + Create a dict representation of an image which we can use to + serialize the image. + """ + + def _fetch_attrs(d, attrs): + return dict([(a, d[a]) for a in attrs + if a in d.keys()]) + + files = [_fetch_attrs(f, db.IMAGE_FILE_ATTRS) for f in image['files']] + + # TODO(sirp): should this be a dict, or a list of dicts? + # A plain dict is more convenient, but list of dicts would provide + # access to created_at, etc + properties = dict((p['key'], p['value']) + for p in image['properties'] + if 'deleted' in p.keys() and not p['deleted']) + + image_dict = _fetch_attrs(image, db.IMAGE_ATTRS) + + image_dict['files'] = files + image_dict['properties'] = properties + return image_dict diff --git a/tests/stubs.py b/tests/stubs.py index 7cdff1639d..813a89ab34 100644 --- a/tests/stubs.py +++ b/tests/stubs.py @@ -225,7 +225,11 @@ def stub_out_parallax_db_image_api(stubs): 'updated_at': datetime.datetime.utcnow(), 'deleted_at': None, 'deleted': False, - 'files': [], + 'files': [ + {"location": "swift://user:passwd@acct/container/obj.tar.gz.0", + "size": 100000}, + {"location": "swift://user:passwd@acct/container/obj.tar.gz.1", + "size": 100001}], 'properties': []}, {'id': 2, 'name': 'fake image #2', @@ -236,7 +240,11 @@ def stub_out_parallax_db_image_api(stubs): 'updated_at': datetime.datetime.utcnow(), 'deleted_at': None, 'deleted': False, - 'files': [], + 'files': [ + {"location": "file://acct/2.tar.gz.0", + "size": 100000}, + {"location": "file://acct/2.tar.gz.1", + "size": 100001}], 'properties': []}] VALID_STATUSES = ('available', 'disabled', 'pending') diff --git a/tests/unit/test_clients.py b/tests/unit/test_clients.py index 347ca57e8d..18b125c89d 100644 --- a/tests/unit/test_clients.py +++ b/tests/unit/test_clients.py @@ -47,7 +47,10 @@ class TestBadClients(unittest.TestCase): class TestParallaxClient(unittest.TestCase): - """Test proper actions made for both valid and invalid requests""" + """ + Test proper actions made for both valid and invalid requests + against a Parallax service + """ def setUp(self): """Establish a clean test environment""" @@ -76,27 +79,61 @@ class TestParallaxClient(unittest.TestCase): 'name': 'fake image #2', 'is_public': True, 'image_type': 'kernel', - 'status': 'available' - } + 'status': 'available', + 'files': [ + {"location": "file://acct/2.tar.gz.0", + "size": 100000}, + {"location": "file://acct/2.tar.gz.1", + "size": 100001}], + 'properties': []} + + expected = {'id': 2, + 'name': 'fake image #2', + 'is_public': True, + 'image_type': 'kernel', + 'status': 'available', + 'files': [ + {"location": "file://acct/2.tar.gz.0", + "size": 100000}, + {"location": "file://acct/2.tar.gz.1", + "size": 100001}], + 'properties': {}} images = self.client.get_images_detailed() self.assertEquals(len(images), 1) - for k,v in fixture.iteritems(): + for k,v in expected.iteritems(): self.assertEquals(v, images[0][k]) - def test_get_image_metadata(self): + def test_get_image(self): """Tests that the detailed info about an image returned""" fixture = {'id': 2, 'name': 'fake image #2', 'is_public': True, 'image_type': 'kernel', - 'status': 'available' - } + 'status': 'available', + 'files': [ + {"location": "file://acct/2.tar.gz.0", + "size": 100000}, + {"location": "file://acct/2.tar.gz.1", + "size": 100001}], + 'properties': []} + + expected = {'id': 2, + 'name': 'fake image #2', + 'is_public': True, + 'image_type': 'kernel', + 'status': 'available', + 'files': [ + {"location": "file://acct/2.tar.gz.0", + "size": 100000}, + {"location": "file://acct/2.tar.gz.1", + "size": 100001}], + 'properties': {}} data = self.client.get_image(2) - for k,v in fixture.iteritems(): + for k,v in expected.iteritems(): self.assertEquals(v, data[k]) def test_get_image_non_existing(self): @@ -106,7 +143,7 @@ class TestParallaxClient(unittest.TestCase): self.client.get_image, 42) - def test_add_image_metadata_basic(self): + def test_add_image_basic(self): """Tests that we can add image metadata and returns the new id""" fixture = {'name': 'fake public image', 'is_public': True, @@ -128,7 +165,7 @@ class TestParallaxClient(unittest.TestCase): self.assertTrue('status' in data.keys()) self.assertEquals('available', data['status']) - def test_add_image_metadata_with_properties(self): + def test_add_image_with_properties(self): """Tests that we can add image metadata with properties""" fixture = {'name': 'fake public image', 'is_public': True, @@ -231,3 +268,22 @@ class TestParallaxClient(unittest.TestCase): self.assertRaises(exception.NotFound, self.client.delete_image, 3) + + +class TestTellerClient(unittest.TestCase): + + """ + Test proper actions made for both valid and invalid requests + against a Teller service + """ + + def setUp(self): + """Establish a clean test environment""" + self.stubs = stubout.StubOutForTesting() + stubs.stub_out_parallax_db_image_api(self.stubs) + stubs.stub_out_parallax_server(self.stubs) + self.client = client.ParallaxClient() + + def tearDown(self): + """Clear the test environment""" + self.stubs.UnsetAll()