blob: 3e72b3432b0eaf016b38720ee7521d3d7c396bb8 [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2013 OpenStack Foundation
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +05302# Copyright 2013 IBM Corp
Matthew Treinisha62347f2013-03-01 16:37:30 -05003# All Rights Reserved.
Matthew Treinisha62347f2013-03-01 16:37:30 -05004#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16
Matthew Treinisha62347f2013-03-01 16:37:30 -050017import random
18
Sirushti Murugesan12dc9732016-07-13 22:49:17 +053019import six
Matthew Treinish01472ff2015-02-20 17:26:52 -050020
Takashi NATSUME12a48512015-08-10 18:33:16 +090021from oslo_log import log as logging
Sean Dague1937d092013-05-17 16:36:38 -040022from tempest.api.image import base
Takashi NATSUME12a48512015-08-10 18:33:16 +090023from tempest import config
Ken'ichi Ohmichicc01c3e2017-03-10 10:48:14 -080024from tempest.lib.common.utils import data_utils
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -080025from tempest.lib import decorators
lkuchlan32b53c32017-04-20 16:51:08 +030026from tempest.lib import exceptions as lib_exc
Matthew Treinisha62347f2013-03-01 16:37:30 -050027
Takashi NATSUME12a48512015-08-10 18:33:16 +090028CONF = config.CONF
29LOG = logging.getLogger(__name__)
30
Matthew Treinisha62347f2013-03-01 16:37:30 -050031
Abhishek Kekane7cff1302020-07-16 10:30:13 +000032class ImportImagesTest(base.BaseV2ImageTest):
33 """Here we test the import operations for image"""
34
35 @classmethod
36 def skip_checks(cls):
37 super(ImportImagesTest, cls).skip_checks()
38 if not CONF.image_feature_enabled.import_image:
39 skip_msg = (
40 "%s skipped as image import is not available" % cls.__name__)
41 raise cls.skipException(skip_msg)
42
43 @decorators.idempotent_id('32ca0c20-e16f-44ac-8590-07869c9b4cc2')
44 def test_image_import(self):
45 """Here we test these functionalities
46
47 Create image, stage image data, import image and verify
48 that import succeeded.
49 """
50
51 body = self.client.info_import()
52 if 'glance-direct' not in body['import-methods']['value']:
53 raise self.skipException('Server does not support '
54 'glance-direct import method')
55
56 # Create image
57 uuid = '00000000-1111-2222-3333-444455556666'
58 image_name = data_utils.rand_name('image')
59 container_format = CONF.image.container_formats[0]
60 disk_format = CONF.image.disk_formats[0]
61 image = self.create_image(name=image_name,
62 container_format=container_format,
63 disk_format=disk_format,
64 visibility='private',
65 ramdisk_id=uuid)
66 self.assertIn('name', image)
67 self.assertEqual(image_name, image['name'])
68 self.assertIn('visibility', image)
69 self.assertEqual('private', image['visibility'])
70 self.assertIn('status', image)
71 self.assertEqual('queued', image['status'])
72
73 # Stage image data
74 file_content = data_utils.random_bytes()
75 image_file = six.BytesIO(file_content)
76 self.client.stage_image_file(image['id'], image_file)
77
78 # Now try to get image details
79 body = self.client.show_image(image['id'])
80 self.assertEqual(image['id'], body['id'])
81 self.assertEqual(image_name, body['name'])
82 self.assertEqual(uuid, body['ramdisk_id'])
83 self.assertEqual('uploading', body['status'])
84
85 # import image from staging to backend
86 self.client.image_import(image['id'])
87 self.client.wait_for_resource_activation(image['id'])
88
89
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +053090class BasicOperationsImagesTest(base.BaseV2ImageTest):
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +000091 """Here we test the basic operations of images"""
Matthew Treinisha62347f2013-03-01 16:37:30 -050092
Jordan Pittier3b46d272017-04-12 16:17:28 +020093 @decorators.attr(type='smoke')
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -080094 @decorators.idempotent_id('139b765e-7f3d-4b3d-8b37-3ca3876ee318')
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +053095 def test_register_upload_get_image_file(self):
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +000096 """Here we test these functionalities
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +053097
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +000098 Register image, upload the image file, get image and get image
99 file api's
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530100 """
101
Sean Daguec6ec4762014-05-29 08:54:21 -0400102 uuid = '00000000-1111-2222-3333-444455556666'
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530103 image_name = data_utils.rand_name('image')
Takashi NATSUME12a48512015-08-10 18:33:16 +0900104 container_format = CONF.image.container_formats[0]
105 disk_format = CONF.image.disk_formats[0]
lkuchlanb3348792016-09-29 10:42:21 +0300106 image = self.create_image(name=image_name,
107 container_format=container_format,
108 disk_format=disk_format,
109 visibility='private',
110 ramdisk_id=uuid)
lkuchlanb3348792016-09-29 10:42:21 +0300111 self.assertIn('name', image)
112 self.assertEqual(image_name, image['name'])
113 self.assertIn('visibility', image)
114 self.assertEqual('private', image['visibility'])
115 self.assertIn('status', image)
116 self.assertEqual('queued', image['status'])
Matthew Treinisha62347f2013-03-01 16:37:30 -0500117
wangxiyuan99e4dcf2019-09-17 09:51:55 +0800118 # NOTE: This Glance API returns different status codes for image
119 # condition. In this empty data case, Glance should return 204,
120 # so here should check the status code.
121 image_file = self.client.show_image_file(image['id'])
122 self.assertEqual(0, len(image_file.data))
123 self.assertEqual(204, image_file.response.status)
124
Matthew Treinisha62347f2013-03-01 16:37:30 -0500125 # Now try uploading an image file
Mark Washenberger5c3b6fe2014-07-29 13:40:34 -0700126 file_content = data_utils.random_bytes()
Sirushti Murugesan12dc9732016-07-13 22:49:17 +0530127 image_file = six.BytesIO(file_content)
lkuchlanb3348792016-09-29 10:42:21 +0300128 self.client.store_image_file(image['id'], image_file)
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530129
130 # Now try to get image details
lkuchlanb3348792016-09-29 10:42:21 +0300131 body = self.client.show_image(image['id'])
132 self.assertEqual(image['id'], body['id'])
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530133 self.assertEqual(image_name, body['name'])
Sean Daguec6ec4762014-05-29 08:54:21 -0400134 self.assertEqual(uuid, body['ramdisk_id'])
Attila Fazekase191cb12013-07-29 06:41:52 +0200135 self.assertIn('size', body)
Matthew Treinisha62347f2013-03-01 16:37:30 -0500136 self.assertEqual(1024, body.get('size'))
137
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530138 # Now try get image file
Ken'ichi Ohmichi3b79f172018-03-20 11:31:44 -0700139 # NOTE: This Glance API returns different status codes for image
140 # condition. In this non-empty data case, Glance should return 200,
141 # so here should check the status code.
lkuchlanb3348792016-09-29 10:42:21 +0300142 body = self.client.show_image_file(image['id'])
David Kranzd7e97b42015-02-16 09:37:31 -0500143 self.assertEqual(file_content, body.data)
Ken'ichi Ohmichi3b79f172018-03-20 11:31:44 -0700144 self.assertEqual(200, body.response.status)
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530145
Jordan Pittier3b46d272017-04-12 16:17:28 +0200146 @decorators.attr(type='smoke')
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800147 @decorators.idempotent_id('f848bb94-1c6e-45a4-8726-39e3a5b23535')
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530148 def test_delete_image(self):
zhufle68f4352020-04-21 13:44:55 +0800149 """Test deleting an image by image_id"""
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530150 # Create image
151 image_name = data_utils.rand_name('image')
Takashi NATSUME12a48512015-08-10 18:33:16 +0900152 container_format = CONF.image.container_formats[0]
153 disk_format = CONF.image.disk_formats[0]
Benny Kopilov900fceb2016-11-09 09:45:40 +0200154 image = self.create_image(name=image_name,
155 container_format=container_format,
156 disk_format=disk_format,
157 visibility='private')
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530158 # Delete Image
lkuchlanb3348792016-09-29 10:42:21 +0300159 self.client.delete_image(image['id'])
160 self.client.wait_for_resource_deletion(image['id'])
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530161
162 # Verifying deletion
John Warrenf3b3e952015-08-17 19:28:12 +0000163 images = self.client.list_images()['images']
Sunil G29856a32014-07-17 23:17:58 +0530164 images_id = [item['id'] for item in images]
lkuchlanb3348792016-09-29 10:42:21 +0300165 self.assertNotIn(image['id'], images_id)
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530166
Jordan Pittier3b46d272017-04-12 16:17:28 +0200167 @decorators.attr(type='smoke')
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800168 @decorators.idempotent_id('f66891a7-a35c-41a8-b590-a065c2a1caa6')
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400169 def test_update_image(self):
zhufle68f4352020-04-21 13:44:55 +0800170 """Test updating an image by image_id"""
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400171 # Create image
172 image_name = data_utils.rand_name('image')
Takashi NATSUME12a48512015-08-10 18:33:16 +0900173 container_format = CONF.image.container_formats[0]
174 disk_format = CONF.image.disk_formats[0]
Benny Kopilov900fceb2016-11-09 09:45:40 +0200175 image = self.create_image(name=image_name,
176 container_format=container_format,
177 disk_format=disk_format,
178 visibility='private')
lkuchlanb3348792016-09-29 10:42:21 +0300179 self.assertEqual('queued', image['status'])
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400180
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400181 # Update Image
182 new_image_name = data_utils.rand_name('new-image')
zhufl311104e2017-08-17 15:13:18 +0800183 self.client.update_image(image['id'], [
Aaron Rosenc7720622014-05-20 10:38:10 -0700184 dict(replace='/name', value=new_image_name)])
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400185
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400186 # Verifying updating
187
lkuchlanb3348792016-09-29 10:42:21 +0300188 body = self.client.show_image(image['id'])
189 self.assertEqual(image['id'], body['id'])
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400190 self.assertEqual(new_image_name, body['name'])
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400191
lkuchlan32b53c32017-04-20 16:51:08 +0300192 @decorators.idempotent_id('951ebe01-969f-4ea9-9898-8a3f1f442ab0')
193 def test_deactivate_reactivate_image(self):
zhufle68f4352020-04-21 13:44:55 +0800194 """Test deactivating and reactivating an image"""
lkuchlan32b53c32017-04-20 16:51:08 +0300195 # Create image
196 image_name = data_utils.rand_name('image')
197 image = self.create_image(name=image_name,
198 container_format='bare',
199 disk_format='raw',
200 visibility='private')
201
202 # Upload an image file
203 content = data_utils.random_bytes()
204 image_file = six.BytesIO(content)
205 self.client.store_image_file(image['id'], image_file)
206
207 # Deactivate image
208 self.client.deactivate_image(image['id'])
209 body = self.client.show_image(image['id'])
210 self.assertEqual("deactivated", body['status'])
211
212 # User unable to download deactivated image
213 self.assertRaises(lib_exc.Forbidden, self.client.show_image_file,
214 image['id'])
215
216 # Reactivate image
217 self.client.reactivate_image(image['id'])
218 body = self.client.show_image(image['id'])
219 self.assertEqual("active", body['status'])
220
221 # User able to download image after reactivation
222 body = self.client.show_image_file(image['id'])
223 self.assertEqual(content, body.data)
224
Matthew Treinisha62347f2013-03-01 16:37:30 -0500225
zhufl6e042bc2017-01-25 10:33:40 +0800226class ListUserImagesTest(base.BaseV2ImageTest):
227 """Here we test the listing of image information"""
Matthew Treinisha62347f2013-03-01 16:37:30 -0500228
229 @classmethod
Andrea Frittoli69a6b632014-09-15 13:14:53 +0100230 def resource_setup(cls):
zhufl6e042bc2017-01-25 10:33:40 +0800231 super(ListUserImagesTest, cls).resource_setup()
Matthew Treinisha62347f2013-03-01 16:37:30 -0500232 # We add a few images here to test the listing functionality of
233 # the images API
Takashi NATSUME12a48512015-08-10 18:33:16 +0900234 container_fmts = CONF.image.container_formats
235 disk_fmts = CONF.image.disk_formats
236 all_pairs = [(container_fmt, disk_fmt)
237 for container_fmt in container_fmts
238 for disk_fmt in disk_fmts]
239
240 for (container_fmt, disk_fmt) in all_pairs[:6]:
Sergey Vilgelm36fdd202018-11-20 16:10:47 -0600241 LOG.debug("Creating an image "
Takashi NATSUME12a48512015-08-10 18:33:16 +0900242 "(Container format: %s, Disk format: %s).",
243 container_fmt, disk_fmt)
244 cls._create_standard_image(container_fmt, disk_fmt)
Matthew Treinisha62347f2013-03-01 16:37:30 -0500245
246 @classmethod
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700247 def _create_standard_image(cls, container_format, disk_format):
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +0000248 """Create a new standard image and return the newly-registered image-id
249
250 Note that the size of the new image is a random number between
Matthew Treinisha62347f2013-03-01 16:37:30 -0500251 1024 and 4096
252 """
Mark Washenberger5c3b6fe2014-07-29 13:40:34 -0700253 size = random.randint(1024, 4096)
Sirushti Murugesan12dc9732016-07-13 22:49:17 +0530254 image_file = six.BytesIO(data_utils.random_bytes(size))
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700255 tags = [data_utils.rand_name('tag'), data_utils.rand_name('tag')]
zhufl08e42762016-10-18 16:07:56 +0800256 image = cls.create_image(container_format=container_format,
lkuchlanb3348792016-09-29 10:42:21 +0300257 disk_format=disk_format,
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700258 visibility='private',
259 tags=tags)
lkuchlanb3348792016-09-29 10:42:21 +0300260 cls.client.store_image_file(image['id'], data=image_file)
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700261 # Keep the data of one test image so it can be used to filter lists
262 cls.test_data = image
Matthew Treinisha62347f2013-03-01 16:37:30 -0500263
lkuchlanb3348792016-09-29 10:42:21 +0300264 return image['id']
Matthew Treinisha62347f2013-03-01 16:37:30 -0500265
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700266 def _list_by_param_value_and_assert(self, params):
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +0000267 """Perform list action with given params and validates result."""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700268 # Retrieve the list of images that meet the filter
John Warrenf3b3e952015-08-17 19:28:12 +0000269 images_list = self.client.list_images(params=params)['images']
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700270 # Validating params of fetched images
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700271 msg = 'No images were found that met the filter criteria.'
272 self.assertNotEmpty(images_list, msg)
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700273 for image in images_list:
274 for key in params:
275 msg = "Failed to list images by %s" % key
276 self.assertEqual(params[key], image[key], msg)
277
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700278 def _list_sorted_by_image_size_and_assert(self, params, desc=False):
279 """Validate an image list that has been sorted by size
280
281 Perform list action with given params and validates the results are
282 sorted by image size in either ascending or descending order.
283 """
284 # Retrieve the list of images that meet the filter
285 images_list = self.client.list_images(params=params)['images']
286 # Validate that the list was fetched sorted accordingly
287 msg = 'No images were found that met the filter criteria.'
288 self.assertNotEmpty(images_list, msg)
289 sorted_list = [image['size'] for image in images_list]
290 msg = 'The list of images was not sorted correctly.'
291 self.assertEqual(sorted(sorted_list, reverse=desc), sorted_list, msg)
292
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800293 @decorators.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
Flavio Percoco7e26be12015-09-15 22:33:19 +0200294 def test_list_no_params(self):
zhufle68f4352020-04-21 13:44:55 +0800295 """Simple test to see all fixture images returned"""
John Warrenf3b3e952015-08-17 19:28:12 +0000296 images_list = self.client.list_images()['images']
Sirushti Murugesan935f2cc2016-07-12 19:48:24 +0530297 image_list = [image['id'] for image in images_list]
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700298
Matthew Treinisha62347f2013-03-01 16:37:30 -0500299 for image in self.created_images:
Attila Fazekase191cb12013-07-29 06:41:52 +0200300 self.assertIn(image, image_list)
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700301
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800302 @decorators.idempotent_id('9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700303 def test_list_images_param_container_format(self):
zhufle68f4352020-04-21 13:44:55 +0800304 """Test to get all images with a specific container_format"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700305 params = {"container_format": self.test_data['container_format']}
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700306 self._list_by_param_value_and_assert(params)
307
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800308 @decorators.idempotent_id('4a4735a7-f22f-49b6-b0d9-66e1ef7453eb')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700309 def test_list_images_param_disk_format(self):
zhufle68f4352020-04-21 13:44:55 +0800310 """Test to get all images with disk_format = raw"""
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700311 params = {"disk_format": "raw"}
312 self._list_by_param_value_and_assert(params)
313
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800314 @decorators.idempotent_id('7a95bb92-d99e-4b12-9718-7bc6ab73e6d2')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700315 def test_list_images_param_visibility(self):
zhufle68f4352020-04-21 13:44:55 +0800316 """Test to get all images with visibility = private"""
Aaron Rosenc7720622014-05-20 10:38:10 -0700317 params = {"visibility": "private"}
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700318 self._list_by_param_value_and_assert(params)
319
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800320 @decorators.idempotent_id('cf1b9a48-8340-480e-af7b-fe7e17690876')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700321 def test_list_images_param_size(self):
zhufle68f4352020-04-21 13:44:55 +0800322 """Test to get all images by size"""
Takashi NATSUME12a48512015-08-10 18:33:16 +0900323 image_id = self.created_images[0]
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700324 # Get image metadata
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000325 image = self.client.show_image(image_id)
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700326
327 params = {"size": image['size']}
328 self._list_by_param_value_and_assert(params)
329
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800330 @decorators.idempotent_id('4ad8c157-971a-4ba8-aa84-ed61154b1e7f')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700331 def test_list_images_param_min_max_size(self):
zhufle68f4352020-04-21 13:44:55 +0800332 """Test to get all images with min size and max size"""
Takashi NATSUME12a48512015-08-10 18:33:16 +0900333 image_id = self.created_images[0]
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700334 # Get image metadata
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000335 image = self.client.show_image(image_id)
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700336
337 size = image['size']
338 params = {"size_min": size - 500, "size_max": size + 500}
John Warrenf3b3e952015-08-17 19:28:12 +0000339 images_list = self.client.list_images(params=params)['images']
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700340 image_size_list = map(lambda x: x['size'], images_list)
341
342 for image_size in image_size_list:
Béla Vancsics64862f72016-11-08 09:12:31 +0100343 self.assertGreaterEqual(image_size, params['size_min'],
344 "Failed to get images by size_min")
345 self.assertLessEqual(image_size, params['size_max'],
346 "Failed to get images by size_max")
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700347
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800348 @decorators.idempotent_id('7fc9e369-0f58-4d05-9aa5-0969e2d59d15')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700349 def test_list_images_param_status(self):
zhufle68f4352020-04-21 13:44:55 +0800350 """Test to get all active images"""
Anju Tiwarica2249d2014-01-23 17:33:02 +0530351 params = {"status": "active"}
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700352 self._list_by_param_value_and_assert(params)
353
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800354 @decorators.idempotent_id('e914a891-3cc8-4b40-ad32-e0a39ffbddbb')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700355 def test_list_images_param_limit(self):
zhufle68f4352020-04-21 13:44:55 +0800356 """Test to get images by limit"""
Takashi NATSUME12a48512015-08-10 18:33:16 +0900357 params = {"limit": 1}
John Warrenf3b3e952015-08-17 19:28:12 +0000358 images_list = self.client.list_images(params=params)['images']
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700359
360 self.assertEqual(len(images_list), params['limit'],
361 "Failed to get images by limit")
raiesmh08a1ce3542014-03-04 11:58:29 +0530362
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800363 @decorators.idempotent_id('e9a44b91-31c8-4b40-a332-e0a39ffb4dbb')
Li Wei14bf2412016-09-25 15:56:23 +0800364 def test_list_image_param_owner(self):
zhufle68f4352020-04-21 13:44:55 +0800365 """Test to get images by owner"""
Li Wei14bf2412016-09-25 15:56:23 +0800366 image_id = self.created_images[0]
367 # Get image metadata
368 image = self.client.show_image(image_id)
369
370 params = {"owner": image['owner']}
371 self._list_by_param_value_and_assert(params)
372
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800373 @decorators.idempotent_id('55c8f5f5-bfed-409d-a6d5-4caeda985d7b')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700374 def test_list_images_param_name(self):
zhufle68f4352020-04-21 13:44:55 +0800375 """Test to get images by name"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700376 params = {'name': self.test_data['name']}
377 self._list_by_param_value_and_assert(params)
378
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800379 @decorators.idempotent_id('aa8ac4df-cff9-418b-8d0f-dd9c67b072c9')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700380 def test_list_images_param_tag(self):
zhufle68f4352020-04-21 13:44:55 +0800381 """Test to get images matching a tag"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700382 params = {'tag': self.test_data['tags'][0]}
383 images_list = self.client.list_images(params=params)['images']
384 # Validating properties of fetched images
385 self.assertNotEmpty(images_list)
386 for image in images_list:
387 msg = ("The image {image_name} does not have the expected tag "
388 "{expected_tag} among its tags: {observerd_tags}."
389 .format(image_name=image['name'],
390 expected_tag=self.test_data['tags'][0],
391 observerd_tags=image['tags']))
392 self.assertIn(self.test_data['tags'][0], image['tags'], msg)
393
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800394 @decorators.idempotent_id('eeadce49-04e0-43b7-aec7-52535d903e7a')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700395 def test_list_images_param_sort(self):
zhufle68f4352020-04-21 13:44:55 +0800396 """Test listing images sorting in descending order"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700397 params = {'sort': 'size:desc'}
398 self._list_sorted_by_image_size_and_assert(params, desc=True)
399
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800400 @decorators.idempotent_id('9faaa0c2-c3a5-43e1-8f61-61c54b409a49')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700401 def test_list_images_param_sort_key_dir(self):
zhufle68f4352020-04-21 13:44:55 +0800402 """Test listing images sorting by size in descending order"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700403 params = {'sort_key': 'size', 'sort_dir': 'desc'}
404 self._list_sorted_by_image_size_and_assert(params, desc=True)
405
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800406 @decorators.idempotent_id('622b925c-479f-4736-860d-adeaf13bc371')
raiesmh08a1ce3542014-03-04 11:58:29 +0530407 def test_get_image_schema(self):
zhufle68f4352020-04-21 13:44:55 +0800408 """Test to get image schema"""
raiesmh08a1ce3542014-03-04 11:58:29 +0530409 schema = "image"
Ken'ichi Ohmichi190b24e2016-06-07 23:20:09 +0900410 body = self.schemas_client.show_schema(schema)
raiesmh08a1ce3542014-03-04 11:58:29 +0530411 self.assertEqual("image", body['name'])
412
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800413 @decorators.idempotent_id('25c8d7b2-df21-460f-87ac-93130bcdc684')
raiesmh08a1ce3542014-03-04 11:58:29 +0530414 def test_get_images_schema(self):
zhufle68f4352020-04-21 13:44:55 +0800415 """Test to get images schema"""
raiesmh08a1ce3542014-03-04 11:58:29 +0530416 schema = "images"
Ken'ichi Ohmichi190b24e2016-06-07 23:20:09 +0900417 body = self.schemas_client.show_schema(schema)
raiesmh08a1ce3542014-03-04 11:58:29 +0530418 self.assertEqual("images", body['name'])
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700419
420
zhufl6e042bc2017-01-25 10:33:40 +0800421class ListSharedImagesTest(base.BaseV2ImageTest):
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700422 """Here we test the listing of a shared image information"""
423
424 credentials = ['primary', 'alt']
425
426 @classmethod
427 def setup_clients(cls):
428 super(ListSharedImagesTest, cls).setup_clients()
Jordan Pittier8160d312017-04-18 11:52:23 +0200429 cls.image_member_client = cls.os_primary.image_member_client_v2
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700430 cls.alt_img_client = cls.os_alt.image_client_v2
431
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800432 @decorators.idempotent_id('3fa50be4-8e38-4c02-a8db-7811bb780122')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700433 def test_list_images_param_member_status(self):
zhufle68f4352020-04-21 13:44:55 +0800434 """Test listing images by member_status and visibility"""
Steve Lewis8ac5b972016-12-22 07:41:29 -0800435 # Create an image to be shared using default visibility
436 image_file = six.BytesIO(data_utils.random_bytes(2048))
437 container_format = CONF.image.container_formats[0]
438 disk_format = CONF.image.disk_formats[0]
439 image = self.create_image(container_format=container_format,
440 disk_format=disk_format)
441 self.client.store_image_file(image['id'], data=image_file)
442
443 # Share the image created with the alt user
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700444 self.image_member_client.create_image_member(
Steve Lewis8ac5b972016-12-22 07:41:29 -0800445 image_id=image['id'], member=self.alt_img_client.tenant_id)
446
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700447 # As an image consumer you need to provide the member_status parameter
448 # along with the visibility=shared parameter in order for it to show
449 # results
450 params = {'member_status': 'pending', 'visibility': 'shared'}
451 fetched_images = self.alt_img_client.list_images(params)['images']
452 self.assertEqual(1, len(fetched_images))
Steve Lewis8ac5b972016-12-22 07:41:29 -0800453 self.assertEqual(image['id'], fetched_images[0]['id'])