Extra changes on Flavor Config
[snaps.git] / snaps / openstack / tests / create_flavor_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 unittest
16 import uuid
17
18 from snaps.config.flavor import FlavorConfig, FlavorConfigError
19 from snaps.openstack import create_flavor
20 from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings
21 from snaps.openstack.tests.os_source_file_test import OSComponentTestCase
22 from snaps.openstack.utils import nova_utils
23 from snaps.openstack.tests import openstack_tests
24
25 __author__ = 'spisarski'
26
27
28 class FlavorSettingsUnitTests(unittest.TestCase):
29     """
30     Tests the construction of the FlavorSettings class
31     """
32
33     def test_no_params(self):
34         with self.assertRaises(FlavorConfigError):
35             FlavorSettings()
36
37     def test_empty_config(self):
38         with self.assertRaises(FlavorConfigError):
39             FlavorSettings(config=dict())
40
41     def test_name_only(self):
42         with self.assertRaises(FlavorConfigError):
43             FlavorSettings(name='foo')
44
45     def test_config_with_name_only(self):
46         with self.assertRaises(FlavorConfigError):
47             FlavorSettings(config={'name': 'foo'})
48
49     def test_name_ram_only(self):
50         with self.assertRaises(FlavorConfigError):
51             FlavorSettings(name='foo', ram=1)
52
53     def test_config_with_name_ram_only(self):
54         with self.assertRaises(FlavorConfigError):
55             FlavorSettings(config={'name': 'foo', 'ram': 1})
56
57     def test_name_ram_disk_only(self):
58         with self.assertRaises(FlavorConfigError):
59             FlavorSettings(name='foo', ram=1, disk=1)
60
61     def test_config_with_name_ram_disk_only(self):
62         with self.assertRaises(FlavorConfigError):
63             FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 1})
64
65     def test_ram_string(self):
66         with self.assertRaises(FlavorConfigError):
67             FlavorSettings(name='foo', ram='bar', disk=2, vcpus=3, ephemeral=4,
68                            swap=5, rxtx_factor=6.0,
69                            is_public=False)
70
71     def test_config_ram_string(self):
72         with self.assertRaises(FlavorConfigError):
73             FlavorSettings(
74                 config={'name': 'foo', 'ram': 'bar', 'disk': 2, 'vcpus': 3,
75                         'ephemeral': 4, 'swap': 5,
76                         'rxtx_factor': 6.0, 'is_public': False})
77
78     def test_ram_float(self):
79         with self.assertRaises(FlavorConfigError):
80             FlavorSettings(name='foo', ram=1.5, disk=2, vcpus=3, ephemeral=4,
81                            swap=5, rxtx_factor=6.0, is_public=False)
82
83     def test_config_ram_float(self):
84         with self.assertRaises(FlavorConfigError):
85             FlavorSettings(
86                 config={'name': 'foo', 'ram': 1.5, 'disk': 2, 'vcpus': 3,
87                         'ephemeral': 4, 'swap': 5,
88                         'rxtx_factor': 6.0, 'is_public': False})
89
90     def test_disk_string(self):
91         with self.assertRaises(FlavorConfigError):
92             FlavorSettings(name='foo', ram=1, disk='bar', vcpus=3, ephemeral=4,
93                            swap=5, rxtx_factor=6.0,
94                            is_public=False)
95
96     def test_config_disk_string(self):
97         with self.assertRaises(FlavorConfigError):
98             FlavorSettings(
99                 config={'name': 'foo', 'ram': 1, 'disk': 'bar', 'vcpus': 3,
100                         'ephemeral': 4, 'swap': 5,
101                         'rxtx_factor': 6.0, 'is_public': False})
102
103     def test_disk_float(self):
104         with self.assertRaises(FlavorConfigError):
105             FlavorSettings(name='foo', ram=1, disk=2.5, vcpus=3, ephemeral=4,
106                            swap=5, rxtx_factor=6.0, is_public=False)
107
108     def test_config_disk_float(self):
109         with self.assertRaises(FlavorConfigError):
110             FlavorSettings(
111                 config={'name': 'foo', 'ram': 1, 'disk': 2.5, 'vcpus': 3,
112                         'ephemeral': 4, 'swap': 5,
113                         'rxtx_factor': 6.0, 'is_public': False})
114
115     def test_vcpus_string(self):
116         with self.assertRaises(FlavorConfigError):
117             FlavorSettings(name='foo', ram=1, disk=2, vcpus='bar', ephemeral=4,
118                            swap=5, rxtx_factor=6.0,
119                            is_public=False)
120
121     def test_config_vcpus_string(self):
122         with self.assertRaises(FlavorConfigError):
123             FlavorSettings(
124                 config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 'bar',
125                         'ephemeral': 4, 'swap': 5,
126                         'rxtx_factor': 6.0, 'is_public': False})
127
128     def test_ephemeral_string(self):
129         with self.assertRaises(FlavorConfigError):
130             FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral='bar',
131                            swap=5, rxtx_factor=6.0,
132                            is_public=False)
133
134     def test_config_ephemeral_string(self):
135         with self.assertRaises(FlavorConfigError):
136             FlavorSettings(
137                 config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3,
138                         'ephemeral': 'bar', 'swap': 5,
139                         'rxtx_factor': 6.0, 'is_public': False})
140
141     def test_ephemeral_float(self):
142         with self.assertRaises(FlavorConfigError):
143             FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4.5,
144                            swap=5, rxtx_factor=6.0, is_public=False)
145
146     def test_config_ephemeral_float(self):
147         with self.assertRaises(FlavorConfigError):
148             FlavorSettings(
149                 config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3,
150                         'ephemeral': 4.5, 'swap': 5,
151                         'rxtx_factor': 6.0, 'is_public': False})
152
153     def test_swap_string(self):
154         with self.assertRaises(FlavorConfigError):
155             FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4,
156                            swap='bar', rxtx_factor=6.0,
157                            is_public=False)
158
159     def test_config_swap_string(self):
160         with self.assertRaises(FlavorConfigError):
161             FlavorSettings(
162                 config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3,
163                         'ephemeral': 4, 'swap': 'bar',
164                         'rxtx_factor': 6.0, 'is_public': False})
165
166     def test_swap_float(self):
167         with self.assertRaises(FlavorConfigError):
168             FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4,
169                            swap=5.5, rxtx_factor=6.0, is_public=False)
170
171     def test_config_swap_float(self):
172         with self.assertRaises(FlavorConfigError):
173             FlavorSettings(
174                 config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3,
175                         'ephemeral': 4, 'swap': 5.5,
176                         'rxtx_factor': 6.0, 'is_public': False})
177
178     def test_rxtx_string(self):
179         with self.assertRaises(FlavorConfigError):
180             FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4,
181                            swap=5, rxtx_factor='bar', is_public=False)
182
183     def test_config_rxtx_string(self):
184         with self.assertRaises(FlavorConfigError):
185             FlavorSettings(
186                 config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3,
187                         'ephemeral': 4, 'swap': 5,
188                         'rxtx_factor': 'bar', 'is_public': False})
189
190     def test_is_pub_string(self):
191         with self.assertRaises(FlavorConfigError):
192             FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4,
193                            swap=5, rxtx_factor=6.0, is_public='bar')
194
195     def test_config_is_pub_string(self):
196         with self.assertRaises(FlavorConfigError):
197             FlavorSettings(
198                 config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3,
199                         'ephemeral': 4, 'swap': 5,
200                         'rxtx_factor': 6.0, 'is_public': 'bar'})
201
202     def test_name_ram_disk_vcpus_only(self):
203         settings = FlavorSettings(name='foo', ram=1, disk=2, vcpus=3)
204         self.assertEqual('foo', settings.name)
205         self.assertEqual('auto', settings.flavor_id)
206         self.assertEqual(1, settings.ram)
207         self.assertEqual(2, settings.disk)
208         self.assertEqual(3, settings.vcpus)
209         self.assertEqual(0, settings.ephemeral)
210         self.assertEqual(0, settings.swap)
211         self.assertEqual(1.0, settings.rxtx_factor)
212         self.assertEqual(True, settings.is_public)
213         self.assertEqual(None, settings.metadata)
214
215     def test_config_with_name_ram_disk_vcpus_only(self):
216         settings = FlavorSettings(
217             **{'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3})
218         self.assertEqual('foo', settings.name)
219         self.assertEqual('auto', settings.flavor_id)
220         self.assertEqual(1, settings.ram)
221         self.assertEqual(2, settings.disk)
222         self.assertEqual(3, settings.vcpus)
223         self.assertEqual(0, settings.ephemeral)
224         self.assertEqual(0, settings.swap)
225         self.assertEqual(1.0, settings.rxtx_factor)
226         self.assertEqual(True, settings.is_public)
227         self.assertEqual(None, settings.metadata)
228
229     def test_all(self):
230         metadata = {'foo': 'bar'}
231         settings = FlavorSettings(
232             name='foo', flavor_id='bar', ram=1, disk=2, vcpus=3, ephemeral=4,
233             swap=5, rxtx_factor=6.0, is_public=False, metadata=metadata)
234         self.assertEqual('foo', settings.name)
235         self.assertEqual('bar', settings.flavor_id)
236         self.assertEqual(1, settings.ram)
237         self.assertEqual(2, settings.disk)
238         self.assertEqual(3, settings.vcpus)
239         self.assertEqual(4, settings.ephemeral)
240         self.assertEqual(5, settings.swap)
241         self.assertEqual(6.0, settings.rxtx_factor)
242         self.assertEqual(False, settings.is_public)
243         self.assertEqual(metadata, settings.metadata)
244
245     def test_config_all(self):
246         metadata = {'foo': 'bar'}
247         settings = FlavorSettings(
248             **{'name': 'foo', 'flavor_id': 'bar', 'ram': 1, 'disk': 2,
249                'vcpus': 3,
250                'ephemeral': 4, 'swap': 5, 'rxtx_factor': 6.0,
251                'is_public': False,
252                'metadata': metadata})
253         self.assertEqual('foo', settings.name)
254         self.assertEqual('bar', settings.flavor_id)
255         self.assertEqual(1, settings.ram)
256         self.assertEqual(2, settings.disk)
257         self.assertEqual(3, settings.vcpus)
258         self.assertEqual(4, settings.ephemeral)
259         self.assertEqual(5, settings.swap)
260         self.assertEqual(6.0, settings.rxtx_factor)
261         self.assertEqual(False, settings.is_public)
262         self.assertEqual(metadata, settings.metadata)
263
264
265 class CreateFlavorTests(OSComponentTestCase):
266     """
267     Test for the CreateSecurityGroup class defined in create_security_group.py
268     """
269
270     def setUp(self):
271         """
272         Instantiates the CreateSecurityGroup object that is responsible for
273         downloading and creating an OS image file within OpenStack
274         """
275         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
276         self.flavor_name = guid + 'name'
277
278         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
279
280         # Initialize for cleanup
281         self.flavor_creator = None
282
283     def tearDown(self):
284         """
285         Cleans the image and downloaded image file
286         """
287         if self.flavor_creator:
288             self.flavor_creator.clean()
289
290         super(self.__class__, self).__clean__()
291
292     def test_create_flavor(self):
293         """
294         Tests the creation of an OpenStack flavor.
295         """
296         # Create Flavor
297         flavor_settings = FlavorConfig(
298             name=self.flavor_name, ram=1, disk=1, vcpus=1)
299         self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
300         flavor = self.flavor_creator.create()
301         self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
302
303     def test_create_flavor_existing(self):
304         """
305         Tests the creation of an OpenStack flavor then starts another creator
306         to ensure it has not been done twice.
307         """
308         # Create Flavor
309         flavor_settings = FlavorConfig(
310             name=self.flavor_name, ram=1, disk=1, vcpus=1)
311         self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
312         flavor = self.flavor_creator.create()
313         self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
314
315         flavor_creator_2 = OpenStackFlavor(self.os_creds, flavor_settings)
316         flavor2 = flavor_creator_2.create()
317
318         self.assertEqual(flavor.id, flavor2.id)
319
320     def test_create_clean_flavor(self):
321         """
322         Tests the creation and cleanup of an OpenStack flavor.
323         """
324         # Create Flavor
325         flavor_settings = FlavorConfig(
326             name=self.flavor_name, ram=1, disk=1, vcpus=1)
327         self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
328         flavor = self.flavor_creator.create()
329         self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
330
331         # Clean Flavor
332         self.flavor_creator.clean()
333
334         self.assertIsNone(self.flavor_creator.get_flavor())
335         self.assertIsNone(
336             nova_utils.get_flavor_by_name(self.nova, flavor_settings.name))
337
338     def test_create_delete_flavor(self):
339         """
340         Tests the creation of an OpenStack Flavor, the deletion, then
341         cleanup to ensure clean() does not
342         raise any exceptions.
343         """
344         # Create Flavor
345         flavor_settings = FlavorConfig(
346             name=self.flavor_name, ram=1, disk=1, vcpus=1)
347         self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
348         flavor = self.flavor_creator.create()
349         self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
350
351         # Delete Flavor
352         nova_utils.delete_flavor(self.nova, flavor)
353         self.assertIsNone(
354             nova_utils.get_flavor_by_name(self.nova, flavor_settings.name))
355
356         # Attempt to cleanup
357         self.flavor_creator.clean()
358
359         self.assertIsNone(self.flavor_creator.get_flavor())
360
361     def test_create_flavor_all_settings(self):
362         """
363         Tests the creation of an OpenStack Flavor, the deletion, then
364         cleanup to ensure clean() does not
365         raise any exceptions.
366         """
367         # Create Flavor
368         if self.flavor_metadata:
369             self.flavor_metadata.update(create_flavor.MEM_PAGE_SIZE_ANY)
370         flavor_settings = openstack_tests.get_flavor_config(
371             name=self.flavor_name, ram=1, disk=1, vcpus=1, ephemeral=2, swap=3,
372             rxtx_factor=2.2, is_public=False,
373             metadata=self.flavor_metadata)
374         self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
375         flavor = self.flavor_creator.create()
376         self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
377
378         # Delete Flavor
379         nova_utils.delete_flavor(self.nova, flavor)
380         self.assertIsNone(
381             nova_utils.get_flavor_by_name(self.nova, flavor_settings.name))
382
383         # Attempt to cleanup
384         self.flavor_creator.clean()
385
386         self.assertIsNone(self.flavor_creator.get_flavor())
387
388
389 def validate_flavor(nova, flavor_settings, flavor):
390     """
391     Validates the flavor_settings against the OpenStack flavor object
392     :param nova: the nova client
393     :param flavor_settings: the settings used to create the flavor
394     :param flavor: the OpenStack flavor object
395     """
396     setting_meta = dict()
397     if flavor_settings.metadata:
398         setting_meta = flavor_settings.metadata
399     metadata = nova_utils.get_flavor_keys(nova, flavor)
400
401     equals = True
402     for key, value in setting_meta.items():
403         if metadata[key] != value:
404             equals = False
405             break
406
407     swap = None
408     if flavor_settings.swap != 0:
409         swap = flavor_settings.swap
410
411     return (
412         flavor is not None and
413         flavor_settings.name == flavor.name and
414         flavor_settings.ram == flavor.ram and
415         flavor_settings.disk == flavor.disk and
416         flavor_settings.vcpus == flavor.vcpus and
417         flavor_settings.ephemeral == flavor.ephemeral and
418         swap == flavor.swap and
419         flavor_settings.rxtx_factor == flavor.rxtx_factor and
420         flavor_settings.is_public == flavor.is_public and
421         equals)