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