Added method to OpenStackHeatStack to return OpenStackFlavor objects.
[snaps.git] / snaps / openstack / tests / create_stack_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 import time
16
17 import pkg_resources
18 from heatclient.exc import HTTPBadRequest
19 from snaps import file_utils
20 from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings
21 from snaps.openstack.create_image import OpenStackImage
22
23 try:
24     from urllib.request import URLError
25 except ImportError:
26     from urllib2 import URLError
27
28 import logging
29 import unittest
30 import uuid
31
32 from snaps.openstack import create_stack
33 from snaps.openstack.create_stack import (
34     StackSettings, StackSettingsError, StackCreationError)
35 from snaps.openstack.tests import openstack_tests, create_instance_tests
36 from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
37 from snaps.openstack.utils import heat_utils, neutron_utils, nova_utils
38
39 __author__ = 'spisarski'
40
41 logger = logging.getLogger('create_stack_tests')
42
43
44 class StackSettingsUnitTests(unittest.TestCase):
45     """
46     Tests the construction of the StackSettings class
47     """
48
49     def test_no_params(self):
50         with self.assertRaises(StackSettingsError):
51             StackSettings()
52
53     def test_empty_config(self):
54         with self.assertRaises(StackSettingsError):
55             StackSettings(**dict())
56
57     def test_name_only(self):
58         with self.assertRaises(StackSettingsError):
59             StackSettings(name='foo')
60
61     def test_config_with_name_only(self):
62         with self.assertRaises(StackSettingsError):
63             StackSettings(**{'name': 'foo'})
64
65     def test_config_minimum_template(self):
66         settings = StackSettings(**{'name': 'stack', 'template': 'foo'})
67         self.assertEqual('stack', settings.name)
68         self.assertEqual('foo', settings.template)
69         self.assertIsNone(settings.template_path)
70         self.assertIsNone(settings.env_values)
71         self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT,
72                          settings.stack_create_timeout)
73
74     def test_config_minimum_template_path(self):
75         settings = StackSettings(**{'name': 'stack', 'template_path': 'foo'})
76         self.assertEqual('stack', settings.name)
77         self.assertIsNone(settings.template)
78         self.assertEqual('foo', settings.template_path)
79         self.assertIsNone(settings.env_values)
80         self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT,
81                          settings.stack_create_timeout)
82
83     def test_minimum_template(self):
84         settings = StackSettings(name='stack', template='foo')
85         self.assertEqual('stack', settings.name)
86         self.assertEqual('foo', settings.template)
87         self.assertIsNone(settings.template_path)
88         self.assertIsNone(settings.env_values)
89         self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT,
90                          settings.stack_create_timeout)
91
92     def test_minimum_template_path(self):
93         settings = StackSettings(name='stack', template_path='foo')
94         self.assertEqual('stack', settings.name)
95         self.assertEqual('foo', settings.template_path)
96         self.assertIsNone(settings.template)
97         self.assertIsNone(settings.env_values)
98         self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT,
99                          settings.stack_create_timeout)
100
101     def test_all(self):
102         env_values = {'foo': 'bar'}
103         settings = StackSettings(name='stack', template='bar',
104                                  template_path='foo', env_values=env_values,
105                                  stack_create_timeout=999)
106         self.assertEqual('stack', settings.name)
107         self.assertEqual('bar', settings.template)
108         self.assertEqual('foo', settings.template_path)
109         self.assertEqual(env_values, settings.env_values)
110         self.assertEqual(999, settings.stack_create_timeout)
111
112     def test_config_all(self):
113         env_values = {'foo': 'bar'}
114         settings = StackSettings(
115             **{'name': 'stack', 'template': 'bar', 'template_path': 'foo',
116                'env_values': env_values, 'stack_create_timeout': 999})
117         self.assertEqual('stack', settings.name)
118         self.assertEqual('bar', settings.template)
119         self.assertEqual('foo', settings.template_path)
120         self.assertEqual(env_values, settings.env_values)
121         self.assertEqual(999, settings.stack_create_timeout)
122
123
124 class CreateStackSuccessTests(OSIntegrationTestCase):
125     """
126     Tests for the CreateStack class defined in create_stack.py
127     """
128
129     def setUp(self):
130         """
131         Instantiates the CreateStack object that is responsible for downloading
132         and creating an OS stack file within OpenStack
133         """
134         super(self.__class__, self).__start__()
135
136         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
137
138         self.heat_creds = self.admin_os_creds
139         self.heat_creds.project_name = self.admin_os_creds.project_name
140
141         self.heat_cli = heat_utils.heat_client(self.heat_creds)
142         self.stack_creator = None
143
144         self.image_creator = OpenStackImage(
145             self.heat_creds, openstack_tests.cirros_image_settings(
146                 name=self.guid + '-image',
147                 image_metadata=self.image_metadata))
148         self.image_creator.create()
149
150         # Create Flavor
151         self.flavor_creator = OpenStackFlavor(
152             self.admin_os_creds,
153             FlavorSettings(name=self.guid + '-flavor-name', ram=256, disk=10,
154                            vcpus=1))
155         self.flavor_creator.create()
156
157         self.network_name = self.guid + '-net'
158         self.subnet_name = self.guid + '-subnet'
159         self.vm_inst_name = self.guid + '-inst'
160
161         self.env_values = {
162             'image_name': self.image_creator.image_settings.name,
163             'flavor_name': self.flavor_creator.flavor_settings.name,
164             'net_name': self.network_name,
165             'subnet_name': self.subnet_name,
166             'inst_name': self.vm_inst_name}
167
168         self.heat_tmplt_path = pkg_resources.resource_filename(
169             'snaps.openstack.tests.heat', 'test_heat_template.yaml')
170
171     def tearDown(self):
172         """
173         Cleans the stack and downloaded stack file
174         """
175         if self.stack_creator:
176             try:
177                 self.stack_creator.clean()
178             except:
179                 pass
180
181         if self.image_creator:
182             try:
183                 self.image_creator.clean()
184             except:
185                 pass
186
187         if self.flavor_creator:
188             try:
189                 self.flavor_creator.clean()
190             except:
191                 pass
192
193         super(self.__class__, self).__clean__()
194
195     def test_create_stack_template_file(self):
196         """
197         Tests the creation of an OpenStack stack from Heat template file.
198         """
199         # Create Stack
200         # Set the default stack settings, then set any custom parameters sent
201         # from the app
202         stack_settings = StackSettings(
203             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
204             template_path=self.heat_tmplt_path,
205             env_values=self.env_values)
206         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
207                                                              stack_settings)
208         created_stack = self.stack_creator.create()
209         self.assertIsNotNone(created_stack)
210
211         retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli,
212                                                      created_stack.id)
213         self.assertIsNotNone(retrieved_stack)
214         self.assertEqual(created_stack.name, retrieved_stack.name)
215         self.assertEqual(created_stack.id, retrieved_stack.id)
216         self.assertEqual(0, len(self.stack_creator.get_outputs()))
217
218     def test_create_stack_short_timeout(self):
219         """
220         Tests the creation of an OpenStack stack from Heat template file.
221         """
222         # Create Stack
223         # Set the default stack settings, then set any custom parameters sent
224         # from the app
225         stack_settings = StackSettings(
226             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
227             template_path=self.heat_tmplt_path,
228             env_values=self.env_values, stack_create_timeout=0)
229
230         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
231                                                              stack_settings)
232         with self.assertRaises(StackCreationError):
233             self.stack_creator.create()
234
235     def test_create_stack_template_dict(self):
236         """
237         Tests the creation of an OpenStack stack from a heat dict() object.
238         """
239         # Create Stack
240         # Set the default stack settings, then set any custom parameters sent
241         # from the app
242         template_dict = heat_utils.parse_heat_template_str(
243             file_utils.read_file(self.heat_tmplt_path))
244         stack_settings = StackSettings(
245             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
246             template=template_dict,
247             env_values=self.env_values)
248         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
249                                                              stack_settings)
250         created_stack = self.stack_creator.create()
251         self.assertIsNotNone(created_stack)
252
253         retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli,
254                                                      created_stack.id)
255         self.assertIsNotNone(retrieved_stack)
256         self.assertEqual(created_stack.name, retrieved_stack.name)
257         self.assertEqual(created_stack.id, retrieved_stack.id)
258         self.assertEqual(0, len(self.stack_creator.get_outputs()))
259
260     def test_create_delete_stack(self):
261         """
262         Tests the creation then deletion of an OpenStack stack to ensure
263         clean() does not raise an Exception.
264         """
265         # Create Stack
266         template_dict = heat_utils.parse_heat_template_str(
267             file_utils.read_file(self.heat_tmplt_path))
268         stack_settings = StackSettings(
269             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
270             template=template_dict,
271             env_values=self.env_values)
272         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
273                                                              stack_settings)
274         created_stack = self.stack_creator.create()
275         self.assertIsNotNone(created_stack)
276
277         retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli,
278                                                      created_stack.id)
279         self.assertIsNotNone(retrieved_stack)
280         self.assertEqual(created_stack.name, retrieved_stack.name)
281         self.assertEqual(created_stack.id, retrieved_stack.id)
282         self.assertEqual(0, len(self.stack_creator.get_outputs()))
283         self.assertEqual(create_stack.STATUS_CREATE_COMPLETE,
284                          self.stack_creator.get_status())
285
286         # Delete Stack manually
287         heat_utils.delete_stack(self.heat_cli, created_stack)
288
289         end_time = time.time() + 90
290         deleted = False
291         while time.time() < end_time:
292             status = heat_utils.get_stack_status(self.heat_cli,
293                                                  retrieved_stack.id)
294             if status == create_stack.STATUS_DELETE_COMPLETE:
295                 deleted = True
296                 break
297
298         self.assertTrue(deleted)
299
300         # Must not throw an exception when attempting to cleanup non-existent
301         # stack
302         self.stack_creator.clean()
303         self.assertIsNone(self.stack_creator.get_stack())
304
305     def test_create_same_stack(self):
306         """
307         Tests the creation of an OpenStack stack when the stack already exists.
308         """
309         # Create Stack
310         template_dict = heat_utils.parse_heat_template_str(
311             file_utils.read_file(self.heat_tmplt_path))
312         stack_settings = StackSettings(
313             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
314             template=template_dict,
315             env_values=self.env_values)
316         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
317                                                              stack_settings)
318         created_stack1 = self.stack_creator.create()
319
320         retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli,
321                                                      created_stack1.id)
322         self.assertIsNotNone(retrieved_stack)
323         self.assertEqual(created_stack1.name, retrieved_stack.name)
324         self.assertEqual(created_stack1.id, retrieved_stack.id)
325         self.assertEqual(0, len(self.stack_creator.get_outputs()))
326
327         # Should be retrieving the instance data
328         stack_creator2 = create_stack.OpenStackHeatStack(self.heat_creds,
329                                                          stack_settings)
330         stack2 = stack_creator2.create()
331         self.assertEqual(created_stack1.id, stack2.id)
332
333     def test_retrieve_network_creators(self):
334         """
335         Tests the creation of an OpenStack stack from Heat template file and
336         the retrieval of the network creator.
337         """
338         stack_settings = StackSettings(
339             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
340             template_path=self.heat_tmplt_path,
341             env_values=self.env_values)
342         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
343                                                              stack_settings)
344         created_stack = self.stack_creator.create()
345         self.assertIsNotNone(created_stack)
346
347         net_creators = self.stack_creator.get_network_creators()
348         self.assertIsNotNone(net_creators)
349         self.assertEqual(1, len(net_creators))
350         self.assertEqual(self.network_name, net_creators[0].get_network().name)
351
352         neutron = neutron_utils.neutron_client(self.os_creds)
353         net_by_name = neutron_utils.get_network(
354             neutron, network_name=net_creators[0].get_network().name)
355         self.assertEqual(net_creators[0].get_network(), net_by_name)
356         self.assertIsNotNone(neutron_utils.get_network_by_id(
357             neutron, net_creators[0].get_network().id))
358
359         self.assertEqual(1, len(net_creators[0].get_subnets()))
360         subnet = net_creators[0].get_subnets()[0]
361         subnet_by_name = neutron_utils.get_subnet(
362             neutron, subnet_name=subnet.name)
363         self.assertEqual(subnet, subnet_by_name)
364
365         subnet_by_id = neutron_utils.get_subnet_by_id(neutron, subnet.id)
366         self.assertIsNotNone(subnet_by_id)
367         self.assertEqual(subnet_by_name, subnet_by_id)
368
369     def test_retrieve_vm_inst_creators(self):
370         """
371         Tests the creation of an OpenStack stack from Heat template file and
372         the retrieval of the network creator.
373         """
374         stack_settings = StackSettings(
375             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
376             template_path=self.heat_tmplt_path,
377             env_values=self.env_values)
378         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
379                                                              stack_settings)
380         created_stack = self.stack_creator.create()
381         self.assertIsNotNone(created_stack)
382
383         vm_inst_creators = self.stack_creator.get_vm_inst_creators()
384         self.assertIsNotNone(vm_inst_creators)
385         self.assertEqual(1, len(vm_inst_creators))
386         self.assertEqual(self.vm_inst_name,
387                          vm_inst_creators[0].get_vm_inst().name)
388
389         nova = nova_utils.nova_client(self.admin_os_creds)
390         vm_inst_by_name = nova_utils.get_server(
391             nova, server_name=vm_inst_creators[0].get_vm_inst().name)
392         self.assertEqual(vm_inst_creators[0].get_vm_inst(), vm_inst_by_name)
393         self.assertIsNotNone(nova_utils.get_server_object_by_id(
394             nova, vm_inst_creators[0].get_vm_inst().id))
395
396
397 class CreateStackFloatingIpTests(OSIntegrationTestCase):
398     """
399     Tests for the CreateStack class defined in create_stack.py
400     """
401
402     def setUp(self):
403         """
404         Instantiates the CreateStack object that is responsible for downloading
405         and creating an OS stack file within OpenStack
406         """
407         super(self.__class__, self).__start__()
408
409         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
410
411         self.heat_creds = self.admin_os_creds
412         self.heat_creds.project_name = self.admin_os_creds.project_name
413
414         self.heat_cli = heat_utils.heat_client(self.heat_creds)
415         self.stack_creator = None
416
417         self.image_creator = OpenStackImage(
418             self.heat_creds, openstack_tests.cirros_image_settings(
419                 name=self.guid + '-image',
420                 image_metadata=self.image_metadata))
421         self.image_creator.create()
422
423         self.network_name = self.guid + '-net'
424         self.subnet_name = self.guid + '-subnet'
425         self.flavor1_name = self.guid + '-flavor1'
426         self.flavor2_name = self.guid + '-flavor2'
427         self.sec_grp_name = self.guid + '-sec_grp'
428         self.vm_inst1_name = self.guid + '-inst1'
429         self.vm_inst2_name = self.guid + '-inst2'
430         self.keypair_name = self.guid + '-kp'
431
432         self.env_values = {
433             'image1_name': self.image_creator.image_settings.name,
434             'image2_name': self.image_creator.image_settings.name,
435             'flavor1_name': self.flavor1_name,
436             'flavor2_name': self.flavor2_name,
437             'net_name': self.network_name,
438             'subnet_name': self.subnet_name,
439             'inst1_name': self.vm_inst1_name,
440             'inst2_name': self.vm_inst2_name,
441             'keypair_name': self.keypair_name,
442             'external_net_name': self.ext_net_name,
443             'security_group_name': self.sec_grp_name}
444
445         self.heat_tmplt_path = pkg_resources.resource_filename(
446             'snaps.openstack.tests.heat', 'floating_ip_heat_template.yaml')
447
448     def tearDown(self):
449         """
450         Cleans the stack and downloaded stack file
451         """
452         if self.stack_creator:
453             try:
454                 self.stack_creator.clean()
455             except:
456                 pass
457
458         if self.image_creator:
459             try:
460                 self.image_creator.clean()
461             except:
462                 pass
463
464         super(self.__class__, self).__clean__()
465
466     def test_connect_via_ssh_heat_vm(self):
467         """
468         Tests the creation of an OpenStack stack from Heat template file and
469         the retrieval of two VM instance creators and attempt to connect via
470         SSH to the first one with a floating IP.
471         """
472         stack_settings = StackSettings(
473             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
474             template_path=self.heat_tmplt_path,
475             env_values=self.env_values)
476         self.stack_creator = create_stack.OpenStackHeatStack(
477             self.heat_creds, stack_settings,
478             [self.image_creator.image_settings])
479         created_stack = self.stack_creator.create()
480         self.assertIsNotNone(created_stack)
481
482         vm_inst_creators = self.stack_creator.get_vm_inst_creators(
483             heat_keypair_option='private_key')
484         self.assertIsNotNone(vm_inst_creators)
485         self.assertEqual(2, len(vm_inst_creators))
486
487         for vm_inst_creator in vm_inst_creators:
488             if vm_inst_creator.get_vm_inst().name == self.vm_inst1_name:
489                 self.assertTrue(
490                     create_instance_tests.validate_ssh_client(vm_inst_creator))
491             else:
492                 vm_settings = vm_inst_creator.instance_settings
493                 self.assertEqual(0, len(vm_settings.floating_ip_settings))
494
495
496 class CreateStackVolumeTests(OSIntegrationTestCase):
497     """
498     Tests for the CreateStack class as they pertain to volumes
499     """
500
501     def setUp(self):
502         """
503         Instantiates the CreateStack object that is responsible for downloading
504         and creating an OS stack file within OpenStack
505         """
506         super(self.__class__, self).__start__()
507
508         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
509
510         self.heat_creds = self.admin_os_creds
511         self.heat_creds.project_name = self.admin_os_creds.project_name
512
513         self.heat_cli = heat_utils.heat_client(self.heat_creds)
514         self.stack_creator = None
515
516         self.volume_name = self.guid + '-volume'
517         self.volume_type_name = self.guid + '-volume-type'
518
519         self.env_values = {
520             'volume_name': self.volume_name,
521             'volume_type_name': self.volume_type_name}
522
523         self.heat_tmplt_path = pkg_resources.resource_filename(
524             'snaps.openstack.tests.heat', 'volume_heat_template.yaml')
525
526         stack_settings = StackSettings(
527             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
528             template_path=self.heat_tmplt_path,
529             env_values=self.env_values)
530         self.stack_creator = create_stack.OpenStackHeatStack(
531             self.heat_creds, stack_settings)
532         self.created_stack = self.stack_creator.create()
533         self.assertIsNotNone(self.created_stack)
534
535     def tearDown(self):
536         """
537         Cleans the stack and downloaded stack file
538         """
539         if self.stack_creator:
540             try:
541                 self.stack_creator.clean()
542             except:
543                 pass
544
545         super(self.__class__, self).__clean__()
546
547     def test_retrieve_volume_creator(self):
548         """
549         Tests the creation of an OpenStack stack from Heat template file and
550         the retrieval of an OpenStackVolume creator/state machine instance
551         """
552         volume_creators = self.stack_creator.get_volume_creators()
553         self.assertEqual(1, len(volume_creators))
554
555         creator = volume_creators[0]
556         self.assertEqual(self.volume_name, creator.volume_settings.name)
557         self.assertEqual(self.volume_name, creator.get_volume().name)
558         self.assertEqual(self.volume_type_name,
559                          creator.volume_settings.type_name)
560         self.assertEqual(self.volume_type_name, creator.get_volume().type)
561         self.assertEqual(1, creator.volume_settings.size)
562         self.assertEqual(1, creator.get_volume().size)
563
564     def test_retrieve_volume_type_creator(self):
565         """
566         Tests the creation of an OpenStack stack from Heat template file and
567         the retrieval of an OpenStackVolume creator/state machine instance
568         """
569         volume_type_creators = self.stack_creator.get_volume_type_creators()
570         self.assertEqual(1, len(volume_type_creators))
571
572         creator = volume_type_creators[0]
573         self.assertIsNotNone(creator)
574
575         volume_type = creator.get_volume_type()
576         self.assertIsNotNone(volume_type)
577
578         self.assertEqual(self.volume_type_name, volume_type.name)
579         self.assertTrue(volume_type.public)
580         self.assertIsNone(volume_type.qos_spec)
581
582         encryption = volume_type.encryption
583         self.assertIsNotNone(encryption)
584         self.assertIsNone(encryption.cipher)
585         self.assertEqual('front-end', encryption.control_location)
586         self.assertIsNone(encryption.key_size)
587         self.assertEqual(u'nova.volume.encryptors.luks.LuksEncryptor',
588                          encryption.provider)
589         self.assertEqual(volume_type.id, encryption.volume_type_id)
590
591
592 class CreateStackFlavorTests(OSIntegrationTestCase):
593     """
594     Tests for the CreateStack class defined in create_stack.py
595     """
596
597     def setUp(self):
598         """
599         Instantiates the CreateStack object that is responsible for downloading
600         and creating an OS stack file within OpenStack
601         """
602         super(self.__class__, self).__start__()
603
604         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
605
606         self.heat_creds = self.admin_os_creds
607         self.heat_creds.project_name = self.admin_os_creds.project_name
608
609         self.heat_cli = heat_utils.heat_client(self.heat_creds)
610         self.stack_creator = None
611
612         self.heat_tmplt_path = pkg_resources.resource_filename(
613             'snaps.openstack.tests.heat', 'flavor_heat_template.yaml')
614
615         stack_settings = StackSettings(
616             name=self.guid + '-stack',
617             template_path=self.heat_tmplt_path)
618         self.stack_creator = create_stack.OpenStackHeatStack(
619             self.heat_creds, stack_settings)
620         self.created_stack = self.stack_creator.create()
621         self.assertIsNotNone(self.created_stack)
622
623     def tearDown(self):
624         """
625         Cleans the stack and downloaded stack file
626         """
627         if self.stack_creator:
628             try:
629                 self.stack_creator.clean()
630             except:
631                 pass
632
633         super(self.__class__, self).__clean__()
634
635     def test_retrieve_flavor_creator(self):
636         """
637         Tests the creation of an OpenStack stack from Heat template file and
638         the retrieval of an OpenStackVolume creator/state machine instance
639         """
640         flavor_creators = self.stack_creator.get_flavor_creators()
641         self.assertEqual(1, len(flavor_creators))
642
643         creator = flavor_creators[0]
644         self.assertTrue(creator.get_flavor().name.startswith(self.guid))
645         self.assertEqual(1024, creator.get_flavor().ram)
646         self.assertEqual(200, creator.get_flavor().disk)
647         self.assertEqual(8, creator.get_flavor().vcpus)
648         self.assertEqual(0, creator.get_flavor().ephemeral)
649         self.assertIsNone(creator.get_flavor().swap)
650         self.assertEqual(1.0, creator.get_flavor().rxtx_factor)
651         self.assertTrue(creator.get_flavor().is_public)
652
653
654 class CreateStackKeypairTests(OSIntegrationTestCase):
655     """
656     Tests for the CreateStack class as they pertain to keypairs
657     """
658
659     def setUp(self):
660         """
661         Instantiates the CreateStack object that is responsible for downloading
662         and creating an OS stack file within OpenStack
663         """
664         super(self.__class__, self).__start__()
665
666         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
667
668         self.heat_creds = self.admin_os_creds
669         self.heat_creds.project_name = self.admin_os_creds.project_name
670
671         self.heat_cli = heat_utils.heat_client(self.heat_creds)
672         self.nova = nova_utils.nova_client(self.heat_creds)
673         self.stack_creator = None
674
675         self.keypair_name = self.guid + '-kp'
676
677         self.env_values = {
678             'keypair_name': self.keypair_name}
679
680         self.heat_tmplt_path = pkg_resources.resource_filename(
681             'snaps.openstack.tests.heat', 'keypair_heat_template.yaml')
682
683         stack_settings = StackSettings(
684             name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
685             template_path=self.heat_tmplt_path,
686             env_values=self.env_values)
687         self.stack_creator = create_stack.OpenStackHeatStack(
688             self.heat_creds, stack_settings)
689         self.created_stack = self.stack_creator.create()
690         self.assertIsNotNone(self.created_stack)
691
692     def tearDown(self):
693         """
694         Cleans the stack and downloaded stack file
695         """
696         if self.stack_creator:
697             try:
698                 self.stack_creator.clean()
699             except:
700                 pass
701
702         super(self.__class__, self).__clean__()
703
704     def test_retrieve_keypair_creator(self):
705         """
706         Tests the creation of an OpenStack stack from Heat template file and
707         the retrieval of an OpenStackKeypair creator/state machine instance
708         """
709         kp_creators = self.stack_creator.get_keypair_creators('private_key')
710         self.assertEqual(1, len(kp_creators))
711
712         creator = kp_creators[0]
713
714         self.assertEqual(self.keypair_name, creator.get_keypair().name)
715         self.assertIsNotNone(creator.keypair_settings.private_filepath)
716
717         private_file_contents = file_utils.read_file(
718             creator.keypair_settings.private_filepath)
719         self.assertTrue(private_file_contents.startswith(
720             '-----BEGIN RSA PRIVATE KEY-----'))
721
722         keypair = nova_utils.get_keypair_by_id(
723             self.nova, creator.get_keypair().id)
724         self.assertIsNotNone(keypair)
725         self.assertEqual(creator.get_keypair(), keypair)
726
727
728 class CreateStackNegativeTests(OSIntegrationTestCase):
729     """
730     Negative test cases for the CreateStack class
731     """
732
733     def setUp(self):
734         super(self.__class__, self).__start__()
735
736         self.heat_creds = self.admin_os_creds
737         self.heat_creds.project_name = self.admin_os_creds.project_name
738
739         self.stack_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
740         self.stack_creator = None
741         self.heat_tmplt_path = pkg_resources.resource_filename(
742             'snaps.openstack.tests.heat', 'test_heat_template.yaml')
743
744     def tearDown(self):
745         if self.stack_creator:
746             self.stack_creator.clean()
747         super(self.__class__, self).__clean__()
748
749     def test_missing_dependencies(self):
750         """
751         Expect an StackCreationError when the stack file does not exist
752         """
753         stack_settings = StackSettings(name=self.stack_name,
754                                        template_path=self.heat_tmplt_path)
755         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
756                                                              stack_settings)
757         with self.assertRaises(HTTPBadRequest):
758             self.stack_creator.create()
759
760     def test_bad_stack_file(self):
761         """
762         Expect an StackCreationError when the stack file does not exist
763         """
764         stack_settings = StackSettings(name=self.stack_name,
765                                        template_path='foo')
766         self.stack_creator = create_stack.OpenStackHeatStack(self.heat_creds,
767                                                              stack_settings)
768         with self.assertRaises(IOError):
769             self.stack_creator.create()