update docs for procedure after host reboot
[yardstick.git] / tests / unit / benchmark / contexts / test_heat.py
1 #!/usr/bin/env python
2
3 ##############################################################################
4 # Copyright (c) 2015 Ericsson AB and others.
5 #
6 # All rights reserved. This program and the accompanying materials
7 # are made available under the terms of the Apache License, Version 2.0
8 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
10 ##############################################################################
11
12 # Unittest for yardstick.benchmark.contexts.heat
13
14 from __future__ import absolute_import
15
16 import logging
17 import os
18 import unittest
19 import uuid
20 from collections import OrderedDict
21
22 import mock
23
24 from itertools import count
25 from yardstick.benchmark.contexts import heat
26 from yardstick.benchmark.contexts import model
27
28 LOG = logging.getLogger(__name__)
29
30
31 class HeatContextTestCase(unittest.TestCase):
32
33     def __init__(self, *args, **kwargs):
34         super(HeatContextTestCase, self).__init__(*args, **kwargs)
35         self.name_iter = ('vnf{:03}'.format(x) for x in count(0, step=3))
36
37     def setUp(self):
38         self.test_context = heat.HeatContext()
39         self.mock_context = mock.Mock(spec=heat.HeatContext())
40
41     def test___init__(self):
42         self.assertIsNone(self.test_context.name)
43         self.assertIsNone(self.test_context.stack)
44         self.assertEqual(self.test_context.networks, OrderedDict())
45         self.assertEqual(self.test_context.servers, [])
46         self.assertEqual(self.test_context.placement_groups, [])
47         self.assertEqual(self.test_context.server_groups, [])
48         self.assertIsNone(self.test_context.keypair_name)
49         self.assertIsNone(self.test_context.secgroup_name)
50         self.assertEqual(self.test_context._server_map, {})
51         self.assertIsNone(self.test_context._image)
52         self.assertIsNone(self.test_context._flavor)
53         self.assertIsNone(self.test_context._user)
54         self.assertIsNone(self.test_context.template_file)
55         self.assertIsNone(self.test_context.heat_parameters)
56         self.assertIsNotNone(self.test_context.key_uuid)
57         self.assertIsNotNone(self.test_context.key_filename)
58
59     @mock.patch('yardstick.benchmark.contexts.heat.PlacementGroup')
60     @mock.patch('yardstick.benchmark.contexts.heat.ServerGroup')
61     @mock.patch('yardstick.benchmark.contexts.heat.Network')
62     @mock.patch('yardstick.benchmark.contexts.heat.Server')
63     def test_init(self, mock_server, mock_network, mock_sg, mock_pg):
64
65         pgs = {'pgrp1': {'policy': 'availability'}}
66         sgs = {'servergroup1': {'policy': 'affinity'}}
67         networks = {'bar': {'cidr': '10.0.1.0/24'}}
68         servers = {'baz': {'floating_ip': True, 'placement': 'pgrp1'}}
69         attrs = {'name': 'foo',
70                  'placement_groups': pgs,
71                  'server_groups': sgs,
72                  'networks': networks,
73                  'servers': servers}
74
75         self.test_context.init(attrs)
76
77         self.assertEqual(self.test_context.name, "foo")
78         self.assertEqual(self.test_context.keypair_name, "foo-key")
79         self.assertEqual(self.test_context.secgroup_name, "foo-secgroup")
80
81         mock_pg.assert_called_with('pgrp1', self.test_context,
82                                    pgs['pgrp1']['policy'])
83         mock_sg.assert_called_with('servergroup1', self.test_context,
84                                    sgs['servergroup1']['policy'])
85         self.assertTrue(len(self.test_context.placement_groups) == 1)
86         self.assertTrue(len(self.test_context.server_groups) == 1)
87
88         mock_network.assert_called_with(
89             'bar', self.test_context, networks['bar'])
90         self.assertTrue(len(self.test_context.networks) == 1)
91
92         mock_server.assert_called_with('baz', self.test_context,
93                                        servers['baz'])
94         self.assertTrue(len(self.test_context.servers) == 1)
95
96         if os.path.exists(self.test_context.key_filename):
97             try:
98                 os.remove(self.test_context.key_filename)
99                 os.remove(self.test_context.key_filename + ".pub")
100             except OSError:
101                 LOG.exception("key_filename: %s",
102                               self.test_context.key_filename)
103
104     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
105     def test__add_resources_to_template_no_servers(self, mock_template):
106
107         self.test_context.keypair_name = "foo-key"
108         self.test_context.secgroup_name = "foo-secgroup"
109         self.test_context.key_uuid = "2f2e4997-0a8e-4eb7-9fa4-f3f8fbbc393b"
110         netattrs = {'cidr': '10.0.0.0/24', 'provider': None, 'external_network': 'ext_net'}
111         self.mock_context.name = 'bar'
112         self.test_context.networks = OrderedDict(
113             {"fool-network": model.Network("fool-network", self.mock_context,
114                                            netattrs)})
115
116         self.test_context._add_resources_to_template(mock_template)
117         mock_template.add_keypair.assert_called_with(
118             "foo-key",
119             "2f2e4997-0a8e-4eb7-9fa4-f3f8fbbc393b")
120         mock_template.add_security_group.assert_called_with("foo-secgroup")
121 #        mock_template.add_network.assert_called_with("bar-fool-network", 'physnet1', None)
122         mock_template.add_router.assert_called_with("bar-fool-network-router",
123                                                     netattrs["external_network"],
124                                                     "bar-fool-network-subnet")
125         mock_template.add_router_interface.assert_called_with("bar-fool-network-router-if0",
126                                                               "bar-fool-network-router",
127                                                               "bar-fool-network-subnet")
128
129     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
130     def test_attrs_get(self, mock_template):
131         image, flavor, user = expected_tuple = 'foo1', 'foo2', 'foo3'
132         self.assertNotEqual(self.test_context.image, image)
133         self.assertNotEqual(self.test_context.flavor, flavor)
134         self.assertNotEqual(self.test_context.user, user)
135         self.test_context._image = image
136         self.test_context._flavor = flavor
137         self.test_context._user = user
138         attr_tuple = self.test_context.image, self.test_context.flavor, self.test_context.user
139         self.assertEqual(attr_tuple, expected_tuple)
140
141     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
142     def test_attrs_set_negative(self, mock_template):
143         with self.assertRaises(AttributeError):
144             self.test_context.image = 'foo'
145
146         with self.assertRaises(AttributeError):
147             self.test_context.flavor = 'foo'
148
149         with self.assertRaises(AttributeError):
150             self.test_context.user = 'foo'
151
152     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
153     def test_deploy(self, mock_template):
154         self.test_context.name = 'foo'
155         self.test_context.template_file = '/bar/baz/some-heat-file'
156         self.test_context.heat_parameters = {'image': 'cirros'}
157         self.test_context.get_neutron_info = mock.MagicMock()
158         self.test_context.deploy()
159
160         mock_template.assert_called_with('foo',
161                                          '/bar/baz/some-heat-file',
162                                          {'image': 'cirros'})
163         self.assertIsNotNone(self.test_context.stack)
164
165     def test_add_server_port(self):
166         network1 = mock.MagicMock()
167         network2 = mock.MagicMock()
168         self.test_context.name = 'foo'
169         self.test_context.stack = mock.MagicMock()
170         self.test_context.networks = {
171             'a': network1,
172             'c': network2,
173         }
174         self.test_context.stack.outputs = {
175             u'b': u'10.20.30.45',
176             u'b-subnet_id': 1,
177             u'foo-a-subnet-cidr': u'10.20.0.0/15',
178             u'foo-a-subnet-gateway_ip': u'10.20.30.1',
179             u'b-mac_address': u'00:01',
180             u'b-device_id': u'dev21',
181             u'b-network_id': u'net789',
182             u'd': u'40.30.20.15',
183             u'd-subnet_id': 2,
184             u'foo-c-subnet-cidr': u'40.30.0.0/18',
185             u'foo-c-subnet-gateway_ip': u'40.30.20.254',
186             u'd-mac_address': u'00:10',
187             u'd-device_id': u'dev43',
188             u'd-network_id': u'net987',
189             u'e': u'40.30.20.15',
190             u'e-subnet_id': 2,
191             u'e-mac_address': u'00:10',
192             u'e-device_id': u'dev43',
193             u'e-network_id': u'net987',
194         }
195         server = mock.MagicMock()
196         server.ports = OrderedDict([
197             ('a', [{'stack_name': 'b', 'port': 'port_a'}]),
198             ('c', [{'stack_name': 'd', 'port': 'port_c'},
199                    {'stack_name': 'e', 'port': 'port_f'}]),
200         ])
201
202         expected = {
203             "private_ip": '10.20.30.45',
204             "subnet_id": 1,
205             "subnet_cidr": '10.20.0.0/15',
206             "network": '10.20.0.0',
207             "netmask": '255.254.0.0',
208             "name": "port_a",
209             "gateway_ip": '10.20.30.1',
210             "mac_address": '00:01',
211             "device_id": 'dev21',
212             "network_id": 'net789',
213             "network_name": 'a',
214             "local_mac": '00:01',
215             "local_ip": '10.20.30.45',
216         }
217         self.test_context.add_server_port(server)
218         self.assertEqual(server.private_ip, '10.20.30.45')
219         self.assertEqual(len(server.interfaces), 3)
220         self.assertDictEqual(server.interfaces['port_a'], expected)
221
222     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
223     def test_undeploy(self, mock_template):
224         self.test_context.stack = mock_template
225         self.test_context.undeploy()
226         self.assertTrue(mock_template.delete.called)
227
228     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
229     @mock.patch('yardstick.benchmark.contexts.heat.os')
230     def test_undeploy_key_filename(self, mock_template, mock_os):
231         self.test_context.stack = mock_template
232         mock_os.path.exists.return_value = True
233         self.assertIsNone(self.test_context.undeploy())
234
235     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
236     def test__get_server_found_dict(self, mock_pkg_resources):
237         """
238         Use HeatContext._get_server to get a server that matches
239         based on a dictionary input.
240         """
241         foo2_server = mock.Mock()
242         foo2_server.key_filename = None
243         foo2_server.private_ip = '10.0.0.2'
244         foo2_server.public_ip = '127.0.0.2'
245         foo2_server.context.user = 'oof'
246
247         baz3_server = mock.Mock()
248         baz3_server.key_filename = None
249         baz3_server.private_ip = '10.0.0.3'
250         baz3_server.public_ip = '127.0.0.3'
251         baz3_server.context.user = 'zab'
252
253         self.test_context.name = 'bar'
254         self.test_context._user = 'bot'
255         self.test_context.stack = mock.Mock()
256         self.test_context.stack.outputs = {
257             'private_ip': '10.0.0.1',
258             'public_ip': '127.0.0.1',
259         }
260         self.test_context.key_uuid = uuid.uuid4()
261         self.test_context._server_map = {
262             'baz3': baz3_server,
263             'foo2': foo2_server,
264         }
265
266         attr_name = {
267             'name': 'foo.bar',
268             'private_ip_attr': 'private_ip',
269             'public_ip_attr': 'public_ip',
270         }
271         result = self.test_context._get_server(attr_name)
272         self.assertEqual(result['user'], 'bot')
273         self.assertEqual(result['ip'], '127.0.0.1')
274         self.assertEqual(result['private_ip'], '10.0.0.1')
275
276     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
277     def test__get_server_found_dict_no_attrs(self, mock_pkg_resources):
278         """
279         Use HeatContext._get_server to get a server that matches
280         based on a dictionary input.
281         """
282         foo2_server = mock.Mock()
283         foo2_server.private_ip = '10.0.0.2'
284         foo2_server.public_ip = '127.0.0.2'
285         foo2_server.context.user = 'oof'
286
287         baz3_server = mock.Mock()
288         baz3_server.private_ip = '10.0.0.3'
289         baz3_server.public_ip = '127.0.0.3'
290         baz3_server.context.user = 'zab'
291
292         self.test_context.name = 'bar'
293         self.test_context._user = 'bot'
294         self.test_context.stack = mock.Mock()
295         self.test_context.stack.outputs = {
296             'private_ip': '10.0.0.1',
297             'public_ip': '127.0.0.1',
298         }
299         self.test_context.key_uuid = uuid.uuid4()
300         self.test_context._server_map = {
301             'baz3': baz3_server,
302             'foo2': foo2_server,
303         }
304
305         attr_name = {
306             'name': 'foo.bar',
307         }
308         result = self.test_context._get_server(attr_name)
309         self.assertEqual(result['user'], 'bot')
310         # no private ip attr mapping in the map results in None value in the result
311         self.assertIsNone(result['private_ip'])
312         # no public ip attr mapping in the map results in no value in the result
313         self.assertNotIn('ip', result)
314
315     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
316     def test__get_server_found_not_dict(self, mock_pkg_resources):
317         """
318         Use HeatContext._get_server to get a server that matches
319         based on a non-dictionary input
320         """
321         foo2_server = mock.Mock()
322         foo2_server.private_ip = '10.0.0.2'
323         foo2_server.public_ip = '127.0.0.2'
324         foo2_server.context.user = 'oof'
325
326         baz3_server = mock.Mock()
327         baz3_server.private_ip = '10.0.0.3'
328         baz3_server.public_ip = None
329         baz3_server.context.user = 'zab'
330
331         self.test_context.name = 'bar1'
332         self.test_context.stack = mock.Mock()
333         self.test_context.stack.outputs = {
334             'private_ip': '10.0.0.1',
335             'public_ip': '127.0.0.1',
336         }
337         self.test_context.key_uuid = uuid.uuid4()
338         self.test_context.generate_routing_table = mock.MagicMock(return_value=[])
339
340         self.test_context._server_map = {
341             'baz3': baz3_server,
342             'foo2': foo2_server,
343         }
344
345         attr_name = 'baz3'
346         result = self.test_context._get_server(attr_name)
347         self.assertEqual(result['user'], 'zab')
348         self.assertEqual(result['private_ip'], '10.0.0.3')
349         # no public_ip on the server results in no value in the result
350         self.assertNotIn('public_ip', result)
351
352     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
353     def test__get_server_none_found_not_dict(self, mock_pkg_resources):
354         """
355         Use HeatContext._get_server to not get a server due to
356         None value associated with the match to a non-dictionary
357         input
358         """
359         foo2_server = mock.Mock()
360         foo2_server.private_ip = '10.0.0.2'
361         foo2_server.public_ip = '127.0.0.2'
362         foo2_server.context.user = 'oof'
363
364         baz3_server = mock.Mock()
365         baz3_server.private_ip = '10.0.0.3'
366         baz3_server.public_ip = None
367         baz3_server.context.user = 'zab'
368
369         self.test_context.name = 'bar1'
370         self.test_context.stack = mock.Mock()
371         self.test_context.stack.outputs = {
372             'private_ip': '10.0.0.1',
373             'public_ip': '127.0.0.1',
374         }
375         self.test_context.key_uuid = uuid.uuid4()
376         self.test_context._server_map = {
377             'baz3': baz3_server,
378             'foo2': foo2_server,
379             'wow4': None,
380         }
381
382         attr_name = 'wow4'
383         result = self.test_context._get_server(attr_name)
384         self.assertIsNone(result)
385
386     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
387     def test__get_server_not_found_dict(self, mock_pkg_resources):
388         """
389         Use HeatContext._get_server to not get a server for lack
390         of a match to a dictionary input
391         """
392         foo2_server = mock.Mock()
393         foo2_server.private_ip = '10.0.0.2'
394         foo2_server.public_ip = '127.0.0.2'
395         foo2_server.context.user = 'oof'
396
397         baz3_server = mock.Mock()
398         baz3_server.private_ip = '10.0.0.3'
399         baz3_server.public_ip = None
400         baz3_server.context.user = 'zab'
401
402         self.test_context.name = 'bar1'
403         self.test_context.stack = mock.Mock()
404         self.test_context.stack.outputs = {
405             'private_ip': '10.0.0.1',
406             'public_ip': '127.0.0.1',
407         }
408         self.test_context.key_uuid = uuid.uuid4()
409         self.test_context._server_map = {
410             'baz3': baz3_server,
411             'foo2': foo2_server,
412         }
413
414         attr_name = {
415             'name': 'foo.wow4',
416             'private_ip_attr': 'private_ip',
417             'public_ip_attr': 'public_ip',
418         }
419         result = self.test_context._get_server(attr_name)
420         self.assertIsNone(result)
421
422     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
423     def test__get_server_not_found_not_dict(self, mock_pkg_resources):
424         """
425         Use HeatContext._get_server to not get a server for lack
426         of a match to a non-dictionary input
427         """
428         foo2_server = mock.Mock()
429         foo2_server.private_ip = '10.0.0.2'
430         foo2_server.public_ip = '127.0.0.2'
431         foo2_server.context.user = 'oof'
432
433         baz3_server = mock.Mock()
434         baz3_server.private_ip = '10.0.0.3'
435         baz3_server.public_ip = None
436         baz3_server.context.user = 'zab'
437
438         self.mock_context.name = 'bar1'
439         self.test_context.stack = mock.Mock()
440         self.mock_context.stack.outputs = {
441             'private_ip': '10.0.0.1',
442             'public_ip': '127.0.0.1',
443         }
444         self.mock_context.key_uuid = uuid.uuid4()
445         self.mock_context._server_map = {
446             'baz3': baz3_server,
447             'foo2': foo2_server,
448         }
449
450         attr_name = 'foo.wow4'
451         result = self.test_context._get_server(attr_name)
452         self.assertIsNone(result)
453
454     def test__get_network(self):
455         network1 = mock.MagicMock()
456         network1.name = 'net_1'
457         network1.vld_id = 'vld111'
458         network1.segmentation_id = 'seg54'
459         network1.network_type = 'type_a'
460         network1.physical_network = 'phys'
461
462         network2 = mock.MagicMock()
463         network2.name = 'net_2'
464         network2.segmentation_id = 'seg45'
465         network2.network_type = 'type_b'
466         network2.physical_network = 'virt'
467
468         self.test_context.networks = {
469             'a': network1,
470             'b': network2,
471         }
472
473         attr_name = None
474         self.assertIsNone(self.test_context._get_network(attr_name))
475
476         attr_name = {}
477         self.assertIsNone(self.test_context._get_network(attr_name))
478
479         attr_name = {'network_type': 'nosuch'}
480         self.assertIsNone(self.test_context._get_network(attr_name))
481
482         attr_name = 'vld777'
483         self.assertIsNone(self.test_context._get_network(attr_name))
484
485         attr_name = {'segmentation_id': 'seg45'}
486         expected = {
487             "name": 'net_2',
488             "segmentation_id": 'seg45',
489             "network_type": 'type_b',
490             "physical_network": 'virt',
491         }
492         result = self.test_context._get_network(attr_name)
493         self.assertDictEqual(result, expected)
494
495         attr_name = 'a'
496         expected = {
497             "name": 'net_1',
498             "segmentation_id": 'seg54',
499             "network_type": 'type_a',
500             "physical_network": 'phys',
501         }
502         result = self.test_context._get_network(attr_name)
503         self.assertDictEqual(result, expected)