Added ext_net_name into template substitution variable.
[snaps.git] / snaps / openstack / tests / create_image_tests.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
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:
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,
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.
15 from glanceclient.exc import HTTPBadRequest
16
17 try:
18     from urllib.request import URLError
19 except ImportError:
20     from urllib2 import URLError
21
22 import logging
23 import shutil
24 import unittest
25 import uuid
26
27 import os
28
29 from snaps import file_utils
30 from snaps.openstack import create_image
31 from snaps.openstack.create_image import (ImageSettings, ImageCreationError,
32                                           ImageSettingsError)
33 from snaps.openstack.tests import openstack_tests
34 from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
35 from snaps.openstack.utils import glance_utils
36
37 __author__ = 'spisarski'
38
39 logger = logging.getLogger('create_image_tests')
40
41
42 class ImageSettingsUnitTests(unittest.TestCase):
43     """
44     Tests the construction of the ImageSettings class
45     """
46
47     def test_no_params(self):
48         with self.assertRaises(ImageSettingsError):
49             ImageSettings()
50
51     def test_empty_config(self):
52         with self.assertRaises(ImageSettingsError):
53             ImageSettings(**dict())
54
55     def test_name_only(self):
56         with self.assertRaises(ImageSettingsError):
57             ImageSettings(name='foo')
58
59     def test_config_with_name_only(self):
60         with self.assertRaises(ImageSettingsError):
61             ImageSettings(**{'name': 'foo'})
62
63     def test_name_user_only(self):
64         with self.assertRaises(ImageSettingsError):
65             ImageSettings(name='foo', image_user='bar')
66
67     def test_config_with_name_user_only(self):
68         with self.assertRaises(ImageSettingsError):
69             ImageSettings(**{'name': 'foo', 'image_user': 'bar'})
70
71     def test_name_user_format_only(self):
72         with self.assertRaises(ImageSettingsError):
73             ImageSettings(name='foo', image_user='bar', img_format='qcow2')
74
75     def test_config_with_name_user_format_only(self):
76         with self.assertRaises(ImageSettingsError):
77             ImageSettings(
78                 **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2'})
79
80     def test_name_user_format_url_only(self):
81         settings = ImageSettings(name='foo', image_user='bar',
82                                  img_format='qcow2', url='http://foo.com')
83         self.assertEqual('foo', settings.name)
84         self.assertEqual('bar', settings.image_user)
85         self.assertEqual('qcow2', settings.format)
86         self.assertEqual('http://foo.com', settings.url)
87         self.assertIsNone(settings.image_file)
88         self.assertFalse(settings.exists)
89         self.assertFalse(settings.public)
90         self.assertIsNone(settings.nic_config_pb_loc)
91
92     def test_name_user_format_url_only_properties(self):
93         properties = {'hw_video_model': 'vga'}
94         settings = ImageSettings(name='foo', image_user='bar',
95                                  img_format='qcow2', url='http://foo.com',
96                                  extra_properties=properties)
97         self.assertEqual('foo', settings.name)
98         self.assertEqual('bar', settings.image_user)
99         self.assertEqual('qcow2', settings.format)
100         self.assertEqual('http://foo.com', settings.url)
101         self.assertEqual(properties, settings.extra_properties)
102         self.assertIsNone(settings.image_file)
103         self.assertFalse(settings.exists)
104         self.assertFalse(settings.public)
105         self.assertIsNone(settings.nic_config_pb_loc)
106
107     def test_config_with_name_user_format_url_only(self):
108         settings = ImageSettings(
109             **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
110                'download_url': 'http://foo.com'})
111         self.assertEqual('foo', settings.name)
112         self.assertEqual('bar', settings.image_user)
113         self.assertEqual('qcow2', settings.format)
114         self.assertEqual('http://foo.com', settings.url)
115         self.assertIsNone(settings.image_file)
116         self.assertFalse(settings.exists)
117         self.assertFalse(settings.public)
118         self.assertIsNone(settings.nic_config_pb_loc)
119
120     def test_name_user_format_file_only(self):
121         settings = ImageSettings(name='foo', image_user='bar',
122                                  img_format='qcow2',
123                                  image_file='/foo/bar.qcow')
124         self.assertEqual('foo', settings.name)
125         self.assertEqual('bar', settings.image_user)
126         self.assertEqual('qcow2', settings.format)
127         self.assertIsNone(settings.url)
128         self.assertEqual('/foo/bar.qcow', settings.image_file)
129         self.assertFalse(settings.exists)
130         self.assertFalse(settings.public)
131         self.assertIsNone(settings.nic_config_pb_loc)
132
133     def test_config_with_name_user_format_file_only(self):
134         settings = ImageSettings(
135             **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
136                'image_file': '/foo/bar.qcow'})
137         self.assertEqual('foo', settings.name)
138         self.assertEqual('bar', settings.image_user)
139         self.assertEqual('qcow2', settings.format)
140         self.assertIsNone(settings.url)
141         self.assertEqual('/foo/bar.qcow', settings.image_file)
142         self.assertFalse(settings.exists)
143         self.assertFalse(settings.public)
144         self.assertIsNone(settings.nic_config_pb_loc)
145
146     def test_all_url(self):
147         properties = {'hw_video_model': 'vga'}
148         kernel_settings = ImageSettings(name='kernel', url='http://kernel.com',
149                                         image_user='bar', img_format='qcow2')
150         ramdisk_settings = ImageSettings(name='ramdisk',
151                                          url='http://ramdisk.com',
152                                          image_user='bar', img_format='qcow2')
153         settings = ImageSettings(name='foo', image_user='bar',
154                                  img_format='qcow2', url='http://foo.com',
155                                  extra_properties=properties,
156                                  nic_config_pb_loc='/foo/bar',
157                                  kernel_image_settings=kernel_settings,
158                                  ramdisk_image_settings=ramdisk_settings,
159                                  exists=True, public=True)
160         self.assertEqual('foo', settings.name)
161         self.assertEqual('bar', settings.image_user)
162         self.assertEqual('qcow2', settings.format)
163         self.assertEqual('http://foo.com', settings.url)
164         self.assertEqual(properties, settings.extra_properties)
165         self.assertIsNone(settings.image_file)
166         self.assertEqual('/foo/bar', settings.nic_config_pb_loc)
167         self.assertEqual('kernel', settings.kernel_image_settings.name)
168         self.assertEqual('http://kernel.com',
169                          settings.kernel_image_settings.url)
170         self.assertEqual('bar', settings.kernel_image_settings.image_user)
171         self.assertEqual('qcow2', settings.kernel_image_settings.format)
172         self.assertEqual('ramdisk', settings.ramdisk_image_settings.name)
173         self.assertEqual('http://ramdisk.com',
174                          settings.ramdisk_image_settings.url)
175         self.assertEqual('bar', settings.ramdisk_image_settings.image_user)
176         self.assertEqual('qcow2', settings.ramdisk_image_settings.format)
177         self.assertTrue(settings.exists)
178         self.assertTrue(settings.public)
179
180     def test_config_all_url(self):
181         settings = ImageSettings(
182             **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
183                'download_url': 'http://foo.com',
184                'extra_properties': '{\'hw_video_model\': \'vga\'}',
185                'nic_config_pb_loc': '/foo/bar',
186                'kernel_image_settings': {
187                    'name': 'kernel',
188                    'download_url': 'http://kernel.com',
189                    'image_user': 'bar',
190                    'format': 'qcow2'},
191                'ramdisk_image_settings': {
192                    'name': 'ramdisk',
193                    'download_url': 'http://ramdisk.com',
194                    'image_user': 'bar',
195                    'format': 'qcow2'},
196                'exists': True, 'public': True})
197         self.assertEqual('foo', settings.name)
198         self.assertEqual('bar', settings.image_user)
199         self.assertEqual('qcow2', settings.format)
200         self.assertEqual('http://foo.com', settings.url)
201         self.assertEqual('{\'hw_video_model\': \'vga\'}',
202                          settings.extra_properties)
203         self.assertIsNone(settings.image_file)
204         self.assertEqual('/foo/bar', settings.nic_config_pb_loc)
205         self.assertEqual('kernel', settings.kernel_image_settings.name)
206         self.assertEqual('http://kernel.com',
207                          settings.kernel_image_settings.url)
208         self.assertEqual('ramdisk', settings.ramdisk_image_settings.name)
209         self.assertEqual('http://ramdisk.com',
210                          settings.ramdisk_image_settings.url)
211         self.assertTrue(settings.exists)
212         self.assertTrue(settings.public)
213
214     def test_all_file(self):
215         properties = {'hw_video_model': 'vga'}
216         settings = ImageSettings(name='foo', image_user='bar',
217                                  img_format='qcow2',
218                                  image_file='/foo/bar.qcow',
219                                  extra_properties=properties,
220                                  nic_config_pb_loc='/foo/bar', exists=True,
221                                  public=True)
222         self.assertEqual('foo', settings.name)
223         self.assertEqual('bar', settings.image_user)
224         self.assertEqual('qcow2', settings.format)
225         self.assertIsNone(settings.url)
226         self.assertEqual('/foo/bar.qcow', settings.image_file)
227         self.assertEqual(properties, settings.extra_properties)
228         self.assertEqual('/foo/bar', settings.nic_config_pb_loc)
229         self.assertTrue(settings.exists)
230         self.assertTrue(settings.public)
231
232     def test_config_all_file(self):
233         settings = ImageSettings(
234             **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
235                'image_file': '/foo/bar.qcow',
236                'extra_properties': '{\'hw_video_model\' : \'vga\'}',
237                'nic_config_pb_loc': '/foo/bar', 'exists': True,
238                'public': True})
239         self.assertEqual('foo', settings.name)
240         self.assertEqual('bar', settings.image_user)
241         self.assertEqual('qcow2', settings.format)
242         self.assertIsNone(settings.url)
243         self.assertEqual('/foo/bar.qcow', settings.image_file)
244         self.assertEqual('{\'hw_video_model\' : \'vga\'}',
245                          settings.extra_properties)
246         self.assertEqual('/foo/bar', settings.nic_config_pb_loc)
247         self.assertTrue(settings.exists)
248         self.assertTrue(settings.public)
249
250
251 class CreateImageSuccessTests(OSIntegrationTestCase):
252     """
253     Test for the CreateImage class defined in create_image.py
254     """
255
256     def setUp(self):
257         """
258         Instantiates the CreateImage object that is responsible for downloading
259         and creating an OS image file within OpenStack
260         """
261         super(self.__class__, self).__start__()
262
263         guid = uuid.uuid4()
264         self.image_name = self.__class__.__name__ + '-' + str(guid)
265         self.glance = glance_utils.glance_client(self.os_creds)
266         self.image_creator = None
267
268         if self.image_metadata and 'glance_tests' in self.image_metadata:
269             glance_test_meta = self.image_metadata['glance_tests']
270         else:
271             glance_test_meta = None
272
273         self.tmp_dir = 'tmp/' + str(guid)
274         if not os.path.exists(self.tmp_dir):
275             os.makedirs(self.tmp_dir)
276
277         self.image_settings = openstack_tests.cirros_image_settings(
278             name=self.image_name,
279             image_metadata=glance_test_meta)
280
281     def tearDown(self):
282         """
283         Cleans the image and downloaded image file
284         """
285         if self.image_creator:
286             self.image_creator.clean()
287
288         if os.path.exists(self.tmp_dir) and os.path.isdir(self.tmp_dir):
289             shutil.rmtree(self.tmp_dir)
290
291         super(self.__class__, self).__clean__()
292
293     def test_create_image_clean_url(self):
294         """
295         Tests the creation of an OpenStack image from a URL.
296         """
297         # Create Image
298         # Set the default image settings, then set any custom parameters sent
299         # from the app
300
301         self.image_creator = create_image.OpenStackImage(self.os_creds,
302                                                          self.image_settings)
303         created_image = self.image_creator.create()
304         self.assertIsNotNone(created_image)
305
306         retrieved_image = glance_utils.get_image(
307             self.glance, image_settings=self.image_settings)
308         self.assertIsNotNone(retrieved_image)
309         self.assertEqual(created_image.size, retrieved_image.size)
310         self.assertEqual(get_image_size(self.image_settings),
311                          retrieved_image.size)
312         self.assertEqual(created_image.name, retrieved_image.name)
313         self.assertEqual(created_image.id, retrieved_image.id)
314
315     def test_create_image_clean_url_properties(self):
316         """
317         Tests the creation of an OpenStack image from a URL and set properties.
318         """
319         # Create Image
320         # Set the default image settings, then set any custom parameters sent
321         # from the app
322         self.image_creator = create_image.OpenStackImage(self.os_creds,
323                                                          self.image_settings)
324         created_image = self.image_creator.create()
325         self.assertIsNotNone(created_image)
326
327         retrieved_image = glance_utils.get_image(
328             self.glance, image_settings=self.image_settings)
329         self.assertIsNotNone(retrieved_image)
330         self.assertEqual(self.image_creator.get_image().size,
331                          retrieved_image.size)
332         self.assertEqual(get_image_size(self.image_settings),
333                          retrieved_image.size)
334         self.assertEqual(created_image.name, retrieved_image.name)
335         self.assertEqual(created_image.id, retrieved_image.id)
336         self.assertEqual(created_image.properties, retrieved_image.properties)
337
338     def test_create_image_clean_file(self):
339         """
340         Tests the creation of an OpenStack image from a file.
341         """
342         if not self.image_settings.image_file and self.image_settings.url:
343             # Download the file of the image
344             image_file_name = file_utils.download(self.image_settings.url,
345                                                   self.tmp_dir).name
346         else:
347             image_file_name = self.image_settings.image_file
348
349         if image_file_name:
350             file_image_settings = openstack_tests.file_image_test_settings(
351                 name=self.image_name, file_path=image_file_name)
352
353             self.image_creator = create_image.OpenStackImage(
354                 self.os_creds, file_image_settings)
355             created_image = self.image_creator.create()
356             self.assertIsNotNone(created_image)
357             self.assertEqual(self.image_name, created_image.name)
358
359             retrieved_image = glance_utils.get_image(
360                 self.glance, image_settings=file_image_settings)
361             self.assertIsNotNone(retrieved_image)
362             self.assertEqual(self.image_creator.get_image().size,
363                              retrieved_image.size)
364             self.assertEqual(get_image_size(file_image_settings),
365                              retrieved_image.size)
366
367             self.assertEqual(created_image.name, retrieved_image.name)
368             self.assertEqual(created_image.id, retrieved_image.id)
369         else:
370             logger.warn(
371                 'Test not executed as the image metadata requires image files')
372
373     def test_create_delete_image(self):
374         """
375         Tests the creation then deletion of an OpenStack image to ensure
376         clean() does not raise an Exception.
377         """
378         # Create Image
379         self.image_creator = create_image.OpenStackImage(self.os_creds,
380                                                          self.image_settings)
381         created_image = self.image_creator.create()
382         self.assertIsNotNone(created_image)
383
384         retrieved_image = glance_utils.get_image(
385             self.glance, image_settings=self.image_settings)
386         self.assertIsNotNone(retrieved_image)
387         self.assertEqual(self.image_creator.get_image().size,
388                          retrieved_image.size)
389         self.assertEqual(get_image_size(self.image_settings),
390                          retrieved_image.size)
391
392         # Delete Image manually
393         glance_utils.delete_image(self.glance, created_image)
394
395         self.assertIsNone(glance_utils.get_image(
396             self.glance, image_settings=self.image_creator.image_settings))
397
398         # Must not throw an exception when attempting to cleanup non-existent
399         # image
400         self.image_creator.clean()
401         self.assertIsNone(self.image_creator.get_image())
402
403     def test_create_same_image(self):
404         """
405         Tests the creation of an OpenStack image when the image already exists.
406         """
407         # Create Image
408         self.image_creator = create_image.OpenStackImage(self.os_creds,
409                                                          self.image_settings)
410         image1 = self.image_creator.create()
411
412         retrieved_image = glance_utils.get_image(
413             self.glance, image_settings=self.image_settings)
414         self.assertIsNotNone(retrieved_image)
415         self.assertEqual(self.image_creator.get_image().size,
416                          retrieved_image.size)
417         self.assertEqual(get_image_size(self.image_settings),
418                          retrieved_image.size)
419         self.assertEqual(image1.name, retrieved_image.name)
420         self.assertEqual(image1.id, retrieved_image.id)
421         self.assertEqual(image1.properties, retrieved_image.properties)
422
423         # Should be retrieving the instance data
424         os_image_2 = create_image.OpenStackImage(self.os_creds,
425                                                  self.image_settings)
426         image2 = os_image_2.create()
427         self.assertEqual(image1.id, image2.id)
428
429     def test_create_same_image_new_settings(self):
430         """
431         Tests the creation of an OpenStack image when the image already exists
432         and the configuration only contains the name.
433         """
434         # Create Image
435         self.image_creator = create_image.OpenStackImage(self.os_creds,
436                                                          self.image_settings)
437         image1 = self.image_creator.create()
438
439         retrieved_image = glance_utils.get_image(
440             self.glance, image_settings=self.image_settings)
441         self.assertIsNotNone(retrieved_image)
442         self.assertEqual(self.image_creator.get_image().size,
443                          retrieved_image.size)
444         self.assertEqual(get_image_size(self.image_settings),
445                          retrieved_image.size)
446         self.assertEqual(image1.name, retrieved_image.name)
447         self.assertEqual(image1.id, retrieved_image.id)
448         self.assertEqual(image1.properties, retrieved_image.properties)
449
450         # Should be retrieving the instance data
451         image_2_settings = ImageSettings(name=self.image_settings.name,
452                                          image_user='foo', exists=True)
453         os_image_2 = create_image.OpenStackImage(self.os_creds,
454                                                  image_2_settings)
455         image2 = os_image_2.create()
456         self.assertEqual(image1.id, image2.id)
457
458
459 class CreateImageNegativeTests(OSIntegrationTestCase):
460     """
461     Negative test cases for the CreateImage class
462     """
463
464     def setUp(self):
465         super(self.__class__, self).__start__()
466
467         self.image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
468         self.image_creator = None
469
470     def tearDown(self):
471         if self.image_creator:
472             self.image_creator.clean()
473
474         super(self.__class__, self).__clean__()
475
476     def test_bad_image_name(self):
477         """
478         Expect an ImageCreationError when the image name does not exist when a
479         file or URL has not been configured
480         """
481         os_image_settings = ImageSettings(name='foo', image_user='bar',
482                                           exists=True)
483         self.image_creator = create_image.OpenStackImage(self.os_creds,
484                                                          os_image_settings)
485
486         with self.assertRaises(ImageCreationError):
487             self.image_creator.create()
488
489             self.fail('ImageCreationError should have been raised prior to'
490                       'this line')
491
492     def test_bad_image_url(self):
493         """
494         Expect an ImageCreationError when the image download url is bad
495         """
496         os_image_settings = openstack_tests.cirros_image_settings(
497             name=self.image_name)
498         self.image_creator = create_image.OpenStackImage(
499             self.os_creds,
500             create_image.ImageSettings(name=os_image_settings.name,
501                                        image_user=os_image_settings.image_user,
502                                        img_format=os_image_settings.format,
503                                        url="http://foo.bar"))
504
505         try:
506             self.image_creator.create()
507         except HTTPBadRequest:
508             pass
509         except URLError:
510             pass
511         except Exception as e:
512             self.fail('Invalid Exception ' + str(e))
513
514     def test_bad_image_image_type(self):
515         """
516         Expect an ImageCreationError when the image type bad
517         """
518         os_image_settings = openstack_tests.cirros_image_settings(
519             name=self.image_name)
520         self.image_creator = create_image.OpenStackImage(
521             self.os_creds,
522             create_image.ImageSettings(name=os_image_settings.name,
523                                        image_user=os_image_settings.image_user,
524                                        img_format='foo',
525                                        url=os_image_settings.url))
526
527         with self.assertRaises(Exception):
528             self.image_creator.create()
529
530     def test_bad_image_file(self):
531         """
532         Expect an ImageCreationError when the image file does not exist
533         """
534         os_image_settings = openstack_tests.cirros_image_settings(
535             name=self.image_name)
536         self.image_creator = create_image.OpenStackImage(
537             self.os_creds,
538             create_image.ImageSettings(name=os_image_settings.name,
539                                        image_user=os_image_settings.image_user,
540                                        img_format=os_image_settings.format,
541                                        image_file="/foo/bar.qcow"))
542         with self.assertRaises(IOError):
543             self.image_creator.create()
544
545
546 class CreateMultiPartImageTests(OSIntegrationTestCase):
547     """
548     Test different means for creating a 3-part images
549     """
550
551     def setUp(self):
552         """
553         Instantiates the CreateImage object that is responsible for
554         downloading and creating an OS image file within OpenStack
555         """
556         super(self.__class__, self).__start__()
557
558         guid = uuid.uuid4()
559         self.image_creators = list()
560         self.image_name = self.__class__.__name__ + '-' + str(guid)
561         self.glance = glance_utils.glance_client(self.os_creds)
562
563         self.tmp_dir = 'tmp/' + str(guid)
564         if not os.path.exists(self.tmp_dir):
565             os.makedirs(self.tmp_dir)
566
567         if self.image_metadata and 'glance_tests' in self.image_metadata:
568             self.glance_test_meta = self.image_metadata['glance_tests']
569         else:
570             self.glance_test_meta = dict()
571
572     def tearDown(self):
573         """
574         Cleans the images and downloaded image file
575         """
576         for image_creator in self.image_creators:
577             image_creator.clean()
578
579         if os.path.exists(self.tmp_dir) and os.path.isdir(self.tmp_dir):
580             shutil.rmtree(self.tmp_dir)
581
582         super(self.__class__, self).__clean__()
583
584     def test_create_three_part_image_from_url(self):
585         """
586         Tests the creation of a 3-part OpenStack image from a URL.
587         """
588         # Create the kernel image
589         if 'disk_file' not in self.glance_test_meta:
590             image_settings = openstack_tests.cirros_image_settings(
591                 name=self.image_name,
592                 image_metadata={
593                     'disk_url':
594                         openstack_tests.CIRROS_DEFAULT_IMAGE_URL,
595                     'kernel_url':
596                         openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL,
597                     'ramdisk_url':
598                         openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL})
599
600             image_creator = create_image.OpenStackImage(self.os_creds,
601                                                         image_settings)
602             self.image_creators.append(image_creator)
603             image_creator.create()
604
605             main_image = glance_utils.get_image(self.glance,
606                                                 image_settings=image_settings)
607             self.assertIsNotNone(main_image)
608             self.assertIsNotNone(image_creator.get_image())
609             self.assertEqual(image_creator.get_image().id, main_image.id)
610
611             kernel_image = glance_utils.get_image(
612                 self.glance,
613                 image_settings=image_settings.kernel_image_settings)
614             self.assertIsNotNone(kernel_image)
615             self.assertIsNotNone(image_creator.get_kernel_image())
616             self.assertEqual(kernel_image.id,
617                              image_creator.get_kernel_image().id)
618
619             ramdisk_image = glance_utils.get_image(
620                 self.glance,
621                 image_settings=image_settings.ramdisk_image_settings)
622             self.assertIsNotNone(ramdisk_image)
623             self.assertIsNotNone(image_creator.get_ramdisk_image())
624             self.assertEqual(ramdisk_image.id,
625                              image_creator.get_ramdisk_image().id)
626         else:
627             logger.warn(
628                 'Test not executed as the image metadata requires image files')
629
630     def test_create_three_part_image_from_file_3_creators(self):
631         """
632         Tests the creation of a 3-part OpenStack image from files.
633         """
634         file_only = False
635
636         # Set properties
637         properties = {}
638         if self.glance_test_meta:
639             if 'extra_properties' in self.glance_test_meta:
640                 properties = self.glance_test_meta['extra_properties']
641             if 'disk_file' in self.glance_test_meta:
642                 file_only = True
643
644         # Create the kernel image
645         kernel_file_name = None
646         kernel_url = openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL
647         if 'kernel_file' in self.glance_test_meta:
648             kernel_file_name = self.glance_test_meta['kernel_file']
649         elif 'kernel_url' in self.glance_test_meta:
650             kernel_url = self.glance_test_meta['kernel_url']
651         else:
652             kernel_url = openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL
653
654         if not kernel_file_name and not file_only:
655             kernel_file_name = file_utils.download(kernel_url,
656                                                    self.tmp_dir).name
657         else:
658             logger.warn('Will not download the kernel image.'
659                         ' Cannot execute test')
660             return
661
662         kernel_file_image_settings = openstack_tests.file_image_test_settings(
663             name=self.image_name + '_kernel', file_path=kernel_file_name)
664
665         self.image_creators.append(create_image.OpenStackImage(
666             self.os_creds, kernel_file_image_settings))
667         kernel_image = self.image_creators[-1].create()
668         self.assertIsNotNone(kernel_image)
669         self.assertEqual(get_image_size(kernel_file_image_settings),
670                          kernel_image.size)
671
672         # Create the ramdisk image
673         ramdisk_file_name = None
674         ramdisk_url = openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL
675         if 'ramdisk_file' in self.glance_test_meta:
676             ramdisk_file_name = self.glance_test_meta['ramdisk_file']
677         elif 'ramdisk_url' in self.glance_test_meta:
678             ramdisk_url = self.glance_test_meta['ramdisk_url']
679
680         if not ramdisk_file_name and not file_only:
681             ramdisk_file_name = file_utils.download(ramdisk_url,
682                                                     self.tmp_dir).name
683         else:
684             logger.warn('Will not download the ramdisk image.'
685                         ' Cannot execute test')
686             return
687
688         ramdisk_file_image_settings = openstack_tests.file_image_test_settings(
689             name=self.image_name + '_ramdisk', file_path=ramdisk_file_name)
690         self.image_creators.append(create_image.OpenStackImage(
691             self.os_creds, ramdisk_file_image_settings))
692         ramdisk_image = self.image_creators[-1].create()
693         self.assertIsNotNone(ramdisk_image)
694         self.assertEqual(get_image_size(ramdisk_file_image_settings),
695                          ramdisk_image.size)
696
697         # Create the main disk image
698         disk_file_name = None
699         disk_url = openstack_tests.CIRROS_DEFAULT_IMAGE_URL
700         if 'disk_file' in self.glance_test_meta:
701             disk_file_name = self.glance_test_meta['disk_file']
702         elif 'disk_url' in self.glance_test_meta:
703             disk_url = self.glance_test_meta['disk_url']
704
705         if not disk_file_name and not file_only:
706             disk_file_name = file_utils.download(disk_url, self.tmp_dir).name
707         else:
708             logger.warn('Will not download the disk file image.'
709                         ' Cannot execute test')
710             return
711
712         file_image_settings = openstack_tests.file_image_test_settings(
713             name=self.image_name, file_path=disk_file_name)
714         properties['kernel_id'] = kernel_image.id
715         properties['ramdisk_id'] = ramdisk_image.id
716         file_image_settings.extra_properties = properties
717         self.image_creators.append(
718             create_image.OpenStackImage(self.os_creds, file_image_settings))
719         created_image = self.image_creators[-1].create()
720
721         self.assertIsNotNone(created_image)
722         self.assertEqual(self.image_name, created_image.name)
723
724         retrieved_image = glance_utils.get_image(
725             self.glance, image_settings=file_image_settings)
726         self.assertIsNotNone(retrieved_image)
727         self.assertEqual(self.image_creators[-1].get_image().size,
728                          retrieved_image.size)
729         self.assertEqual(get_image_size(file_image_settings),
730                          retrieved_image.size)
731         self.assertEqual(created_image.name, retrieved_image.name)
732         self.assertEqual(created_image.id, retrieved_image.id)
733         self.assertEqual(created_image.properties, retrieved_image.properties)
734
735     def test_create_three_part_image_from_url_3_creators(self):
736         """
737         Tests the creation of a 3-part OpenStack image from a URL.
738         """
739         if 'disk_file' not in self.glance_test_meta:
740             # Set properties
741             properties = {}
742             if self.glance_test_meta and \
743                     'extra_properties' in self.glance_test_meta:
744                 properties = self.glance_test_meta['extra_properties']
745
746             # Create the kernel image
747             kernel_image_settings = openstack_tests.cirros_image_settings(
748                 name=self.image_name + '_kernel',
749                 url=openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL)
750
751             if self.glance_test_meta:
752                 if 'kernel_url' in self.glance_test_meta:
753                     kernel_image_settings.url = self.glance_test_meta[
754                         'kernel_url']
755             self.image_creators.append(
756                 create_image.OpenStackImage(self.os_creds,
757                                             kernel_image_settings))
758             kernel_image = self.image_creators[-1].create()
759             self.assertIsNotNone(kernel_image)
760             self.assertEqual(get_image_size(kernel_image_settings),
761                              kernel_image.size)
762
763             # Create the ramdisk image
764             ramdisk_image_settings = openstack_tests.cirros_image_settings(
765                 name=self.image_name + '_ramdisk',
766                 url=openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL)
767             if self.glance_test_meta:
768                 if 'ramdisk_url' in self.glance_test_meta:
769                     ramdisk_image_settings.url = self.glance_test_meta[
770                         'ramdisk_url']
771             self.image_creators.append(
772                 create_image.OpenStackImage(self.os_creds,
773                                             ramdisk_image_settings))
774             ramdisk_image = self.image_creators[-1].create()
775             self.assertIsNotNone(ramdisk_image)
776             self.assertEqual(get_image_size(ramdisk_image_settings),
777                              ramdisk_image.size)
778
779             # Create the main image
780             os_image_settings = openstack_tests.cirros_image_settings(
781                 name=self.image_name,
782                 url=openstack_tests.CIRROS_DEFAULT_IMAGE_URL)
783             if self.glance_test_meta:
784                 if 'disk_url' in self.glance_test_meta:
785                     os_image_settings.url = self.glance_test_meta['disk_url']
786
787             properties['kernel_id'] = kernel_image.id
788             properties['ramdisk_id'] = ramdisk_image.id
789             os_image_settings.extra_properties = properties
790
791             self.image_creators.append(
792                 create_image.OpenStackImage(self.os_creds, os_image_settings))
793             created_image = self.image_creators[-1].create()
794             self.assertIsNotNone(created_image)
795             self.assertEqual(self.image_name, created_image.name)
796
797             retrieved_image = glance_utils.get_image(
798                 self.glance, image_settings=os_image_settings)
799             self.assertIsNotNone(retrieved_image)
800
801             self.assertEqual(self.image_creators[-1].get_image().size,
802                              retrieved_image.size)
803             self.assertEqual(get_image_size(os_image_settings),
804                              retrieved_image.size)
805
806             self.assertEqual(created_image.name, retrieved_image.name)
807             self.assertEqual(created_image.id, retrieved_image.id)
808             self.assertEqual(created_image.properties,
809                              retrieved_image.properties)
810         else:
811             logger.warn(
812                 'Test not executed as the image metadata requires image files')
813
814
815 def get_image_size(image_settings):
816     """
817     Returns the expected image size
818     :return:
819     """
820     if image_settings.image_file:
821         return os.path.getsize(image_settings.image_file)
822     elif image_settings.url:
823         return int(file_utils.get_content_length(image_settings.url))
824     else:
825         raise Exception(
826             'Cannot retrieve expected image size. Image filename or URL has '
827             'not been configured')