NSB: fix port topology
[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", netattrs["external_network"], "bar-fool-network-subnet")
123         mock_template.add_router_interface.assert_called_with("bar-fool-network-router-if0", "bar-fool-network-router", "bar-fool-network-subnet")
124
125     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
126     def test_attrs_get(self, mock_template):
127         image, flavor, user = expected_tuple = 'foo1', 'foo2', 'foo3'
128         self.assertNotEqual(self.test_context.image, image)
129         self.assertNotEqual(self.test_context.flavor, flavor)
130         self.assertNotEqual(self.test_context.user, user)
131         self.test_context._image = image
132         self.test_context._flavor = flavor
133         self.test_context._user = user
134         attr_tuple = self.test_context.image, self.test_context.flavor, self.test_context.user
135         self.assertEqual(attr_tuple, expected_tuple)
136
137     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
138     def test_attrs_set_negative(self, mock_template):
139         with self.assertRaises(AttributeError):
140             self.test_context.image = 'foo'
141
142         with self.assertRaises(AttributeError):
143             self.test_context.flavor = 'foo'
144
145         with self.assertRaises(AttributeError):
146             self.test_context.user = 'foo'
147
148     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
149     def test_deploy(self, mock_template):
150         self.test_context.name = 'foo'
151         self.test_context.template_file = '/bar/baz/some-heat-file'
152         self.test_context.heat_parameters = {'image': 'cirros'}
153         self.test_context.get_neutron_info = mock.MagicMock()
154         self.test_context.deploy()
155
156         mock_template.assert_called_with('foo',
157                                          '/bar/baz/some-heat-file',
158                                          {'image': 'cirros'})
159         self.assertIsNotNone(self.test_context.stack)
160
161     def test_add_server_port(self):
162         network1 = mock.MagicMock()
163         network2 = mock.MagicMock()
164         self.test_context.name = 'foo'
165         self.test_context.stack = mock.MagicMock()
166         self.test_context.networks = {
167             'a': network1,
168             'c': network2,
169         }
170         self.test_context.stack.outputs = {
171             u'b': u'10.20.30.45',
172             u'b-subnet_id': 1,
173             u'foo-a-subnet-cidr': u'10.20.0.0/15',
174             u'foo-a-subnet-gateway_ip': u'10.20.30.1',
175             u'b-mac_address': u'00:01',
176             u'b-device_id': u'dev21',
177             u'b-network_id': u'net789',
178             u'd': u'40.30.20.15',
179             u'd-subnet_id': 2,
180             u'foo-c-subnet-cidr': u'40.30.0.0/18',
181             u'foo-c-subnet-gateway_ip': u'40.30.20.254',
182             u'd-mac_address': u'00:10',
183             u'd-device_id': u'dev43',
184             u'd-network_id': u'net987',
185             u'e': u'40.30.20.15',
186             u'e-subnet_id': 2,
187             u'e-mac_address': u'00:10',
188             u'e-device_id': u'dev43',
189             u'e-network_id': u'net987',
190         }
191         server = mock.MagicMock()
192         server.ports = OrderedDict([
193             ('a', [{'stack_name': 'b', 'port': 'port_a'}]),
194             ('c', [{'stack_name': 'd', 'port': 'port_c'},
195                    {'stack_name': 'e', 'port': 'port_f'}]),
196         ])
197
198         expected = {
199             "private_ip": '10.20.30.45',
200             "subnet_id": 1,
201             "subnet_cidr": '10.20.0.0/15',
202             "network": '10.20.0.0',
203             "netmask": '255.254.0.0',
204             "gateway_ip": '10.20.30.1',
205             "mac_address": '00:01',
206             "device_id": 'dev21',
207             "network_id": 'net789',
208             "network_name": 'a',
209             "local_mac": '00:01',
210             "local_ip": '10.20.30.45',
211         }
212         self.test_context.add_server_port(server)
213         self.assertEqual(server.private_ip, '10.20.30.45')
214         self.assertEqual(len(server.interfaces), 3)
215         self.assertDictEqual(server.interfaces['port_a'], expected)
216
217     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
218     def test_undeploy(self, mock_template):
219         self.test_context.stack = mock_template
220         self.test_context.undeploy()
221         self.assertTrue(mock_template.delete.called)
222
223     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
224     @mock.patch('yardstick.benchmark.contexts.heat.os')
225     def test_undeploy_key_filename(self, mock_template, mock_os):
226         self.test_context.stack = mock_template
227         mock_os.path.exists.return_value = True
228         self.assertIsNone(self.test_context.undeploy())
229
230     def test__get_server_found_dict(self):
231         """
232         Use HeatContext._get_server to get a server that matches
233         based on a dictionary input.
234         """
235         foo2_server = mock.Mock()
236         foo2_server.key_filename = 'key_file'
237         foo2_server.private_ip = '10.0.0.2'
238         foo2_server.public_ip = '127.0.0.2'
239         foo2_server.context.user = 'oof'
240
241         baz3_server = mock.Mock()
242         baz3_server.key_filename = 'key_filename'
243         baz3_server.private_ip = '10.0.0.3'
244         baz3_server.public_ip = '127.0.0.3'
245         baz3_server.context.user = 'zab'
246
247         self.test_context.name = 'bar'
248         self.test_context._user = 'bot'
249         self.test_context.stack = mock.Mock()
250         self.test_context.stack.outputs = {
251             'private_ip': '10.0.0.1',
252             'public_ip': '127.0.0.1',
253         }
254         self.test_context.key_uuid = uuid.uuid4()
255         self.test_context._server_map = {
256             'baz3': baz3_server,
257             'foo2': foo2_server,
258         }
259
260         attr_name = {
261             'name': 'foo.bar',
262             'private_ip_attr': 'private_ip',
263             'public_ip_attr': 'public_ip',
264         }
265         result = self.test_context._get_server(attr_name)
266         self.assertEqual(result['user'], 'bot')
267         self.assertIsNotNone(result['key_filename'])
268         self.assertEqual(result['ip'], '127.0.0.1')
269         self.assertEqual(result['private_ip'], '10.0.0.1')
270
271     def test__get_server_found_dict_no_attrs(self):
272         """
273         Use HeatContext._get_server to get a server that matches
274         based on a dictionary input.
275         """
276         foo2_server = mock.Mock()
277         foo2_server.private_ip = '10.0.0.2'
278         foo2_server.public_ip = '127.0.0.2'
279         foo2_server.context.user = 'oof'
280
281         baz3_server = mock.Mock()
282         baz3_server.private_ip = '10.0.0.3'
283         baz3_server.public_ip = '127.0.0.3'
284         baz3_server.context.user = 'zab'
285
286         self.test_context.name = 'bar'
287         self.test_context._user = 'bot'
288         self.test_context.stack = mock.Mock()
289         self.test_context.stack.outputs = {
290             'private_ip': '10.0.0.1',
291             'public_ip': '127.0.0.1',
292         }
293         self.test_context.key_uuid = uuid.uuid4()
294         self.test_context._server_map = {
295             'baz3': baz3_server,
296             'foo2': foo2_server,
297         }
298
299         attr_name = {
300             'name': 'foo.bar',
301         }
302         result = self.test_context._get_server(attr_name)
303         self.assertEqual(result['user'], 'bot')
304         self.assertIsNotNone(result['key_filename'])
305         # no private ip attr mapping in the map results in None value in the result
306         self.assertIsNone(result['private_ip'])
307         # no public ip attr mapping in the map results in no value in the result
308         self.assertNotIn('ip', result)
309
310     def test__get_server_found_not_dict(self):
311         """
312         Use HeatContext._get_server to get a server that matches
313         based on a non-dictionary input
314         """
315         foo2_server = mock.Mock()
316         foo2_server.private_ip = '10.0.0.2'
317         foo2_server.public_ip = '127.0.0.2'
318         foo2_server.context.user = 'oof'
319
320         baz3_server = mock.Mock()
321         baz3_server.private_ip = '10.0.0.3'
322         baz3_server.public_ip = None
323         baz3_server.context.user = 'zab'
324
325         self.test_context.name = 'bar1'
326         self.test_context.stack = mock.Mock()
327         self.test_context.stack.outputs = {
328             'private_ip': '10.0.0.1',
329             'public_ip': '127.0.0.1',
330         }
331         self.test_context.key_uuid = uuid.uuid4()
332         self.test_context.generate_routing_table = mock.MagicMock(return_value=[])
333
334         self.test_context._server_map = {
335             'baz3': baz3_server,
336             'foo2': foo2_server,
337         }
338
339         attr_name = 'baz3'
340         result = self.test_context._get_server(attr_name)
341         self.assertEqual(result['user'], 'zab')
342         self.assertIsNotNone(result['key_filename'])
343         self.assertEqual(result['private_ip'], '10.0.0.3')
344         # no public_ip on the server results in no value in the result
345         self.assertNotIn('public_ip', result)
346
347     def test__get_server_none_found_not_dict(self):
348         """
349         Use HeatContext._get_server to not get a server due to
350         None value associated with the match to a non-dictionary
351         input
352         """
353         foo2_server = mock.Mock()
354         foo2_server.private_ip = '10.0.0.2'
355         foo2_server.public_ip = '127.0.0.2'
356         foo2_server.context.user = 'oof'
357
358         baz3_server = mock.Mock()
359         baz3_server.private_ip = '10.0.0.3'
360         baz3_server.public_ip = None
361         baz3_server.context.user = 'zab'
362
363         self.test_context.name = 'bar1'
364         self.test_context.stack = mock.Mock()
365         self.test_context.stack.outputs = {
366             'private_ip': '10.0.0.1',
367             'public_ip': '127.0.0.1',
368         }
369         self.test_context.key_uuid = uuid.uuid4()
370         self.test_context._server_map = {
371             'baz3': baz3_server,
372             'foo2': foo2_server,
373             'wow4': None,
374         }
375
376         attr_name = 'wow4'
377         result = self.test_context._get_server(attr_name)
378         self.assertIsNone(result)
379
380     def test__get_server_not_found_dict(self):
381         """
382         Use HeatContext._get_server to not get a server for lack
383         of a match to a dictionary input
384         """
385         foo2_server = mock.Mock()
386         foo2_server.private_ip = '10.0.0.2'
387         foo2_server.public_ip = '127.0.0.2'
388         foo2_server.context.user = 'oof'
389
390         baz3_server = mock.Mock()
391         baz3_server.private_ip = '10.0.0.3'
392         baz3_server.public_ip = None
393         baz3_server.context.user = 'zab'
394
395         self.test_context.name = 'bar1'
396         self.test_context.stack = mock.Mock()
397         self.test_context.stack.outputs = {
398             'private_ip': '10.0.0.1',
399             'public_ip': '127.0.0.1',
400         }
401         self.test_context.key_uuid = uuid.uuid4()
402         self.test_context._server_map = {
403             'baz3': baz3_server,
404             'foo2': foo2_server,
405         }
406
407         attr_name = {
408             'name': 'foo.wow4',
409             'private_ip_attr': 'private_ip',
410             'public_ip_attr': 'public_ip',
411         }
412         result = self.test_context._get_server(attr_name)
413         self.assertIsNone(result)
414
415     def test__get_server_not_found_not_dict(self):
416         """
417         Use HeatContext._get_server to not get a server for lack
418         of a match to a non-dictionary input
419         """
420         foo2_server = mock.Mock()
421         foo2_server.private_ip = '10.0.0.2'
422         foo2_server.public_ip = '127.0.0.2'
423         foo2_server.context.user = 'oof'
424
425         baz3_server = mock.Mock()
426         baz3_server.private_ip = '10.0.0.3'
427         baz3_server.public_ip = None
428         baz3_server.context.user = 'zab'
429
430         self.mock_context.name = 'bar1'
431         self.test_context.stack = mock.Mock()
432         self.mock_context.stack.outputs = {
433             'private_ip': '10.0.0.1',
434             'public_ip': '127.0.0.1',
435         }
436         self.mock_context.key_uuid = uuid.uuid4()
437         self.mock_context._server_map = {
438             'baz3': baz3_server,
439             'foo2': foo2_server,
440         }
441
442         attr_name = 'foo.wow4'
443         result = self.test_context._get_server(attr_name)
444         self.assertIsNone(result)
445
446     def test__get_network(self):
447         network1 = mock.MagicMock()
448         network1.name = 'net_1'
449         network1.vld_id = 'vld111'
450         network1.segmentation_id = 'seg54'
451         network1.network_type = 'type_a'
452         network1.physical_network = 'phys'
453
454         network2 = mock.MagicMock()
455         network2.name = 'net_2'
456         network2.segmentation_id = 'seg45'
457         network2.network_type = 'type_b'
458         network2.physical_network = 'virt'
459
460         self.test_context.networks = {
461             'a': network1,
462             'b': network2,
463         }
464
465         attr_name = None
466         self.assertIsNone(self.test_context._get_network(attr_name))
467
468         attr_name = {}
469         self.assertIsNone(self.test_context._get_network(attr_name))
470
471         attr_name = {'network_type': 'nosuch'}
472         self.assertIsNone(self.test_context._get_network(attr_name))
473
474         attr_name = 'vld777'
475         self.assertIsNone(self.test_context._get_network(attr_name))
476
477         attr_name = {'segmentation_id': 'seg45'}
478         expected = {
479             "name": 'net_2',
480             "segmentation_id": 'seg45',
481             "network_type": 'type_b',
482             "physical_network": 'virt',
483         }
484         result = self.test_context._get_network(attr_name)
485         self.assertDictEqual(result, expected)
486
487         attr_name = 'a'
488         expected = {
489             "name": 'net_1',
490             "segmentation_id": 'seg54',
491             "network_type": 'type_a',
492             "physical_network": 'phys',
493         }
494         result = self.test_context._get_network(attr_name)
495         self.assertDictEqual(result, expected)