blob: 90ffeae8c67763d61a51378a504d8453ac2fe9d7 [file] [log] [blame]
Jay Pipes50677282012-01-06 15:39:20 -05001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
ZhiQiang Fan39f97222013-09-20 04:49:44 +08003# Copyright 2012 OpenStack Foundation
Jay Pipes50677282012-01-06 15:39:20 -05004# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18import cStringIO as StringIO
Jay Pipes50677282012-01-06 15:39:20 -050019
Sean Dague1937d092013-05-17 16:36:38 -040020from tempest.api.image import base
Matthew Treinish72ea4422013-02-07 14:42:49 -050021from tempest import exceptions
Attila Fazekas11795b52013-02-24 15:49:08 +010022from tempest.test import attr
Jay Pipes50677282012-01-06 15:39:20 -050023
24
Matthew Treinishce3ef922013-03-11 14:02:46 -040025class CreateRegisterImagesTest(base.BaseV1ImageTest):
26 """Here we test the registration and creation of images."""
Jay Pipes50677282012-01-06 15:39:20 -050027
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -040028 @attr(type='gate')
Matthew Treinish72ea4422013-02-07 14:42:49 -050029 def test_register_with_invalid_container_format(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -050030 # Negative tests for invalid data supplied to POST /images
Chris Yeohe04628e2013-02-25 17:12:21 +103031 self.assertRaises(exceptions.BadRequest, self.client.create_image,
32 'test', 'wrong', 'vhd')
Jay Pipes50677282012-01-06 15:39:20 -050033
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -040034 @attr(type='gate')
Matthew Treinish72ea4422013-02-07 14:42:49 -050035 def test_register_with_invalid_disk_format(self):
Chris Yeohe04628e2013-02-25 17:12:21 +103036 self.assertRaises(exceptions.BadRequest, self.client.create_image,
37 'test', 'bare', 'wrong')
Jay Pipes50677282012-01-06 15:39:20 -050038
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -040039 @attr(type='gate')
Jay Pipes50677282012-01-06 15:39:20 -050040 def test_register_then_upload(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -050041 # Register, then upload an image
Matthew Treinish72ea4422013-02-07 14:42:49 -050042 properties = {'prop1': 'val1'}
Matthew Treinishce3ef922013-03-11 14:02:46 -040043 resp, body = self.create_image(name='New Name',
44 container_format='bare',
45 disk_format='raw',
46 is_public=True,
47 properties=properties)
Attila Fazekase191cb12013-07-29 06:41:52 +020048 self.assertIn('id', body)
Matthew Treinish72ea4422013-02-07 14:42:49 -050049 image_id = body.get('id')
Matthew Treinish72ea4422013-02-07 14:42:49 -050050 self.assertEqual('New Name', body.get('name'))
Matthew Treinish72ea4422013-02-07 14:42:49 -050051 self.assertTrue(body.get('is_public'))
Matthew Treinish72ea4422013-02-07 14:42:49 -050052 self.assertEqual('queued', body.get('status'))
Matthew Treinish72ea4422013-02-07 14:42:49 -050053 for key, val in properties.items():
54 self.assertEqual(val, body.get('properties')[key])
Jay Pipes50677282012-01-06 15:39:20 -050055
56 # Now try uploading an image file
Matthew Treinish72ea4422013-02-07 14:42:49 -050057 image_file = StringIO.StringIO(('*' * 1024))
58 resp, body = self.client.update_image(image_id, data=image_file)
Attila Fazekase191cb12013-07-29 06:41:52 +020059 self.assertIn('size', body)
Matthew Treinish72ea4422013-02-07 14:42:49 -050060 self.assertEqual(1024, body.get('size'))
Jay Pipes50677282012-01-06 15:39:20 -050061
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -040062 @attr(type='gate')
Jay Pipes50677282012-01-06 15:39:20 -050063 def test_register_remote_image(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -050064 # Register a new remote image
Matthew Treinishce3ef922013-03-11 14:02:46 -040065 resp, body = self.create_image(name='New Remote Image',
66 container_format='bare',
67 disk_format='raw', is_public=True,
68 location='http://example.com'
afazekas4a96bf82013-03-25 16:07:38 +010069 '/someimage.iso',
70 properties={'key1': 'value1',
71 'key2': 'value2'})
Attila Fazekase191cb12013-07-29 06:41:52 +020072 self.assertIn('id', body)
Matthew Treinish72ea4422013-02-07 14:42:49 -050073 self.assertEqual('New Remote Image', body.get('name'))
Matthew Treinish72ea4422013-02-07 14:42:49 -050074 self.assertTrue(body.get('is_public'))
Matthew Treinish72ea4422013-02-07 14:42:49 -050075 self.assertEqual('active', body.get('status'))
afazekas4a96bf82013-03-25 16:07:38 +010076 properties = body.get('properties')
77 self.assertEqual(properties['key1'], 'value1')
78 self.assertEqual(properties['key2'], 'value2')
Jay Pipes50677282012-01-06 15:39:20 -050079
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -040080 @attr(type='gate')
Attila Fazekase72b7cd2013-03-26 18:34:21 +010081 def test_register_http_image(self):
Attila Fazekase72b7cd2013-03-26 18:34:21 +010082 resp, body = self.create_image(name='New Http Image',
83 container_format='bare',
84 disk_format='raw', is_public=True,
Sean Dague83401992013-05-06 17:46:36 -040085 copy_from=self.config.images.http_image)
Attila Fazekase191cb12013-07-29 06:41:52 +020086 self.assertIn('id', body)
Attila Fazekase72b7cd2013-03-26 18:34:21 +010087 image_id = body.get('id')
Attila Fazekase72b7cd2013-03-26 18:34:21 +010088 self.assertEqual('New Http Image', body.get('name'))
89 self.assertTrue(body.get('is_public'))
90 self.client.wait_for_image_status(image_id, 'active')
91 resp, body = self.client.get_image(image_id)
92 self.assertEqual(resp['status'], '200')
Attila Fazekase72b7cd2013-03-26 18:34:21 +010093
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -040094 @attr(type='gate')
hi2suresh75a20302013-04-09 09:17:06 +000095 def test_register_image_with_min_ram(self):
96 # Register an image with min ram
97 properties = {'prop1': 'val1'}
98 resp, body = self.create_image(name='New_image_with_min_ram',
99 container_format='bare',
100 disk_format='raw',
101 is_public=True,
102 min_ram=40,
103 properties=properties)
Attila Fazekase191cb12013-07-29 06:41:52 +0200104 self.assertIn('id', body)
hi2suresh75a20302013-04-09 09:17:06 +0000105 self.assertEqual('New_image_with_min_ram', body.get('name'))
106 self.assertTrue(body.get('is_public'))
107 self.assertEqual('queued', body.get('status'))
108 self.assertEqual(40, body.get('min_ram'))
109 for key, val in properties.items():
110 self.assertEqual(val, body.get('properties')[key])
111
Jay Pipes50677282012-01-06 15:39:20 -0500112
Matthew Treinishce3ef922013-03-11 14:02:46 -0400113class ListImagesTest(base.BaseV1ImageTest):
Jay Pipes50677282012-01-06 15:39:20 -0500114
115 """
116 Here we test the listing of image information
117 """
118
119 @classmethod
120 def setUpClass(cls):
Matthew Treinishce3ef922013-03-11 14:02:46 -0400121 super(ListImagesTest, cls).setUpClass()
Jay Pipes50677282012-01-06 15:39:20 -0500122
123 # We add a few images here to test the listing functionality of
124 # the images API
Attila Fazekas11795b52013-02-24 15:49:08 +0100125 img1 = cls._create_remote_image('one', 'bare', 'raw')
126 img2 = cls._create_remote_image('two', 'ami', 'ami')
127 img3 = cls._create_remote_image('dup', 'bare', 'raw')
128 img4 = cls._create_remote_image('dup', 'bare', 'raw')
129 img5 = cls._create_standard_image('1', 'ami', 'ami', 42)
130 img6 = cls._create_standard_image('2', 'ami', 'ami', 142)
131 img7 = cls._create_standard_image('33', 'bare', 'raw', 142)
132 img8 = cls._create_standard_image('33', 'bare', 'raw', 142)
133 cls.created_set = set(cls.created_images)
134 # 4x-4x remote image
135 cls.remote_set = set((img1, img2, img3, img4))
136 cls.standard_set = set((img5, img6, img7, img8))
137 # 5x bare, 3x ami
138 cls.bare_set = set((img1, img3, img4, img7, img8))
139 cls.ami_set = set((img2, img5, img6))
140 # 1x with size 42
141 cls.size42_set = set((img5,))
142 # 3x with size 142
143 cls.size142_set = set((img6, img7, img8))
144 # dup named
145 cls.dup_set = set((img3, img4))
Jay Pipes50677282012-01-06 15:39:20 -0500146
147 @classmethod
Attila Fazekas11795b52013-02-24 15:49:08 +0100148 def _create_remote_image(cls, name, container_format, disk_format):
Jay Pipes50677282012-01-06 15:39:20 -0500149 """
150 Create a new remote image and return the ID of the newly-registered
151 image
152 """
Attila Fazekas11795b52013-02-24 15:49:08 +0100153 name = 'New Remote Image %s' % name
154 location = 'http://example.com/someimage_%s.iso' % name
Matthew Treinishce3ef922013-03-11 14:02:46 -0400155 resp, image = cls.create_image(name=name,
156 container_format=container_format,
157 disk_format=disk_format,
158 is_public=True,
159 location=location)
Attila Fazekas11795b52013-02-24 15:49:08 +0100160 image_id = image['id']
Jay Pipes50677282012-01-06 15:39:20 -0500161 return image_id
162
163 @classmethod
Attila Fazekas11795b52013-02-24 15:49:08 +0100164 def _create_standard_image(cls, name, container_format,
165 disk_format, size):
Jay Pipes50677282012-01-06 15:39:20 -0500166 """
167 Create a new standard image and return the ID of the newly-registered
168 image. Note that the size of the new image is a random number between
169 1024 and 4096
170 """
Attila Fazekas11795b52013-02-24 15:49:08 +0100171 image_file = StringIO.StringIO('*' * size)
172 name = 'New Standard Image %s' % name
Matthew Treinishce3ef922013-03-11 14:02:46 -0400173 resp, image = cls.create_image(name=name,
174 container_format=container_format,
175 disk_format=disk_format,
176 is_public=True, data=image_file)
Attila Fazekas11795b52013-02-24 15:49:08 +0100177 image_id = image['id']
Jay Pipes50677282012-01-06 15:39:20 -0500178 return image_id
179
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -0400180 @attr(type='gate')
Jay Pipes50677282012-01-06 15:39:20 -0500181 def test_index_no_params(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500182 # Simple test to see all fixture images returned
Matthew Treinish72ea4422013-02-07 14:42:49 -0500183 resp, images_list = self.client.image_list()
184 self.assertEqual(resp['status'], '200')
185 image_list = map(lambda x: x['id'], images_list)
Attila Fazekas11795b52013-02-24 15:49:08 +0100186 for image_id in self.created_images:
Attila Fazekase191cb12013-07-29 06:41:52 +0200187 self.assertIn(image_id, image_list)
Attila Fazekas11795b52013-02-24 15:49:08 +0100188
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -0400189 @attr(type='gate')
Attila Fazekas11795b52013-02-24 15:49:08 +0100190 def test_index_disk_format(self):
191 resp, images_list = self.client.image_list(disk_format='ami')
192 self.assertEqual(resp['status'], '200')
193 for image in images_list:
194 self.assertEqual(image['disk_format'], 'ami')
195 result_set = set(map(lambda x: x['id'], images_list))
196 self.assertTrue(self.ami_set <= result_set)
197 self.assertFalse(self.created_set - self.ami_set <= result_set)
198
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -0400199 @attr(type='gate')
Attila Fazekas11795b52013-02-24 15:49:08 +0100200 def test_index_container_format(self):
201 resp, images_list = self.client.image_list(container_format='bare')
202 self.assertEqual(resp['status'], '200')
203 for image in images_list:
204 self.assertEqual(image['container_format'], 'bare')
205 result_set = set(map(lambda x: x['id'], images_list))
206 self.assertTrue(self.bare_set <= result_set)
207 self.assertFalse(self.created_set - self.bare_set <= result_set)
208
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -0400209 @attr(type='gate')
Attila Fazekas11795b52013-02-24 15:49:08 +0100210 def test_index_max_size(self):
211 resp, images_list = self.client.image_list(size_max=42)
212 self.assertEqual(resp['status'], '200')
213 for image in images_list:
214 self.assertTrue(image['size'] <= 42)
215 result_set = set(map(lambda x: x['id'], images_list))
216 self.assertTrue(self.size42_set <= result_set)
217 self.assertFalse(self.created_set - self.size42_set <= result_set)
218
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -0400219 @attr(type='gate')
Attila Fazekas11795b52013-02-24 15:49:08 +0100220 def test_index_min_size(self):
221 resp, images_list = self.client.image_list(size_min=142)
222 self.assertEqual(resp['status'], '200')
223 for image in images_list:
224 self.assertTrue(image['size'] >= 142)
225 result_set = set(map(lambda x: x['id'], images_list))
226 self.assertTrue(self.size142_set <= result_set)
227 self.assertFalse(self.size42_set <= result_set)
228
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -0400229 @attr(type='gate')
Attila Fazekas11795b52013-02-24 15:49:08 +0100230 def test_index_status_active_detail(self):
231 resp, images_list = self.client.image_list_detail(status='active',
232 sort_key='size',
233 sort_dir='desc')
234 self.assertEqual(resp['status'], '200')
235 top_size = images_list[0]['size'] # We have non-zero sized images
236 for image in images_list:
237 size = image['size']
238 self.assertTrue(size <= top_size)
239 top_size = size
240 self.assertEqual(image['status'], 'active')
241
Giampaolo Lauriafd5f5952013-05-15 09:44:24 -0400242 @attr(type='gate')
Attila Fazekas11795b52013-02-24 15:49:08 +0100243 def test_index_name(self):
244 resp, images_list = self.client.image_list_detail(
Sean Dague14c68182013-04-14 15:34:30 -0400245 name='New Remote Image dup')
Attila Fazekas11795b52013-02-24 15:49:08 +0100246 self.assertEqual(resp['status'], '200')
247 result_set = set(map(lambda x: x['id'], images_list))
248 for image in images_list:
249 self.assertEqual(image['name'], 'New Remote Image dup')
250 self.assertTrue(self.dup_set <= result_set)
251 self.assertFalse(self.created_set - self.dup_set <= result_set)