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