blob: 8beed3224e19f435e214a3d38482833168d5d964 [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Jay Pipes50677282012-01-06 15:39:20 -05002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Matthew Treinishb0c65f22015-04-23 09:09:41 -040016from six import moves
Matthew Treinish01472ff2015-02-20 17:26:52 -050017
Sean Dague1937d092013-05-17 16:36:38 -040018from tempest.api.image import base
Fei Long Wangd39431f2015-05-14 11:30:48 +120019from tempest.common.utils import data_utils
Matthew Treinishbc0e03e2014-01-30 16:51:06 +000020from tempest import config
ivan-zhud1bbe5d2013-12-29 18:32:46 +080021from tempest import test
Jay Pipes50677282012-01-06 15:39:20 -050022
Matthew Treinishbc0e03e2014-01-30 16:51:06 +000023CONF = config.CONF
24
Jay Pipes50677282012-01-06 15:39:20 -050025
Matthew Treinishce3ef922013-03-11 14:02:46 -040026class CreateRegisterImagesTest(base.BaseV1ImageTest):
27 """Here we test the registration and creation of images."""
Jay Pipes50677282012-01-06 15:39:20 -050028
Chris Hoge7579c1a2015-02-26 14:12:15 -080029 @test.idempotent_id('3027f8e6-3492-4a11-8575-c3293017af4d')
Jay Pipes50677282012-01-06 15:39:20 -050030 def test_register_then_upload(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -050031 # Register, then upload an image
Matthew Treinish72ea4422013-02-07 14:42:49 -050032 properties = {'prop1': 'val1'}
David Kranz34f18782015-01-06 13:43:55 -050033 body = self.create_image(name='New Name',
34 container_format='bare',
35 disk_format='raw',
36 is_public=False,
37 properties=properties)
Attila Fazekase191cb12013-07-29 06:41:52 +020038 self.assertIn('id', body)
Matthew Treinish72ea4422013-02-07 14:42:49 -050039 image_id = body.get('id')
Matthew Treinish72ea4422013-02-07 14:42:49 -050040 self.assertEqual('New Name', body.get('name'))
Aaron Rosenc7720622014-05-20 10:38:10 -070041 self.assertFalse(body.get('is_public'))
Matthew Treinish72ea4422013-02-07 14:42:49 -050042 self.assertEqual('queued', body.get('status'))
Matthew Treinish72ea4422013-02-07 14:42:49 -050043 for key, val in properties.items():
44 self.assertEqual(val, body.get('properties')[key])
Jay Pipes50677282012-01-06 15:39:20 -050045
46 # Now try uploading an image file
Matthew Treinishb0c65f22015-04-23 09:09:41 -040047 image_file = moves.cStringIO(data_utils.random_bytes())
David Kranz34f18782015-01-06 13:43:55 -050048 body = self.client.update_image(image_id, data=image_file)
Attila Fazekase191cb12013-07-29 06:41:52 +020049 self.assertIn('size', body)
Matthew Treinish72ea4422013-02-07 14:42:49 -050050 self.assertEqual(1024, body.get('size'))
Jay Pipes50677282012-01-06 15:39:20 -050051
Chris Hoge7579c1a2015-02-26 14:12:15 -080052 @test.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
Jay Pipes50677282012-01-06 15:39:20 -050053 def test_register_remote_image(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -050054 # Register a new remote image
David Kranz34f18782015-01-06 13:43:55 -050055 body = self.create_image(name='New Remote Image',
56 container_format='bare',
57 disk_format='raw', is_public=False,
58 location=CONF.image.http_image,
59 properties={'key1': 'value1',
60 'key2': 'value2'})
Attila Fazekase191cb12013-07-29 06:41:52 +020061 self.assertIn('id', body)
Matthew Treinish72ea4422013-02-07 14:42:49 -050062 self.assertEqual('New Remote Image', body.get('name'))
Aaron Rosenc7720622014-05-20 10:38:10 -070063 self.assertFalse(body.get('is_public'))
Matthew Treinish72ea4422013-02-07 14:42:49 -050064 self.assertEqual('active', body.get('status'))
afazekas4a96bf82013-03-25 16:07:38 +010065 properties = body.get('properties')
66 self.assertEqual(properties['key1'], 'value1')
67 self.assertEqual(properties['key2'], 'value2')
Jay Pipes50677282012-01-06 15:39:20 -050068
Chris Hoge7579c1a2015-02-26 14:12:15 -080069 @test.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
Attila Fazekase72b7cd2013-03-26 18:34:21 +010070 def test_register_http_image(self):
David Kranz34f18782015-01-06 13:43:55 -050071 body = self.create_image(name='New Http Image',
72 container_format='bare',
73 disk_format='raw', is_public=False,
74 copy_from=CONF.image.http_image)
Attila Fazekase191cb12013-07-29 06:41:52 +020075 self.assertIn('id', body)
Attila Fazekase72b7cd2013-03-26 18:34:21 +010076 image_id = body.get('id')
Attila Fazekase72b7cd2013-03-26 18:34:21 +010077 self.assertEqual('New Http Image', body.get('name'))
Aaron Rosenc7720622014-05-20 10:38:10 -070078 self.assertFalse(body.get('is_public'))
Attila Fazekase72b7cd2013-03-26 18:34:21 +010079 self.client.wait_for_image_status(image_id, 'active')
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +000080 self.client.show_image(image_id)
Attila Fazekase72b7cd2013-03-26 18:34:21 +010081
Chris Hoge7579c1a2015-02-26 14:12:15 -080082 @test.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
hi2suresh75a20302013-04-09 09:17:06 +000083 def test_register_image_with_min_ram(self):
84 # Register an image with min ram
85 properties = {'prop1': 'val1'}
David Kranz34f18782015-01-06 13:43:55 -050086 body = self.create_image(name='New_image_with_min_ram',
87 container_format='bare',
88 disk_format='raw',
89 is_public=False,
90 min_ram=40,
91 properties=properties)
Attila Fazekase191cb12013-07-29 06:41:52 +020092 self.assertIn('id', body)
hi2suresh75a20302013-04-09 09:17:06 +000093 self.assertEqual('New_image_with_min_ram', body.get('name'))
Aaron Rosenc7720622014-05-20 10:38:10 -070094 self.assertFalse(body.get('is_public'))
hi2suresh75a20302013-04-09 09:17:06 +000095 self.assertEqual('queued', body.get('status'))
96 self.assertEqual(40, body.get('min_ram'))
97 for key, val in properties.items():
98 self.assertEqual(val, body.get('properties')[key])
David Kranz9c3b3b62014-06-19 16:05:53 -040099 self.client.delete_image(body['id'])
hi2suresh75a20302013-04-09 09:17:06 +0000100
Jay Pipes50677282012-01-06 15:39:20 -0500101
Matthew Treinishce3ef922013-03-11 14:02:46 -0400102class ListImagesTest(base.BaseV1ImageTest):
Jay Pipes50677282012-01-06 15:39:20 -0500103
104 """
105 Here we test the listing of image information
106 """
107
108 @classmethod
Andrea Frittoli69a6b632014-09-15 13:14:53 +0100109 def resource_setup(cls):
110 super(ListImagesTest, cls).resource_setup()
Jay Pipes50677282012-01-06 15:39:20 -0500111 # We add a few images here to test the listing functionality of
112 # the images API
Attila Fazekas11795b52013-02-24 15:49:08 +0100113 img1 = cls._create_remote_image('one', 'bare', 'raw')
114 img2 = cls._create_remote_image('two', 'ami', 'ami')
115 img3 = cls._create_remote_image('dup', 'bare', 'raw')
116 img4 = cls._create_remote_image('dup', 'bare', 'raw')
117 img5 = cls._create_standard_image('1', 'ami', 'ami', 42)
118 img6 = cls._create_standard_image('2', 'ami', 'ami', 142)
119 img7 = cls._create_standard_image('33', 'bare', 'raw', 142)
120 img8 = cls._create_standard_image('33', 'bare', 'raw', 142)
121 cls.created_set = set(cls.created_images)
122 # 4x-4x remote image
123 cls.remote_set = set((img1, img2, img3, img4))
124 cls.standard_set = set((img5, img6, img7, img8))
125 # 5x bare, 3x ami
126 cls.bare_set = set((img1, img3, img4, img7, img8))
127 cls.ami_set = set((img2, img5, img6))
128 # 1x with size 42
129 cls.size42_set = set((img5,))
130 # 3x with size 142
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800131 cls.size142_set = set((img6, img7, img8,))
Attila Fazekas11795b52013-02-24 15:49:08 +0100132 # dup named
133 cls.dup_set = set((img3, img4))
Jay Pipes50677282012-01-06 15:39:20 -0500134
135 @classmethod
Attila Fazekas11795b52013-02-24 15:49:08 +0100136 def _create_remote_image(cls, name, container_format, disk_format):
Jay Pipes50677282012-01-06 15:39:20 -0500137 """
138 Create a new remote image and return the ID of the newly-registered
139 image
140 """
Attila Fazekas11795b52013-02-24 15:49:08 +0100141 name = 'New Remote Image %s' % name
Matthew Treinishe81ae692014-06-19 17:41:31 -0400142 location = CONF.image.http_image
David Kranz34f18782015-01-06 13:43:55 -0500143 image = cls.create_image(name=name,
144 container_format=container_format,
145 disk_format=disk_format,
146 is_public=False,
147 location=location)
Attila Fazekas11795b52013-02-24 15:49:08 +0100148 image_id = image['id']
Jay Pipes50677282012-01-06 15:39:20 -0500149 return image_id
150
151 @classmethod
Attila Fazekas11795b52013-02-24 15:49:08 +0100152 def _create_standard_image(cls, name, container_format,
153 disk_format, size):
Jay Pipes50677282012-01-06 15:39:20 -0500154 """
155 Create a new standard image and return the ID of the newly-registered
156 image. Note that the size of the new image is a random number between
157 1024 and 4096
158 """
Matthew Treinishb0c65f22015-04-23 09:09:41 -0400159 image_file = moves.cStringIO(data_utils.random_bytes(size))
Attila Fazekas11795b52013-02-24 15:49:08 +0100160 name = 'New Standard Image %s' % name
David Kranz34f18782015-01-06 13:43:55 -0500161 image = cls.create_image(name=name,
162 container_format=container_format,
163 disk_format=disk_format,
164 is_public=False, data=image_file)
Attila Fazekas11795b52013-02-24 15:49:08 +0100165 image_id = image['id']
Jay Pipes50677282012-01-06 15:39:20 -0500166 return image_id
167
Chris Hoge7579c1a2015-02-26 14:12:15 -0800168 @test.idempotent_id('246178ab-3b33-4212-9a4b-a7fe8261794d')
Jay Pipes50677282012-01-06 15:39:20 -0500169 def test_index_no_params(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500170 # Simple test to see all fixture images returned
Ken'ichi Ohmichie3acc122015-05-22 00:32:54 +0000171 images_list = self.client.list_images()
Matthew Treinish72ea4422013-02-07 14:42:49 -0500172 image_list = map(lambda x: x['id'], images_list)
Attila Fazekas11795b52013-02-24 15:49:08 +0100173 for image_id in self.created_images:
Attila Fazekase191cb12013-07-29 06:41:52 +0200174 self.assertIn(image_id, image_list)
Attila Fazekas11795b52013-02-24 15:49:08 +0100175
Chris Hoge7579c1a2015-02-26 14:12:15 -0800176 @test.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
Attila Fazekas11795b52013-02-24 15:49:08 +0100177 def test_index_disk_format(self):
Ken'ichi Ohmichie3acc122015-05-22 00:32:54 +0000178 images_list = self.client.list_images(disk_format='ami')
Attila Fazekas11795b52013-02-24 15:49:08 +0100179 for image in images_list:
180 self.assertEqual(image['disk_format'], 'ami')
181 result_set = set(map(lambda x: x['id'], images_list))
182 self.assertTrue(self.ami_set <= result_set)
183 self.assertFalse(self.created_set - self.ami_set <= result_set)
184
Chris Hoge7579c1a2015-02-26 14:12:15 -0800185 @test.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
Attila Fazekas11795b52013-02-24 15:49:08 +0100186 def test_index_container_format(self):
Ken'ichi Ohmichie3acc122015-05-22 00:32:54 +0000187 images_list = self.client.list_images(container_format='bare')
Attila Fazekas11795b52013-02-24 15:49:08 +0100188 for image in images_list:
189 self.assertEqual(image['container_format'], 'bare')
190 result_set = set(map(lambda x: x['id'], images_list))
191 self.assertTrue(self.bare_set <= result_set)
192 self.assertFalse(self.created_set - self.bare_set <= result_set)
193
Chris Hoge7579c1a2015-02-26 14:12:15 -0800194 @test.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
Attila Fazekas11795b52013-02-24 15:49:08 +0100195 def test_index_max_size(self):
Ken'ichi Ohmichie3acc122015-05-22 00:32:54 +0000196 images_list = self.client.list_images(size_max=42)
Attila Fazekas11795b52013-02-24 15:49:08 +0100197 for image in images_list:
198 self.assertTrue(image['size'] <= 42)
199 result_set = set(map(lambda x: x['id'], images_list))
200 self.assertTrue(self.size42_set <= result_set)
201 self.assertFalse(self.created_set - self.size42_set <= result_set)
202
Chris Hoge7579c1a2015-02-26 14:12:15 -0800203 @test.idempotent_id('6ffc16d0-4cbf-4401-95c8-4ac63eac34d8')
Attila Fazekas11795b52013-02-24 15:49:08 +0100204 def test_index_min_size(self):
Ken'ichi Ohmichie3acc122015-05-22 00:32:54 +0000205 images_list = self.client.list_images(size_min=142)
Attila Fazekas11795b52013-02-24 15:49:08 +0100206 for image in images_list:
207 self.assertTrue(image['size'] >= 142)
208 result_set = set(map(lambda x: x['id'], images_list))
209 self.assertTrue(self.size142_set <= result_set)
210 self.assertFalse(self.size42_set <= result_set)
211
Chris Hoge7579c1a2015-02-26 14:12:15 -0800212 @test.idempotent_id('e5dc26d9-9aa2-48dd-bda5-748e1445da98')
Attila Fazekas11795b52013-02-24 15:49:08 +0100213 def test_index_status_active_detail(self):
Ken'ichi Ohmichibcad2a22015-05-22 09:37:06 +0000214 images_list = self.client.list_images(detail=True,
215 status='active',
216 sort_key='size',
217 sort_dir='desc')
Attila Fazekas11795b52013-02-24 15:49:08 +0100218 top_size = images_list[0]['size'] # We have non-zero sized images
219 for image in images_list:
220 size = image['size']
221 self.assertTrue(size <= top_size)
222 top_size = size
223 self.assertEqual(image['status'], 'active')
224
Chris Hoge7579c1a2015-02-26 14:12:15 -0800225 @test.idempotent_id('097af10a-bae8-4342-bff4-edf89969ed2a')
Attila Fazekas11795b52013-02-24 15:49:08 +0100226 def test_index_name(self):
Ken'ichi Ohmichibcad2a22015-05-22 09:37:06 +0000227 images_list = self.client.list_images(
228 detail=True,
Sean Dague14c68182013-04-14 15:34:30 -0400229 name='New Remote Image dup')
Attila Fazekas11795b52013-02-24 15:49:08 +0100230 result_set = set(map(lambda x: x['id'], images_list))
231 for image in images_list:
232 self.assertEqual(image['name'], 'New Remote Image dup')
233 self.assertTrue(self.dup_set <= result_set)
234 self.assertFalse(self.created_set - self.dup_set <= result_set)
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800235
236
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800237class UpdateImageMetaTest(base.BaseV1ImageTest):
238 @classmethod
Andrea Frittoli69a6b632014-09-15 13:14:53 +0100239 def resource_setup(cls):
240 super(UpdateImageMetaTest, cls).resource_setup()
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800241 cls.image_id = cls._create_standard_image('1', 'ami', 'ami', 42)
242
243 @classmethod
244 def _create_standard_image(cls, name, container_format,
245 disk_format, size):
246 """
247 Create a new standard image and return the ID of the newly-registered
Mark Washenberger5c3b6fe2014-07-29 13:40:34 -0700248 image.
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800249 """
Matthew Treinishb0c65f22015-04-23 09:09:41 -0400250 image_file = moves.cStringIO(data_utils.random_bytes(size))
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800251 name = 'New Standard Image %s' % name
David Kranz34f18782015-01-06 13:43:55 -0500252 image = cls.create_image(name=name,
253 container_format=container_format,
254 disk_format=disk_format,
255 is_public=False, data=image_file,
256 properties={'key1': 'value1'})
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800257 image_id = image['id']
258 return image_id
259
Chris Hoge7579c1a2015-02-26 14:12:15 -0800260 @test.idempotent_id('01752c1c-0275-4de3-9e5b-876e44541928')
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800261 def test_list_image_metadata(self):
262 # All metadata key/value pairs for an image should be returned
David Kranz34f18782015-01-06 13:43:55 -0500263 resp_metadata = self.client.get_image_meta(self.image_id)
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800264 expected = {'key1': 'value1'}
265 self.assertEqual(expected, resp_metadata['properties'])
266
Chris Hoge7579c1a2015-02-26 14:12:15 -0800267 @test.idempotent_id('d6d7649c-08ce-440d-9ea7-e3dda552f33c')
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800268 def test_update_image_metadata(self):
269 # The metadata for the image should match the updated values
270 req_metadata = {'key1': 'alt1', 'key2': 'value2'}
David Kranz34f18782015-01-06 13:43:55 -0500271 metadata = self.client.get_image_meta(self.image_id)
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800272 self.assertEqual(metadata['properties'], {'key1': 'value1'})
273 metadata['properties'].update(req_metadata)
David Kranz34f18782015-01-06 13:43:55 -0500274 metadata = self.client.update_image(
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800275 self.image_id, properties=metadata['properties'])
276
David Kranz34f18782015-01-06 13:43:55 -0500277 resp_metadata = self.client.get_image_meta(self.image_id)
ivan-zhud1bbe5d2013-12-29 18:32:46 +0800278 expected = {'key1': 'alt1', 'key2': 'value2'}
279 self.assertEqual(expected, resp_metadata['properties'])