1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
20 from snaps import file_utils
21 from snaps.openstack.create_image import ImageSettings
23 import openstack_tests
24 from snaps.openstack.utils import glance_utils, nova_utils
25 from snaps.openstack import create_image
26 from snaps.openstack import os_credentials
27 from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
29 __author__ = 'spisarski'
32 class ImageSettingsUnitTests(unittest.TestCase):
34 Tests the construction of the ImageSettings class
37 def test_no_params(self):
38 with self.assertRaises(Exception):
41 def test_empty_config(self):
42 with self.assertRaises(Exception):
43 ImageSettings(config=dict())
45 def test_name_only(self):
46 with self.assertRaises(Exception):
47 ImageSettings(name='foo')
49 def test_config_with_name_only(self):
50 with self.assertRaises(Exception):
51 ImageSettings(config={'name': 'foo'})
53 def test_name_user_only(self):
54 with self.assertRaises(Exception):
55 ImageSettings(name='foo', image_user='bar')
57 def test_config_with_name_user_only(self):
58 with self.assertRaises(Exception):
59 ImageSettings(config={'name': 'foo', 'image_user': 'bar'})
61 def test_name_user_format_only(self):
62 with self.assertRaises(Exception):
63 ImageSettings(name='foo', image_user='bar', img_format='qcow2')
65 def test_config_with_name_user_format_only(self):
66 with self.assertRaises(Exception):
67 ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2'})
69 def test_name_user_format_url_file_only(self):
70 with self.assertRaises(Exception):
71 ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com',
72 image_file='/foo/bar.qcow')
74 def test_config_with_name_user_format_url_file_only(self):
75 with self.assertRaises(Exception):
76 ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
77 'download_url': 'http://foo.com', 'image_file': '/foo/bar.qcow'})
79 def test_name_user_format_url_only(self):
80 settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com')
81 self.assertEquals('foo', settings.name)
82 self.assertEquals('bar', settings.image_user)
83 self.assertEquals('qcow2', settings.format)
84 self.assertEquals('http://foo.com', settings.url)
85 self.assertIsNone(settings.image_file)
86 self.assertIsNone(settings.nic_config_pb_loc)
88 def test_name_user_format_url_only_properties(self):
90 properties['hw_video_model'] = 'vga'
91 settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com', extra_properties=properties)
92 self.assertEquals('foo', settings.name)
93 self.assertEquals('bar', settings.image_user)
94 self.assertEquals('qcow2', settings.format)
95 self.assertEquals('http://foo.com', settings.url)
96 self.assertEquals(properties, settings.extra_properties)
97 self.assertIsNone(settings.image_file)
98 self.assertIsNone(settings.nic_config_pb_loc)
101 def test_config_with_name_user_format_url_only(self):
102 settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
103 'download_url': 'http://foo.com'})
104 self.assertEquals('foo', settings.name)
105 self.assertEquals('bar', settings.image_user)
106 self.assertEquals('qcow2', settings.format)
107 self.assertEquals('http://foo.com', settings.url)
108 self.assertIsNone(settings.image_file)
109 self.assertIsNone(settings.nic_config_pb_loc)
111 def test_name_user_format_file_only(self):
112 settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', image_file='/foo/bar.qcow')
113 self.assertEquals('foo', settings.name)
114 self.assertEquals('bar', settings.image_user)
115 self.assertEquals('qcow2', settings.format)
116 self.assertIsNone(settings.url)
117 self.assertEquals('/foo/bar.qcow', settings.image_file)
118 self.assertIsNone(settings.nic_config_pb_loc)
120 def test_config_with_name_user_format_file_only(self):
121 settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
122 'image_file': '/foo/bar.qcow'})
123 self.assertEquals('foo', settings.name)
124 self.assertEquals('bar', settings.image_user)
125 self.assertEquals('qcow2', settings.format)
126 self.assertIsNone(settings.url)
127 self.assertEquals('/foo/bar.qcow', settings.image_file)
128 self.assertIsNone(settings.nic_config_pb_loc)
130 def test_all_url(self):
132 properties['hw_video_model'] = 'vga'
133 settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com',
134 extra_properties=properties, nic_config_pb_loc='/foo/bar')
135 self.assertEquals('foo', settings.name)
136 self.assertEquals('bar', settings.image_user)
137 self.assertEquals('qcow2', settings.format)
138 self.assertEquals('http://foo.com', settings.url)
139 self.assertEquals(properties, settings.extra_properties)
140 self.assertIsNone(settings.image_file)
141 self.assertEquals('/foo/bar', settings.nic_config_pb_loc)
143 def test_config_all_url(self):
144 settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
145 'download_url': 'http://foo.com',
146 'extra_properties' : '{\'hw_video_model\': \'vga\'}',
147 'nic_config_pb_loc': '/foo/bar'})
148 self.assertEquals('foo', settings.name)
149 self.assertEquals('bar', settings.image_user)
150 self.assertEquals('qcow2', settings.format)
151 self.assertEquals('http://foo.com', settings.url)
152 self.assertEquals('{\'hw_video_model\': \'vga\'}', settings.extra_properties)
153 self.assertIsNone(settings.image_file)
154 self.assertEquals('/foo/bar', settings.nic_config_pb_loc)
156 def test_all_file(self):
158 properties['hw_video_model'] = 'vga'
159 settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', image_file='/foo/bar.qcow',
160 extra_properties=properties, nic_config_pb_loc='/foo/bar')
161 self.assertEquals('foo', settings.name)
162 self.assertEquals('bar', settings.image_user)
163 self.assertEquals('qcow2', settings.format)
164 self.assertIsNone(settings.url)
165 self.assertEquals('/foo/bar.qcow', settings.image_file)
166 self.assertEquals(properties, settings.extra_properties)
167 self.assertEquals('/foo/bar', settings.nic_config_pb_loc)
169 def test_config_all_file(self):
170 settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
171 'image_file': '/foo/bar.qcow',
172 'extra_properties' : '{\'hw_video_model\' : \'vga\'}',
173 'nic_config_pb_loc': '/foo/bar'})
174 self.assertEquals('foo', settings.name)
175 self.assertEquals('bar', settings.image_user)
176 self.assertEquals('qcow2', settings.format)
177 self.assertIsNone(settings.url)
178 self.assertEquals('/foo/bar.qcow', settings.image_file)
179 self.assertEquals('{\'hw_video_model\' : \'vga\'}', settings.extra_properties)
180 self.assertEquals('/foo/bar', settings.nic_config_pb_loc)
183 class CreateImageSuccessTests(OSIntegrationTestCase):
185 Test for the CreateImage class defined in create_image.py
190 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
193 super(self.__class__, self).__start__()
196 self.image_name = self.__class__.__name__ + '-' + str(guid)
198 self.nova = nova_utils.nova_client(self.os_creds)
199 self.glance = glance_utils.glance_client(self.os_creds)
201 self.tmp_dir = 'tmp/' + str(guid)
202 if not os.path.exists(self.tmp_dir):
203 os.makedirs(self.tmp_dir)
207 Cleans the image and downloaded image file
209 if self.image_creator:
210 self.image_creator.clean()
212 if os.path.exists(self.tmp_dir) and os.path.isdir(self.tmp_dir):
213 shutil.rmtree(self.tmp_dir)
215 super(self.__class__, self).__clean__()
217 def test_create_image_clean_url(self):
219 Tests the creation of an OpenStack image from a URL.
222 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
223 self.image_creator = create_image.OpenStackImage(self.os_creds, os_image_settings)
225 created_image = self.image_creator.create()
226 self.assertIsNotNone(created_image)
228 retrieved_image = glance_utils.get_image(self.nova, self.glance, os_image_settings.name)
229 self.assertIsNotNone(retrieved_image)
231 self.assertEquals(created_image.name, retrieved_image.name)
232 self.assertEquals(created_image.id, retrieved_image.id)
234 def test_create_image_clean_url_properties(self):
236 Tests the creation of an OpenStack image from a URL and set properties.
240 properties['hw_video_model'] = 'vga'
243 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
244 os_image_settings.extra_properties = properties
245 self.image_creator = create_image.OpenStackImage(self.os_creds, os_image_settings)
247 created_image = self.image_creator.create()
248 self.assertIsNotNone(created_image)
250 retrieved_image = glance_utils.get_image(self.nova, self.glance, os_image_settings.name)
251 self.assertIsNotNone(retrieved_image)
253 self.assertEquals(created_image.name, retrieved_image.name)
254 self.assertEquals(created_image.id, retrieved_image.id)
255 self.assertEquals(created_image.properties, retrieved_image.properties)
257 def test_create_image_clean_file(self):
259 Tests the creation of an OpenStack image from a file.
261 url_image_settings = openstack_tests.cirros_url_image('foo')
262 image_file = file_utils.download(url_image_settings.url, self.tmp_dir)
263 file_image_settings = openstack_tests.file_image_test_settings(name=self.image_name, file_path=image_file.name)
264 self.image_creator = create_image.OpenStackImage(self.os_creds, file_image_settings)
266 self.image = self.image_creator.create()
267 self.assertIsNotNone(self.image)
268 self.assertEqual(self.image_name, self.image.name)
270 created_image = self.image_creator.create()
271 self.assertIsNotNone(created_image)
273 retrieved_image = glance_utils.get_image(self.nova, self.glance, file_image_settings.name)
274 self.assertIsNotNone(retrieved_image)
276 self.assertEquals(created_image.name, retrieved_image.name)
277 self.assertEquals(created_image.id, retrieved_image.id)
279 def test_create_delete_image(self):
281 Tests the creation then deletion of an OpenStack image to ensure clean() does not raise an Exception.
284 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
285 self.image_creator = create_image.OpenStackImage(self.os_creds, os_image_settings)
286 created_image = self.image_creator.create()
287 self.assertIsNotNone(created_image)
289 # Delete Image manually
290 glance_utils.delete_image(self.glance, created_image)
292 self.assertIsNone(glance_utils.get_image(self.nova, self.glance, self.image_creator.image_settings.name))
294 # Must not throw an exception when attempting to cleanup non-existent image
295 self.image_creator.clean()
296 self.assertIsNone(self.image_creator.get_image())
298 def test_create_same_image(self):
300 Tests the creation of an OpenStack image when the image already exists.
303 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
304 self.image_creator = create_image.OpenStackImage(self.os_creds, os_image_settings)
305 image1 = self.image_creator.create()
306 # Should be retrieving the instance data
307 os_image_2 = create_image.OpenStackImage(self.os_creds, os_image_settings)
308 image2 = os_image_2.create()
309 self.assertEquals(image1.id, image2.id)
312 class CreateImageNegativeTests(OSIntegrationTestCase):
314 Negative test cases for the CreateImage class
318 super(self.__class__, self).__start__()
320 self.image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
321 self.image_creator = None
324 if self.image_creator:
325 self.image_creator.clean()
327 super(self.__class__, self).__clean__()
329 def test_none_image_name(self):
331 Expect an exception when the image name is None
333 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
334 with self.assertRaises(Exception):
335 self.image_creator = create_image.OpenStackImage(
336 self.os_creds, create_image.ImageSettings(
337 name=None, image_user=os_image_settings.image_user, img_format=os_image_settings.format,
338 url=os_image_settings.url))
340 self.fail('Exception should have been thrown prior to this line')
342 def test_bad_image_url(self):
344 Expect an exception when the image download url is bad
346 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
347 self.image_creator = create_image.OpenStackImage(self.os_creds, create_image.ImageSettings(
348 name=os_image_settings.name, image_user=os_image_settings.image_user,
349 img_format=os_image_settings.format, url="http://foo.bar"))
350 with self.assertRaises(Exception):
351 self.image_creator.create()
353 def test_bad_image_file(self):
355 Expect an exception when the image file does not exist
357 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
358 self.image_creator = create_image.OpenStackImage(
360 create_image.ImageSettings(name=os_image_settings.name, image_user=os_image_settings.image_user,
361 img_format=os_image_settings.format, image_file="/foo/bar.qcow"))
362 with self.assertRaises(Exception):
363 self.image_creator.create()
365 def test_none_proj_name(self):
367 Expect an exception when the project name is None
369 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
370 with self.assertRaises(Exception):
371 self.image_creator = create_image.OpenStackImage(
372 os_credentials.OSCreds(self.os_creds.username, self.os_creds.password, self.os_creds.auth_url, None,
373 proxy_settings=self.os_creds.proxy_settings),
375 self.image_creator.create()
377 def test_none_auth_url(self):
379 Expect an exception when the project name is None
381 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
382 with self.assertRaises(Exception):
383 self.image_creator = create_image.OpenStackImage(
384 os_credentials.OSCreds(self.os_creds.username, self.os_creds.password, None,
385 self.os_creds.project_name, proxy_settings=self.os_creds.proxy_settings),
387 self.image_creator.create()
389 def test_none_password(self):
391 Expect an exception when the project name is None
393 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
394 with self.assertRaises(Exception):
395 self.image_creator = create_image.OpenStackImage(
396 os_credentials.OSCreds(self.os_creds.username, None, self.os_creds.os_auth_url,
397 self.os_creds.project_name, proxy_settings=self.os_creds.proxy_settings),
400 def test_none_user(self):
402 Expect an exception when the project name is None
404 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
405 with self.assertRaises(Exception):
406 self.image_creator = create_image.OpenStackImage(
407 os_credentials.OSCreds(None, self.os_creds.password, self.os_creds.os_auth_url,
408 self.os_creds.project_name,
409 proxy_settings=self.os_creds.proxy_settings),
413 class CreateMultiPartImageTests(OSIntegrationTestCase):
415 Test for creating a 3-part image
419 Instantiates the CreateImage object that is responsible for
420 downloading and creating an OS image file within OpenStack
422 super(self.__class__, self).__start__()
425 self.image_creators = list()
426 self.image_name = self.__class__.__name__ + '-' + str(guid)
428 self.nova = nova_utils.nova_client(self.os_creds)
429 self.glance = glance_utils.glance_client(self.os_creds)
431 self.tmp_dir = 'tmp/' + str(guid)
432 if not os.path.exists(self.tmp_dir):
433 os.makedirs(self.tmp_dir)
437 Cleans the images and downloaded image file
439 while self.image_creators:
440 self.image_creators[0].clean()
441 self.image_creators.pop(0)
443 if os.path.exists(self.tmp_dir) and os.path.isdir(self.tmp_dir):
444 shutil.rmtree(self.tmp_dir)
446 super(self.__class__, self).__clean__()
448 def test_create_three_part_image_from_url(self):
450 Tests the creation of a 3-part OpenStack image from a URL.
455 # Create the kernel image
456 kernel_image_settings = openstack_tests.cirros_url_image(name=self.image_name+'_kernel',
457 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
458 self.image_creators.append(create_image.OpenStackImage(self.os_creds, kernel_image_settings))
459 kernel_image = self.image_creators[-1].create()
460 self.assertIsNotNone(kernel_image)
462 # Create the ramdisk image
463 ramdisk_image_settings = openstack_tests.cirros_url_image(name=self.image_name+'_ramdisk',
464 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
465 self.image_creators.append(create_image.OpenStackImage(self.os_creds, ramdisk_image_settings))
466 ramdisk_image = self.image_creators[-1].create()
467 self.assertIsNotNone(ramdisk_image)
469 # Create the main image
470 os_image_settings = openstack_tests.cirros_url_image(name=self.image_name,
471 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
472 properties['kernel_id'] = kernel_image.id
473 properties['ramdisk_id'] = ramdisk_image.id
474 os_image_settings.extra_properties = properties
475 self.image_creators.append(create_image.OpenStackImage(self.os_creds, os_image_settings))
476 created_image = self.image_creators[-1].create()
477 self.assertIsNotNone(created_image)
478 self.assertEqual(self.image_name, created_image.name)
480 retrieved_image = glance_utils.get_image(self.nova, self.glance, os_image_settings.name)
481 self.assertIsNotNone(retrieved_image)
483 self.assertEquals(created_image.name, retrieved_image.name)
484 self.assertEquals(created_image.id, retrieved_image.id)
485 self.assertEquals(created_image.properties, retrieved_image.properties)
487 def test_create_three_part_image_from_file(self):
489 Tests the creation of a 3-part OpenStack image from files.
494 # Create the kernel image
495 url_image_settings = openstack_tests.cirros_url_image('foo_kernel',
496 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
497 kernel_image_file = file_utils.download(url_image_settings.url, self.tmp_dir)
498 kernel_file_image_settings = openstack_tests.file_image_test_settings(
499 name=self.image_name+'_kernel', file_path=kernel_image_file.name)
500 self.image_creators.append(create_image.OpenStackImage(self.os_creds, kernel_file_image_settings))
501 kernel_image = self.image_creators[-1].create()
502 self.assertIsNotNone(kernel_image)
504 # Create the ramdisk image
505 url_image_settings = openstack_tests.cirros_url_image('foo_ramdisk',
506 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
507 ramdisk_image_file = file_utils.download(url_image_settings.url, self.tmp_dir)
508 ramdisk_file_image_settings = openstack_tests.file_image_test_settings(
509 name=self.image_name+'_ramdisk', file_path=ramdisk_image_file.name)
510 self.image_creators.append(create_image.OpenStackImage(self.os_creds, ramdisk_file_image_settings))
511 ramdisk_image = self.image_creators[-1].create()
512 self.assertIsNotNone(ramdisk_image)
514 # Create the main image
515 url_image_settings = openstack_tests.cirros_url_image('foo',
516 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
517 image_file = file_utils.download(url_image_settings.url, self.tmp_dir)
518 file_image_settings = openstack_tests.file_image_test_settings(name=self.image_name, file_path=image_file.name)
519 properties['kernel_id'] = kernel_image.id
520 properties['ramdisk_id'] = ramdisk_image.id
521 file_image_settings.extra_properties = properties
522 self.image_creators.append(create_image.OpenStackImage(self.os_creds, file_image_settings))
523 created_image = self.image_creators[-1].create()
525 self.assertIsNotNone(created_image)
526 self.assertEqual(self.image_name, created_image.name)
528 retrieved_image = glance_utils.get_image(self.nova, self.glance, file_image_settings.name)
529 self.assertIsNotNone(retrieved_image)
531 self.assertEquals(created_image.name, retrieved_image.name)
532 self.assertEquals(created_image.id, retrieved_image.id)
533 self.assertEquals(created_image.properties, retrieved_image.properties)