blob: c1a7211ae43da19be571282a0a735741f660918d [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
Ghanshyam Mann1425ecd2020-07-22 21:01:26 -050043 @classmethod
44 def resource_setup(cls):
45 super(ImportImagesTest, cls).resource_setup()
46 cls.available_import_methods = cls.client.info_import()[
47 'import-methods']['value']
48 if not cls.available_import_methods:
49 raise cls.skipException('Server does not support '
50 'any import method')
Abhishek Kekane7cff1302020-07-16 10:30:13 +000051
Ghanshyam Mann1425ecd2020-07-22 21:01:26 -050052 def _create_image(self):
Abhishek Kekane7cff1302020-07-16 10:30:13 +000053 # Create image
54 uuid = '00000000-1111-2222-3333-444455556666'
55 image_name = data_utils.rand_name('image')
56 container_format = CONF.image.container_formats[0]
57 disk_format = CONF.image.disk_formats[0]
58 image = self.create_image(name=image_name,
59 container_format=container_format,
60 disk_format=disk_format,
61 visibility='private',
62 ramdisk_id=uuid)
63 self.assertIn('name', image)
64 self.assertEqual(image_name, image['name'])
65 self.assertIn('visibility', image)
66 self.assertEqual('private', image['visibility'])
67 self.assertIn('status', image)
68 self.assertEqual('queued', image['status'])
Ghanshyam Mann1425ecd2020-07-22 21:01:26 -050069 return image
Abhishek Kekane7cff1302020-07-16 10:30:13 +000070
Ghanshyam Mann1425ecd2020-07-22 21:01:26 -050071 @decorators.idempotent_id('32ca0c20-e16f-44ac-8590-07869c9b4cc2')
72 def test_image_glance_direct_import(self):
73 """Test 'glance-direct' import functionalities
74
75 Create image, stage image data, import image and verify
76 that import succeeded.
77 """
78 if 'glance-direct' not in self.available_import_methods:
79 raise self.skipException('Server does not support '
80 'glance-direct import method')
81 image = self._create_image()
Abhishek Kekane7cff1302020-07-16 10:30:13 +000082 # Stage image data
83 file_content = data_utils.random_bytes()
84 image_file = six.BytesIO(file_content)
85 self.client.stage_image_file(image['id'], image_file)
Ghanshyam Mann1425ecd2020-07-22 21:01:26 -050086 # Check image status is 'uploading'
87 body = self.client.show_image(image['id'])
88 self.assertEqual(image['id'], body['id'])
89 self.assertEqual('uploading', body['status'])
90 # import image from staging to backend
91 self.client.image_import(image['id'], method='glance-direct')
92 self.client.wait_for_resource_activation(image['id'])
Abhishek Kekane7cff1302020-07-16 10:30:13 +000093
Ghanshyam Mann1425ecd2020-07-22 21:01:26 -050094 @decorators.idempotent_id('f6feb7a4-b04f-4706-a011-206129f83e62')
95 def test_image_web_download_import(self):
96 """Test 'web-download' import functionalities
97
98 Create image, import image and verify that import
99 succeeded.
100 """
101 if 'web-download' not in self.available_import_methods:
102 raise self.skipException('Server does not support '
103 'web-download import method')
104 image = self._create_image()
Abhishek Kekane7cff1302020-07-16 10:30:13 +0000105 # Now try to get image details
106 body = self.client.show_image(image['id'])
107 self.assertEqual(image['id'], body['id'])
Ghanshyam Mann1425ecd2020-07-22 21:01:26 -0500108 self.assertEqual('queued', body['status'])
109 # import image from web to backend
110 image_uri = CONF.image.http_image
111 self.client.image_import(image['id'], method='web-download',
112 image_uri=image_uri)
Abhishek Kekane7cff1302020-07-16 10:30:13 +0000113 self.client.wait_for_resource_activation(image['id'])
114
115
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530116class BasicOperationsImagesTest(base.BaseV2ImageTest):
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +0000117 """Here we test the basic operations of images"""
Matthew Treinisha62347f2013-03-01 16:37:30 -0500118
Jordan Pittier3b46d272017-04-12 16:17:28 +0200119 @decorators.attr(type='smoke')
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800120 @decorators.idempotent_id('139b765e-7f3d-4b3d-8b37-3ca3876ee318')
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530121 def test_register_upload_get_image_file(self):
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +0000122 """Here we test these functionalities
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530123
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +0000124 Register image, upload the image file, get image and get image
125 file api's
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530126 """
127
Sean Daguec6ec4762014-05-29 08:54:21 -0400128 uuid = '00000000-1111-2222-3333-444455556666'
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530129 image_name = data_utils.rand_name('image')
Takashi NATSUME12a48512015-08-10 18:33:16 +0900130 container_format = CONF.image.container_formats[0]
131 disk_format = CONF.image.disk_formats[0]
lkuchlanb3348792016-09-29 10:42:21 +0300132 image = self.create_image(name=image_name,
133 container_format=container_format,
134 disk_format=disk_format,
135 visibility='private',
136 ramdisk_id=uuid)
lkuchlanb3348792016-09-29 10:42:21 +0300137 self.assertIn('name', image)
138 self.assertEqual(image_name, image['name'])
139 self.assertIn('visibility', image)
140 self.assertEqual('private', image['visibility'])
141 self.assertIn('status', image)
142 self.assertEqual('queued', image['status'])
Matthew Treinisha62347f2013-03-01 16:37:30 -0500143
wangxiyuan99e4dcf2019-09-17 09:51:55 +0800144 # NOTE: This Glance API returns different status codes for image
145 # condition. In this empty data case, Glance should return 204,
146 # so here should check the status code.
147 image_file = self.client.show_image_file(image['id'])
148 self.assertEqual(0, len(image_file.data))
149 self.assertEqual(204, image_file.response.status)
150
Matthew Treinisha62347f2013-03-01 16:37:30 -0500151 # Now try uploading an image file
Mark Washenberger5c3b6fe2014-07-29 13:40:34 -0700152 file_content = data_utils.random_bytes()
Sirushti Murugesan12dc9732016-07-13 22:49:17 +0530153 image_file = six.BytesIO(file_content)
lkuchlanb3348792016-09-29 10:42:21 +0300154 self.client.store_image_file(image['id'], image_file)
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530155
156 # Now try to get image details
lkuchlanb3348792016-09-29 10:42:21 +0300157 body = self.client.show_image(image['id'])
158 self.assertEqual(image['id'], body['id'])
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530159 self.assertEqual(image_name, body['name'])
Sean Daguec6ec4762014-05-29 08:54:21 -0400160 self.assertEqual(uuid, body['ramdisk_id'])
Attila Fazekase191cb12013-07-29 06:41:52 +0200161 self.assertIn('size', body)
Matthew Treinisha62347f2013-03-01 16:37:30 -0500162 self.assertEqual(1024, body.get('size'))
163
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530164 # Now try get image file
Ken'ichi Ohmichi3b79f172018-03-20 11:31:44 -0700165 # NOTE: This Glance API returns different status codes for image
166 # condition. In this non-empty data case, Glance should return 200,
167 # so here should check the status code.
lkuchlanb3348792016-09-29 10:42:21 +0300168 body = self.client.show_image_file(image['id'])
David Kranzd7e97b42015-02-16 09:37:31 -0500169 self.assertEqual(file_content, body.data)
Ken'ichi Ohmichi3b79f172018-03-20 11:31:44 -0700170 self.assertEqual(200, body.response.status)
Hoisaleshwara Madan V Se50a6f12013-10-23 18:01:01 +0530171
Jordan Pittier3b46d272017-04-12 16:17:28 +0200172 @decorators.attr(type='smoke')
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800173 @decorators.idempotent_id('f848bb94-1c6e-45a4-8726-39e3a5b23535')
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530174 def test_delete_image(self):
zhufle68f4352020-04-21 13:44:55 +0800175 """Test deleting an image by image_id"""
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530176 # Create image
177 image_name = data_utils.rand_name('image')
Takashi NATSUME12a48512015-08-10 18:33:16 +0900178 container_format = CONF.image.container_formats[0]
179 disk_format = CONF.image.disk_formats[0]
Benny Kopilov900fceb2016-11-09 09:45:40 +0200180 image = self.create_image(name=image_name,
181 container_format=container_format,
182 disk_format=disk_format,
183 visibility='private')
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530184 # Delete Image
lkuchlanb3348792016-09-29 10:42:21 +0300185 self.client.delete_image(image['id'])
186 self.client.wait_for_resource_deletion(image['id'])
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530187
188 # Verifying deletion
John Warrenf3b3e952015-08-17 19:28:12 +0000189 images = self.client.list_images()['images']
Sunil G29856a32014-07-17 23:17:58 +0530190 images_id = [item['id'] for item in images]
lkuchlanb3348792016-09-29 10:42:21 +0300191 self.assertNotIn(image['id'], images_id)
Hoisaleshwara Madan V S7cba1082013-11-26 12:43:04 +0530192
Jordan Pittier3b46d272017-04-12 16:17:28 +0200193 @decorators.attr(type='smoke')
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800194 @decorators.idempotent_id('f66891a7-a35c-41a8-b590-a065c2a1caa6')
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400195 def test_update_image(self):
zhufle68f4352020-04-21 13:44:55 +0800196 """Test updating an image by image_id"""
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400197 # Create image
198 image_name = data_utils.rand_name('image')
Takashi NATSUME12a48512015-08-10 18:33:16 +0900199 container_format = CONF.image.container_formats[0]
200 disk_format = CONF.image.disk_formats[0]
Benny Kopilov900fceb2016-11-09 09:45:40 +0200201 image = self.create_image(name=image_name,
202 container_format=container_format,
203 disk_format=disk_format,
204 visibility='private')
lkuchlanb3348792016-09-29 10:42:21 +0300205 self.assertEqual('queued', image['status'])
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400206
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400207 # Update Image
208 new_image_name = data_utils.rand_name('new-image')
zhufl311104e2017-08-17 15:13:18 +0800209 self.client.update_image(image['id'], [
Aaron Rosenc7720622014-05-20 10:38:10 -0700210 dict(replace='/name', value=new_image_name)])
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400211
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400212 # Verifying updating
213
lkuchlanb3348792016-09-29 10:42:21 +0300214 body = self.client.show_image(image['id'])
215 self.assertEqual(image['id'], body['id'])
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400216 self.assertEqual(new_image_name, body['name'])
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400217
lkuchlan32b53c32017-04-20 16:51:08 +0300218 @decorators.idempotent_id('951ebe01-969f-4ea9-9898-8a3f1f442ab0')
219 def test_deactivate_reactivate_image(self):
zhufle68f4352020-04-21 13:44:55 +0800220 """Test deactivating and reactivating an image"""
lkuchlan32b53c32017-04-20 16:51:08 +0300221 # Create image
222 image_name = data_utils.rand_name('image')
223 image = self.create_image(name=image_name,
224 container_format='bare',
225 disk_format='raw',
226 visibility='private')
227
228 # Upload an image file
229 content = data_utils.random_bytes()
230 image_file = six.BytesIO(content)
231 self.client.store_image_file(image['id'], image_file)
232
233 # Deactivate image
234 self.client.deactivate_image(image['id'])
235 body = self.client.show_image(image['id'])
236 self.assertEqual("deactivated", body['status'])
237
238 # User unable to download deactivated image
239 self.assertRaises(lib_exc.Forbidden, self.client.show_image_file,
240 image['id'])
241
242 # Reactivate image
243 self.client.reactivate_image(image['id'])
244 body = self.client.show_image(image['id'])
245 self.assertEqual("active", body['status'])
246
247 # User able to download image after reactivation
248 body = self.client.show_image_file(image['id'])
249 self.assertEqual(content, body.data)
250
Matthew Treinisha62347f2013-03-01 16:37:30 -0500251
zhufl6e042bc2017-01-25 10:33:40 +0800252class ListUserImagesTest(base.BaseV2ImageTest):
253 """Here we test the listing of image information"""
Matthew Treinisha62347f2013-03-01 16:37:30 -0500254
255 @classmethod
Andrea Frittoli69a6b632014-09-15 13:14:53 +0100256 def resource_setup(cls):
zhufl6e042bc2017-01-25 10:33:40 +0800257 super(ListUserImagesTest, cls).resource_setup()
Matthew Treinisha62347f2013-03-01 16:37:30 -0500258 # We add a few images here to test the listing functionality of
259 # the images API
Takashi NATSUME12a48512015-08-10 18:33:16 +0900260 container_fmts = CONF.image.container_formats
261 disk_fmts = CONF.image.disk_formats
262 all_pairs = [(container_fmt, disk_fmt)
263 for container_fmt in container_fmts
264 for disk_fmt in disk_fmts]
265
266 for (container_fmt, disk_fmt) in all_pairs[:6]:
Sergey Vilgelm36fdd202018-11-20 16:10:47 -0600267 LOG.debug("Creating an image "
Takashi NATSUME12a48512015-08-10 18:33:16 +0900268 "(Container format: %s, Disk format: %s).",
269 container_fmt, disk_fmt)
270 cls._create_standard_image(container_fmt, disk_fmt)
Matthew Treinisha62347f2013-03-01 16:37:30 -0500271
272 @classmethod
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700273 def _create_standard_image(cls, container_format, disk_format):
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +0000274 """Create a new standard image and return the newly-registered image-id
275
276 Note that the size of the new image is a random number between
Matthew Treinisha62347f2013-03-01 16:37:30 -0500277 1024 and 4096
278 """
Mark Washenberger5c3b6fe2014-07-29 13:40:34 -0700279 size = random.randint(1024, 4096)
Sirushti Murugesan12dc9732016-07-13 22:49:17 +0530280 image_file = six.BytesIO(data_utils.random_bytes(size))
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700281 tags = [data_utils.rand_name('tag'), data_utils.rand_name('tag')]
zhufl08e42762016-10-18 16:07:56 +0800282 image = cls.create_image(container_format=container_format,
lkuchlanb3348792016-09-29 10:42:21 +0300283 disk_format=disk_format,
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700284 visibility='private',
285 tags=tags)
lkuchlanb3348792016-09-29 10:42:21 +0300286 cls.client.store_image_file(image['id'], data=image_file)
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700287 # Keep the data of one test image so it can be used to filter lists
288 cls.test_data = image
Matthew Treinisha62347f2013-03-01 16:37:30 -0500289
lkuchlanb3348792016-09-29 10:42:21 +0300290 return image['id']
Matthew Treinisha62347f2013-03-01 16:37:30 -0500291
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700292 def _list_by_param_value_and_assert(self, params):
Ken'ichi Ohmichi9e3dac02015-11-19 07:01:07 +0000293 """Perform list action with given params and validates result."""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700294 # Retrieve the list of images that meet the filter
John Warrenf3b3e952015-08-17 19:28:12 +0000295 images_list = self.client.list_images(params=params)['images']
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700296 # Validating params of fetched images
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700297 msg = 'No images were found that met the filter criteria.'
298 self.assertNotEmpty(images_list, msg)
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700299 for image in images_list:
300 for key in params:
301 msg = "Failed to list images by %s" % key
302 self.assertEqual(params[key], image[key], msg)
303
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700304 def _list_sorted_by_image_size_and_assert(self, params, desc=False):
305 """Validate an image list that has been sorted by size
306
307 Perform list action with given params and validates the results are
308 sorted by image size in either ascending or descending order.
309 """
310 # Retrieve the list of images that meet the filter
311 images_list = self.client.list_images(params=params)['images']
312 # Validate that the list was fetched sorted accordingly
313 msg = 'No images were found that met the filter criteria.'
314 self.assertNotEmpty(images_list, msg)
315 sorted_list = [image['size'] for image in images_list]
316 msg = 'The list of images was not sorted correctly.'
317 self.assertEqual(sorted(sorted_list, reverse=desc), sorted_list, msg)
318
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800319 @decorators.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
Flavio Percoco7e26be12015-09-15 22:33:19 +0200320 def test_list_no_params(self):
zhufle68f4352020-04-21 13:44:55 +0800321 """Simple test to see all fixture images returned"""
John Warrenf3b3e952015-08-17 19:28:12 +0000322 images_list = self.client.list_images()['images']
Sirushti Murugesan935f2cc2016-07-12 19:48:24 +0530323 image_list = [image['id'] for image in images_list]
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700324
Matthew Treinisha62347f2013-03-01 16:37:30 -0500325 for image in self.created_images:
Attila Fazekase191cb12013-07-29 06:41:52 +0200326 self.assertIn(image, image_list)
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700327
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800328 @decorators.idempotent_id('9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700329 def test_list_images_param_container_format(self):
zhufle68f4352020-04-21 13:44:55 +0800330 """Test to get all images with a specific container_format"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700331 params = {"container_format": self.test_data['container_format']}
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700332 self._list_by_param_value_and_assert(params)
333
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800334 @decorators.idempotent_id('4a4735a7-f22f-49b6-b0d9-66e1ef7453eb')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700335 def test_list_images_param_disk_format(self):
zhufle68f4352020-04-21 13:44:55 +0800336 """Test to get all images with disk_format = raw"""
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700337 params = {"disk_format": "raw"}
338 self._list_by_param_value_and_assert(params)
339
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800340 @decorators.idempotent_id('7a95bb92-d99e-4b12-9718-7bc6ab73e6d2')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700341 def test_list_images_param_visibility(self):
zhufle68f4352020-04-21 13:44:55 +0800342 """Test to get all images with visibility = private"""
Aaron Rosenc7720622014-05-20 10:38:10 -0700343 params = {"visibility": "private"}
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700344 self._list_by_param_value_and_assert(params)
345
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800346 @decorators.idempotent_id('cf1b9a48-8340-480e-af7b-fe7e17690876')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700347 def test_list_images_param_size(self):
zhufle68f4352020-04-21 13:44:55 +0800348 """Test to get all images by size"""
Takashi NATSUME12a48512015-08-10 18:33:16 +0900349 image_id = self.created_images[0]
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700350 # Get image metadata
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000351 image = self.client.show_image(image_id)
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700352
353 params = {"size": image['size']}
354 self._list_by_param_value_and_assert(params)
355
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800356 @decorators.idempotent_id('4ad8c157-971a-4ba8-aa84-ed61154b1e7f')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700357 def test_list_images_param_min_max_size(self):
zhufle68f4352020-04-21 13:44:55 +0800358 """Test to get all images with min size and max size"""
Takashi NATSUME12a48512015-08-10 18:33:16 +0900359 image_id = self.created_images[0]
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700360 # Get image metadata
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000361 image = self.client.show_image(image_id)
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700362
363 size = image['size']
364 params = {"size_min": size - 500, "size_max": size + 500}
John Warrenf3b3e952015-08-17 19:28:12 +0000365 images_list = self.client.list_images(params=params)['images']
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700366 image_size_list = map(lambda x: x['size'], images_list)
367
368 for image_size in image_size_list:
Béla Vancsics64862f72016-11-08 09:12:31 +0100369 self.assertGreaterEqual(image_size, params['size_min'],
370 "Failed to get images by size_min")
371 self.assertLessEqual(image_size, params['size_max'],
372 "Failed to get images by size_max")
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700373
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800374 @decorators.idempotent_id('7fc9e369-0f58-4d05-9aa5-0969e2d59d15')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700375 def test_list_images_param_status(self):
zhufle68f4352020-04-21 13:44:55 +0800376 """Test to get all active images"""
Anju Tiwarica2249d2014-01-23 17:33:02 +0530377 params = {"status": "active"}
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700378 self._list_by_param_value_and_assert(params)
379
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800380 @decorators.idempotent_id('e914a891-3cc8-4b40-ad32-e0a39ffbddbb')
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700381 def test_list_images_param_limit(self):
zhufle68f4352020-04-21 13:44:55 +0800382 """Test to get images by limit"""
Takashi NATSUME12a48512015-08-10 18:33:16 +0900383 params = {"limit": 1}
John Warrenf3b3e952015-08-17 19:28:12 +0000384 images_list = self.client.list_images(params=params)['images']
Abhijeet Malawadef268d8e2013-09-17 06:20:23 -0700385
386 self.assertEqual(len(images_list), params['limit'],
387 "Failed to get images by limit")
raiesmh08a1ce3542014-03-04 11:58:29 +0530388
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800389 @decorators.idempotent_id('e9a44b91-31c8-4b40-a332-e0a39ffb4dbb')
Li Wei14bf2412016-09-25 15:56:23 +0800390 def test_list_image_param_owner(self):
zhufle68f4352020-04-21 13:44:55 +0800391 """Test to get images by owner"""
Li Wei14bf2412016-09-25 15:56:23 +0800392 image_id = self.created_images[0]
393 # Get image metadata
394 image = self.client.show_image(image_id)
395
396 params = {"owner": image['owner']}
397 self._list_by_param_value_and_assert(params)
398
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800399 @decorators.idempotent_id('55c8f5f5-bfed-409d-a6d5-4caeda985d7b')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700400 def test_list_images_param_name(self):
zhufle68f4352020-04-21 13:44:55 +0800401 """Test to get images by name"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700402 params = {'name': self.test_data['name']}
403 self._list_by_param_value_and_assert(params)
404
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800405 @decorators.idempotent_id('aa8ac4df-cff9-418b-8d0f-dd9c67b072c9')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700406 def test_list_images_param_tag(self):
zhufle68f4352020-04-21 13:44:55 +0800407 """Test to get images matching a tag"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700408 params = {'tag': self.test_data['tags'][0]}
409 images_list = self.client.list_images(params=params)['images']
410 # Validating properties of fetched images
411 self.assertNotEmpty(images_list)
412 for image in images_list:
413 msg = ("The image {image_name} does not have the expected tag "
414 "{expected_tag} among its tags: {observerd_tags}."
415 .format(image_name=image['name'],
416 expected_tag=self.test_data['tags'][0],
417 observerd_tags=image['tags']))
418 self.assertIn(self.test_data['tags'][0], image['tags'], msg)
419
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800420 @decorators.idempotent_id('eeadce49-04e0-43b7-aec7-52535d903e7a')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700421 def test_list_images_param_sort(self):
zhufle68f4352020-04-21 13:44:55 +0800422 """Test listing images sorting in descending order"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700423 params = {'sort': 'size:desc'}
424 self._list_sorted_by_image_size_and_assert(params, desc=True)
425
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800426 @decorators.idempotent_id('9faaa0c2-c3a5-43e1-8f61-61c54b409a49')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700427 def test_list_images_param_sort_key_dir(self):
zhufle68f4352020-04-21 13:44:55 +0800428 """Test listing images sorting by size in descending order"""
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700429 params = {'sort_key': 'size', 'sort_dir': 'desc'}
430 self._list_sorted_by_image_size_and_assert(params, desc=True)
431
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800432 @decorators.idempotent_id('622b925c-479f-4736-860d-adeaf13bc371')
raiesmh08a1ce3542014-03-04 11:58:29 +0530433 def test_get_image_schema(self):
zhufle68f4352020-04-21 13:44:55 +0800434 """Test to get image schema"""
raiesmh08a1ce3542014-03-04 11:58:29 +0530435 schema = "image"
Ken'ichi Ohmichi190b24e2016-06-07 23:20:09 +0900436 body = self.schemas_client.show_schema(schema)
raiesmh08a1ce3542014-03-04 11:58:29 +0530437 self.assertEqual("image", body['name'])
438
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800439 @decorators.idempotent_id('25c8d7b2-df21-460f-87ac-93130bcdc684')
raiesmh08a1ce3542014-03-04 11:58:29 +0530440 def test_get_images_schema(self):
zhufle68f4352020-04-21 13:44:55 +0800441 """Test to get images schema"""
raiesmh08a1ce3542014-03-04 11:58:29 +0530442 schema = "images"
Ken'ichi Ohmichi190b24e2016-06-07 23:20:09 +0900443 body = self.schemas_client.show_schema(schema)
raiesmh08a1ce3542014-03-04 11:58:29 +0530444 self.assertEqual("images", body['name'])
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700445
446
zhufl6e042bc2017-01-25 10:33:40 +0800447class ListSharedImagesTest(base.BaseV2ImageTest):
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700448 """Here we test the listing of a shared image information"""
449
450 credentials = ['primary', 'alt']
451
452 @classmethod
453 def setup_clients(cls):
454 super(ListSharedImagesTest, cls).setup_clients()
Jordan Pittier8160d312017-04-18 11:52:23 +0200455 cls.image_member_client = cls.os_primary.image_member_client_v2
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700456 cls.alt_img_client = cls.os_alt.image_client_v2
457
Ken'ichi Ohmichif35efa22017-01-27 17:55:24 -0800458 @decorators.idempotent_id('3fa50be4-8e38-4c02-a8db-7811bb780122')
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700459 def test_list_images_param_member_status(self):
zhufle68f4352020-04-21 13:44:55 +0800460 """Test listing images by member_status and visibility"""
Steve Lewis8ac5b972016-12-22 07:41:29 -0800461 # Create an image to be shared using default visibility
462 image_file = six.BytesIO(data_utils.random_bytes(2048))
463 container_format = CONF.image.container_formats[0]
464 disk_format = CONF.image.disk_formats[0]
465 image = self.create_image(container_format=container_format,
466 disk_format=disk_format)
467 self.client.store_image_file(image['id'], data=image_file)
468
469 # Share the image created with the alt user
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700470 self.image_member_client.create_image_member(
Steve Lewis8ac5b972016-12-22 07:41:29 -0800471 image_id=image['id'], member=self.alt_img_client.tenant_id)
472
Castulo J. Martineze9c8ce82016-05-16 07:55:53 -0700473 # As an image consumer you need to provide the member_status parameter
474 # along with the visibility=shared parameter in order for it to show
475 # results
476 params = {'member_status': 'pending', 'visibility': 'shared'}
477 fetched_images = self.alt_img_client.list_images(params)['images']
478 self.assertEqual(1, len(fetched_images))
Steve Lewis8ac5b972016-12-22 07:41:29 -0800479 self.assertEqual(image['id'], fetched_images[0]['id'])