blob: 2701107714e97df22c79ff987b16735dcb7cc734 [file] [log] [blame]
Jay Pipes50677282012-01-06 15:39:20 -05001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 OpenStack, LLC
4# 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
Matthew Treinish481466b2012-12-20 17:16:01 -050020from tempest import clients
Matthew Treinish72ea4422013-02-07 14:42:49 -050021from tempest import exceptions
Attila Fazekas11795b52013-02-24 15:49:08 +010022import tempest.test
23from tempest.test import attr
Jay Pipes50677282012-01-06 15:39:20 -050024
25
Attila Fazekasdc216422013-01-29 15:12:14 +010026class CreateRegisterImagesTest(tempest.test.BaseTestCase):
Jay Pipes50677282012-01-06 15:39:20 -050027
28 """
29 Here we test the registration and creation of images
30 """
31
32 @classmethod
33 def setUpClass(cls):
Matthew Treinish72ea4422013-02-07 14:42:49 -050034 cls.os = clients.Manager()
35 cls.client = cls.os.image_client
Jay Pipes50677282012-01-06 15:39:20 -050036 cls.created_images = []
37
38 @classmethod
39 def tearDownClass(cls):
40 for image_id in cls.created_images:
Matthew Treinish72ea4422013-02-07 14:42:49 -050041 cls.client.delete(image_id)
Jay Pipes50677282012-01-06 15:39:20 -050042
Matthew Treinish72ea4422013-02-07 14:42:49 -050043 @attr(type='negative')
44 def test_register_with_invalid_container_format(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -050045 # Negative tests for invalid data supplied to POST /images
Matthew Treinish72ea4422013-02-07 14:42:49 -050046 try:
47 resp, body = self.client.create_image('test', 'wrong', 'vhd')
48 except exceptions.BadRequest:
49 pass
50 else:
51 self.fail('Invalid container format should not be accepted')
Jay Pipes50677282012-01-06 15:39:20 -050052
Matthew Treinish72ea4422013-02-07 14:42:49 -050053 @attr(type='negative')
54 def test_register_with_invalid_disk_format(self):
55 try:
56 resp, body = self.client.create_image('test', 'bare', 'wrong')
57 except exceptions.BadRequest:
58 pass
59 else:
60 self.fail("Invalid disk format should not be accepted")
Jay Pipes50677282012-01-06 15:39:20 -050061
62 @attr(type='image')
63 def test_register_then_upload(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -050064 # Register, then upload an image
Matthew Treinish72ea4422013-02-07 14:42:49 -050065 properties = {'prop1': 'val1'}
66 resp, body = self.client.create_image('New Name', 'bare', 'raw',
67 is_public=True,
68 properties=properties)
69 self.assertTrue('id' in body)
70 image_id = body.get('id')
Jay Pipes50677282012-01-06 15:39:20 -050071 self.created_images.append(image_id)
Matthew Treinish72ea4422013-02-07 14:42:49 -050072 self.assertTrue('name' in body)
73 self.assertEqual('New Name', body.get('name'))
74 self.assertTrue('is_public' in body)
75 self.assertTrue(body.get('is_public'))
76 self.assertTrue('status' in body)
77 self.assertEqual('queued', body.get('status'))
78 self.assertTrue('properties' in body)
79 for key, val in properties.items():
80 self.assertEqual(val, body.get('properties')[key])
Jay Pipes50677282012-01-06 15:39:20 -050081
82 # Now try uploading an image file
Matthew Treinish72ea4422013-02-07 14:42:49 -050083 image_file = StringIO.StringIO(('*' * 1024))
84 resp, body = self.client.update_image(image_id, data=image_file)
85 self.assertTrue('size' in body)
86 self.assertEqual(1024, body.get('size'))
Jay Pipes50677282012-01-06 15:39:20 -050087
88 @attr(type='image')
Jay Pipes50677282012-01-06 15:39:20 -050089 def test_register_remote_image(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -050090 # Register a new remote image
Matthew Treinish72ea4422013-02-07 14:42:49 -050091 resp, body = self.client.create_image('New Remote Image', 'bare',
92 'raw', is_public=True,
93 location='http://example.com'
94 '/someimage.iso')
95 self.assertTrue('id' in body)
96 image_id = body.get('id')
Jay Pipes50677282012-01-06 15:39:20 -050097 self.created_images.append(image_id)
Matthew Treinish72ea4422013-02-07 14:42:49 -050098 self.assertTrue('name' in body)
99 self.assertEqual('New Remote Image', body.get('name'))
100 self.assertTrue('is_public' in body)
101 self.assertTrue(body.get('is_public'))
102 self.assertTrue('status' in body)
103 self.assertEqual('active', body.get('status'))
Jay Pipes50677282012-01-06 15:39:20 -0500104
105
Attila Fazekasdc216422013-01-29 15:12:14 +0100106class ListImagesTest(tempest.test.BaseTestCase):
Jay Pipes50677282012-01-06 15:39:20 -0500107
108 """
109 Here we test the listing of image information
110 """
111
112 @classmethod
113 def setUpClass(cls):
Matthew Treinish72ea4422013-02-07 14:42:49 -0500114 cls.os = clients.Manager()
115 cls.client = cls.os.image_client
Jay Pipes50677282012-01-06 15:39:20 -0500116 cls.created_images = []
Jay Pipes50677282012-01-06 15:39:20 -0500117
118 # We add a few images here to test the listing functionality of
119 # the images API
Attila Fazekas11795b52013-02-24 15:49:08 +0100120 img1 = cls._create_remote_image('one', 'bare', 'raw')
121 img2 = cls._create_remote_image('two', 'ami', 'ami')
122 img3 = cls._create_remote_image('dup', 'bare', 'raw')
123 img4 = cls._create_remote_image('dup', 'bare', 'raw')
124 img5 = cls._create_standard_image('1', 'ami', 'ami', 42)
125 img6 = cls._create_standard_image('2', 'ami', 'ami', 142)
126 img7 = cls._create_standard_image('33', 'bare', 'raw', 142)
127 img8 = cls._create_standard_image('33', 'bare', 'raw', 142)
128 cls.created_set = set(cls.created_images)
129 # 4x-4x remote image
130 cls.remote_set = set((img1, img2, img3, img4))
131 cls.standard_set = set((img5, img6, img7, img8))
132 # 5x bare, 3x ami
133 cls.bare_set = set((img1, img3, img4, img7, img8))
134 cls.ami_set = set((img2, img5, img6))
135 # 1x with size 42
136 cls.size42_set = set((img5,))
137 # 3x with size 142
138 cls.size142_set = set((img6, img7, img8))
139 # dup named
140 cls.dup_set = set((img3, img4))
Jay Pipes50677282012-01-06 15:39:20 -0500141
142 @classmethod
143 def tearDownClass(cls):
144 for image_id in cls.created_images:
Matthew Treinish72ea4422013-02-07 14:42:49 -0500145 cls.client.delete_image(image_id)
146 cls.client.wait_for_resource_deletion(image_id)
Jay Pipes50677282012-01-06 15:39:20 -0500147
148 @classmethod
Attila Fazekas11795b52013-02-24 15:49:08 +0100149 def _create_remote_image(cls, name, container_format, disk_format):
Jay Pipes50677282012-01-06 15:39:20 -0500150 """
151 Create a new remote image and return the ID of the newly-registered
152 image
153 """
Attila Fazekas11795b52013-02-24 15:49:08 +0100154 name = 'New Remote Image %s' % name
155 location = 'http://example.com/someimage_%s.iso' % name
156 resp, image = cls.client.create_image(name,
157 container_format, disk_format,
158 is_public=True,
159 location=location)
160 image_id = image['id']
161 cls.created_images.append(image_id)
Jay Pipes50677282012-01-06 15:39:20 -0500162 return image_id
163
164 @classmethod
Attila Fazekas11795b52013-02-24 15:49:08 +0100165 def _create_standard_image(cls, name, container_format,
166 disk_format, size):
Jay Pipes50677282012-01-06 15:39:20 -0500167 """
168 Create a new standard image and return the ID of the newly-registered
169 image. Note that the size of the new image is a random number between
170 1024 and 4096
171 """
Attila Fazekas11795b52013-02-24 15:49:08 +0100172 image_file = StringIO.StringIO('*' * size)
173 name = 'New Standard Image %s' % name
174 resp, image = cls.client.create_image(name,
175 container_format, disk_format,
176 is_public=True, data=image_file)
177 image_id = image['id']
178 cls.created_images.append(image_id)
Jay Pipes50677282012-01-06 15:39:20 -0500179 return image_id
180
181 @attr(type='image')
182 def test_index_no_params(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500183 # Simple test to see all fixture images returned
Matthew Treinish72ea4422013-02-07 14:42:49 -0500184 resp, images_list = self.client.image_list()
185 self.assertEqual(resp['status'], '200')
186 image_list = map(lambda x: x['id'], images_list)
Attila Fazekas11795b52013-02-24 15:49:08 +0100187 for image_id in self.created_images:
188 self.assertTrue(image_id in image_list)
189
190 @attr(type='image')
191 def test_index_disk_format(self):
192 resp, images_list = self.client.image_list(disk_format='ami')
193 self.assertEqual(resp['status'], '200')
194 for image in images_list:
195 self.assertEqual(image['disk_format'], 'ami')
196 result_set = set(map(lambda x: x['id'], images_list))
197 self.assertTrue(self.ami_set <= result_set)
198 self.assertFalse(self.created_set - self.ami_set <= result_set)
199
200 @attr(type='image')
201 def test_index_container_format(self):
202 resp, images_list = self.client.image_list(container_format='bare')
203 self.assertEqual(resp['status'], '200')
204 for image in images_list:
205 self.assertEqual(image['container_format'], 'bare')
206 result_set = set(map(lambda x: x['id'], images_list))
207 self.assertTrue(self.bare_set <= result_set)
208 self.assertFalse(self.created_set - self.bare_set <= result_set)
209
210 @attr(type='image')
211 def test_index_max_size(self):
212 resp, images_list = self.client.image_list(size_max=42)
213 self.assertEqual(resp['status'], '200')
214 for image in images_list:
215 self.assertTrue(image['size'] <= 42)
216 result_set = set(map(lambda x: x['id'], images_list))
217 self.assertTrue(self.size42_set <= result_set)
218 self.assertFalse(self.created_set - self.size42_set <= result_set)
219
220 @attr(type='image')
221 def test_index_min_size(self):
222 resp, images_list = self.client.image_list(size_min=142)
223 self.assertEqual(resp['status'], '200')
224 for image in images_list:
225 self.assertTrue(image['size'] >= 142)
226 result_set = set(map(lambda x: x['id'], images_list))
227 self.assertTrue(self.size142_set <= result_set)
228 self.assertFalse(self.size42_set <= result_set)
229
230 @attr(type='image')
231 def test_index_status_active_detail(self):
232 resp, images_list = self.client.image_list_detail(status='active',
233 sort_key='size',
234 sort_dir='desc')
235 self.assertEqual(resp['status'], '200')
236 top_size = images_list[0]['size'] # We have non-zero sized images
237 for image in images_list:
238 size = image['size']
239 self.assertTrue(size <= top_size)
240 top_size = size
241 self.assertEqual(image['status'], 'active')
242
243 @attr(type='image')
244 def test_index_name(self):
245 resp, images_list = self.client.image_list_detail(
246 name='New Remote Image dup')
247 self.assertEqual(resp['status'], '200')
248 result_set = set(map(lambda x: x['id'], images_list))
249 for image in images_list:
250 self.assertEqual(image['name'], 'New Remote Image dup')
251 self.assertTrue(self.dup_set <= result_set)
252 self.assertFalse(self.created_set - self.dup_set <= result_set)