diff options
Diffstat (limited to 'openstackclient/tests/unit/image/v2/fakes.py')
-rw-r--r-- | openstackclient/tests/unit/image/v2/fakes.py | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/openstackclient/tests/unit/image/v2/fakes.py b/openstackclient/tests/unit/image/v2/fakes.py new file mode 100644 index 00000000..4d9f6458 --- /dev/null +++ b/openstackclient/tests/unit/image/v2/fakes.py @@ -0,0 +1,309 @@ +# Copyright 2013 Nebula Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import copy +import mock +import random +import uuid + +from glanceclient.v2 import schemas +from osc_lib import utils as common_utils +import warlock + +from openstackclient.tests.unit import fakes +from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes +from openstackclient.tests.unit import utils + +image_id = '0f41529e-7c12-4de8-be2d-181abb825b3c' +image_name = 'graven' +image_owner = 'baal' +image_protected = False +image_visibility = 'public' +image_tags = [] + +IMAGE = { + 'id': image_id, + 'name': image_name, + 'owner': image_owner, + 'protected': image_protected, + 'visibility': image_visibility, + 'tags': image_tags +} + +IMAGE_columns = tuple(sorted(IMAGE)) +IMAGE_data = tuple((IMAGE[x] for x in sorted(IMAGE))) + +IMAGE_SHOW = copy.copy(IMAGE) +IMAGE_SHOW['tags'] = '' +IMAGE_SHOW_data = tuple((IMAGE_SHOW[x] for x in sorted(IMAGE_SHOW))) + +# Just enough v2 schema to do some testing +IMAGE_schema = { + "additionalProperties": { + "type": "string" + }, + "name": "image", + "links": [ + { + "href": "{self}", + "rel": "self" + }, + { + "href": "{file}", + "rel": "enclosure" + }, + { + "href": "{schema}", + "rel": "describedby" + } + ], + "properties": { + "id": { + "pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$", # noqa + "type": "string", + "description": "An identifier for the image" + }, + "name": { + "type": [ + "null", + "string" + ], + "description": "Descriptive name for the image", + "maxLength": 255 + }, + "owner": { + "type": [ + "null", + "string" + ], + "description": "Owner of the image", + "maxLength": 255 + }, + "protected": { + "type": "boolean", + "description": "If true, image will not be deletable." + }, + "self": { + "type": "string", + "description": "(READ-ONLY)" + }, + "schema": { + "type": "string", + "description": "(READ-ONLY)" + }, + "size": { + "type": [ + "null", + "integer" + ], + "description": "Size of image file in bytes (READ-ONLY)" + }, + "status": { + "enum": [ + "queued", + "saving", + "active", + "killed", + "deleted", + "pending_delete" + ], + "type": "string", + "description": "Status of the image (READ-ONLY)" + }, + "tags": { + "items": { + "type": "string", + "maxLength": 255 + }, + "type": "array", + "description": "List of strings related to the image" + }, + "visibility": { + "enum": [ + "public", + "private" + ], + "type": "string", + "description": "Scope of image accessibility" + }, + } +} + + +class FakeImagev2Client(object): + + def __init__(self, **kwargs): + self.images = mock.Mock() + self.images.resource_class = fakes.FakeResource(None, {}) + self.image_members = mock.Mock() + self.image_members.resource_class = fakes.FakeResource(None, {}) + self.image_tags = mock.Mock() + self.image_tags.resource_class = fakes.FakeResource(None, {}) + self.auth_token = kwargs['token'] + self.management_url = kwargs['endpoint'] + + +class TestImagev2(utils.TestCommand): + + def setUp(self): + super(TestImagev2, self).setUp() + + self.app.client_manager.image = FakeImagev2Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) + + self.app.client_manager.identity = identity_fakes.FakeIdentityv3Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) + + +class FakeImage(object): + """Fake one or more images. + + TODO(xiexs): Currently, only image API v2 is supported by this class. + """ + + @staticmethod + def create_one_image(attrs=None): + """Create a fake image. + + :param Dictionary attrs: + A dictionary with all attrbutes of image + :return: + A FakeResource object with id, name, owner, protected, + visibility and tags attrs + """ + attrs = attrs or {} + + # Set default attribute + image_info = { + 'id': str(uuid.uuid4()), + 'name': 'image-name' + uuid.uuid4().hex, + 'owner': 'image-owner' + uuid.uuid4().hex, + 'protected': bool(random.choice([0, 1])), + 'visibility': random.choice(['public', 'private']), + 'tags': [uuid.uuid4().hex for r in range(2)], + } + + # Overwrite default attributes if there are some attributes set + image_info.update(attrs) + + # Set up the schema + model = warlock.model_factory( + IMAGE_schema, + schemas.SchemaBasedModel, + ) + + return model(**image_info) + + @staticmethod + def create_images(attrs=None, count=2): + """Create multiple fake images. + + :param Dictionary attrs: + A dictionary with all attributes of image + :param Integer count: + The number of images to be faked + :return: + A list of FakeResource objects + """ + images = [] + for n in range(0, count): + images.append(FakeImage.create_one_image(attrs)) + + return images + + @staticmethod + def get_images(images=None, count=2): + """Get an iterable MagicMock object with a list of faked images. + + If images list is provided, then initialize the Mock object with the + list. Otherwise create one. + + :param List images: + A list of FakeResource objects faking images + :param Integer count: + The number of images to be faked + :return + An iterable Mock object with side_effect set to a list of faked + images + """ + if images is None: + images = FakeImage.create_images(count) + + return mock.MagicMock(side_effect=images) + + @staticmethod + def get_image_columns(image=None): + """Get the image columns from a faked image object. + + :param image: + A FakeResource objects faking image + :return + A tuple which may include the following keys: + ('id', 'name', 'owner', 'protected', 'visibility', 'tags') + """ + if image is not None: + return tuple(sorted(image)) + return IMAGE_columns + + @staticmethod + def get_image_data(image=None): + """Get the image data from a faked image object. + + :param image: + A FakeResource objects faking image + :return + A tuple which may include the following values: + ('image-123', 'image-foo', 'admin', False, 'public', 'bar, baz') + """ + data_list = [] + if image is not None: + for x in sorted(image.keys()): + if x == 'tags': + # The 'tags' should be format_list + data_list.append( + common_utils.format_list(getattr(image, x))) + else: + data_list.append(getattr(image, x)) + return tuple(data_list) + + @staticmethod + def create_one_image_member(attrs=None): + """Create a fake image member. + + :param Dictionary attrs: + A dictionary with all attrbutes of image member + :return: + A FakeResource object with member_id, image_id and so on + """ + attrs = attrs or {} + + # Set default attribute + image_member_info = { + 'member_id': 'member-id-' + uuid.uuid4().hex, + 'image_id': 'image-id-' + uuid.uuid4().hex, + 'status': 'pending', + } + + # Overwrite default attributes if there are some attributes set + image_member_info.update(attrs) + + image_member = fakes.FakeModel( + copy.deepcopy(image_member_info)) + + return image_member |