Merge "Add service in kubernetes context"
[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     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
231     def test__get_server_found_dict(self, mock_pkg_resources):
232         """
233         Use HeatContext._get_server to get a server that matches
234         based on a dictionary input.
235         """
236         foo2_server = mock.Mock()
237         foo2_server.key_filename = None
238         foo2_server.private_ip = '10.0.0.2'
239         foo2_server.public_ip = '127.0.0.2'
240         foo2_server.context.user = 'oof'
241
242         baz3_server = mock.Mock()
243         baz3_server.key_filename = None
244         baz3_server.private_ip = '10.0.0.3'
245         baz3_server.public_ip = '127.0.0.3'
246         baz3_server.context.user = 'zab'
247
248         self.test_context.name = 'bar'
249         self.test_context._user = 'bot'
250         self.test_context.stack = mock.Mock()
251         self.test_context.stack.outputs = {
252             'private_ip': '10.0.0.1',
253             'public_ip': '127.0.0.1',
254         }
255         self.test_context.key_uuid = uuid.uuid4()
256         self.test_context._server_map = {
257             'baz3': baz3_server,
258             'foo2': foo2_server,
259         }
260
261         attr_name = {
262             'name': 'foo.bar',
263             'private_ip_attr': 'private_ip',
264             'public_ip_attr': 'public_ip',
265         }
266         result = self.test_context._get_server(attr_name)
267         self.assertEqual(result['user'], 'bot')
268         self.assertEqual(result['ip'], '127.0.0.1')
269         self.assertEqual(result['private_ip'], '10.0.0.1')
270
271     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
272     def test__get_server_found_dict_no_attrs(self, mock_pkg_resources):
273         """
274         Use HeatContext._get_server to get a server that matches
275         based on a dictionary input.
276         """
277         foo2_server = mock.Mock()
278         foo2_server.private_ip = '10.0.0.2'
279         foo2_server.public_ip = '127.0.0.2'
280         foo2_server.context.user = 'oof'
281
282         baz3_server = mock.Mock()
283         baz3_server.private_ip = '10.0.0.3'
284         baz3_server.public_ip = '127.0.0.3'
285         baz3_server.context.user = 'zab'
286
287         self.test_context.name = 'bar'
288         self.test_context._user = 'bot'
289         self.test_context.stack = mock.Mock()
290         self.test_context.stack.outputs = {
291             'private_ip': '10.0.0.1',
292             'public_ip': '127.0.0.1',
293         }
294         self.test_context.key_uuid = uuid.uuid4()
295         self.test_context._server_map = {
296             'baz3': baz3_server,
297             'foo2': foo2_server,
298         }
299
300         attr_name = {
301             'name': 'foo.bar',
302         }
303         result = self.test_context._get_server(attr_name)
304         self.assertEqual(result['user'], 'bot')
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     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
311     def test__get_server_found_not_dict(self, mock_pkg_resources):
312         """
313         Use HeatContext._get_server to get a server that matches
314         based on a non-dictionary input
315         """
316         foo2_server = mock.Mock()
317         foo2_server.private_ip = '10.0.0.2'
318         foo2_server.public_ip = '127.0.0.2'
319         foo2_server.context.user = 'oof'
320
321         baz3_server = mock.Mock()
322         baz3_server.private_ip = '10.0.0.3'
323         baz3_server.public_ip = None
324         baz3_server.context.user = 'zab'
325
326         self.test_context.name = 'bar1'
327         self.test_context.stack = mock.Mock()
328         self.test_context.stack.outputs = {
329             'private_ip': '10.0.0.1',
330             'public_ip': '127.0.0.1',
331         }
332         self.test_context.key_uuid = uuid.uuid4()
333         self.test_context.generate_routing_table = mock.MagicMock(return_value=[])
334
335         self.test_context._server_map = {
336             'baz3': baz3_server,
337             'foo2': foo2_server,
338         }
339
340         attr_name = 'baz3'
341         result = self.test_context._get_server(attr_name)
342         self.assertEqual(result['user'], 'zab')
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     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
348     def test__get_server_none_found_not_dict(self, mock_pkg_resources):
349         """
350         Use HeatContext._get_server to not get a server due to
351         None value associated with the match to a non-dictionary
352         input
353         """
354         foo2_server = mock.Mock()
355         foo2_server.private_ip = '10.0.0.2'
356         foo2_server.public_ip = '127.0.0.2'
357         foo2_server.context.user = 'oof'
358
359         baz3_server = mock.Mock()
360         baz3_server.private_ip = '10.0.0.3'
361         baz3_server.public_ip = None
362         baz3_server.context.user = 'zab'
363
364         self.test_context.name = 'bar1'
365         self.test_context.stack = mock.Mock()
366         self.test_context.stack.outputs = {
367             'private_ip': '10.0.0.1',
368             'public_ip': '127.0.0.1',
369         }
370         self.test_context.key_uuid = uuid.uuid4()
371         self.test_context._server_map = {
372             'baz3': baz3_server,
373             'foo2': foo2_server,
374             'wow4': None,
375         }
376
377         attr_name = 'wow4'
378         result = self.test_context._get_server(attr_name)
379         self.assertIsNone(result)
380
381     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
382     def test__get_server_not_found_dict(self, mock_pkg_resources):
383         """
384         Use HeatContext._get_server to not get a server for lack
385         of a match to a dictionary input
386         """
387         foo2_server = mock.Mock()
388         foo2_server.private_ip = '10.0.0.2'
389         foo2_server.public_ip = '127.0.0.2'
390         foo2_server.context.user = 'oof'
391
392         baz3_server = mock.Mock()
393         baz3_server.private_ip = '10.0.0.3'
394         baz3_server.public_ip = None
395         baz3_server.context.user = 'zab'
396
397         self.test_context.name = 'bar1'
398         self.test_context.stack = mock.Mock()
399         self.test_context.stack.outputs = {
400             'private_ip': '10.0.0.1',
401             'public_ip': '127.0.0.1',
402         }
403         self.test_context.key_uuid = uuid.uuid4()
404         self.test_context._server_map = {
405             'baz3': baz3_server,
406             'foo2': foo2_server,
407         }
408
409         attr_name = {
410             'name': 'foo.wow4',
411             'private_ip_attr': 'private_ip',
412             'public_ip_attr': 'public_ip',
413         }
414         result = self.test_context._get_server(attr_name)
415         self.assertIsNone(result)
416
417     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
418     def test__get_server_not_found_not_dict(self, mock_pkg_resources):
419         """
420         Use HeatContext._get_server to not get a server for lack
421         of a match to a non-dictionary input
422         """
423         foo2_server = mock.Mock()
424         foo2_server.private_ip = '10.0.0.2'
425         foo2_server.public_ip = '127.0.0.2'
426         foo2_server.context.user = 'oof'
427
428         baz3_server = mock.Mock()
429         baz3_server.private_ip = '10.0.0.3'
430         baz3_server.public_ip = None
431         baz3_server.context.user = 'zab'
432
433         self.mock_context.name = 'bar1'
434         self.test_context.stack = mock.Mock()
435         self.mock_context.stack.outputs = {
436             'private_ip': '10.0.0.1',
437             'public_ip': '127.0.0.1',
438         }
439         self.mock_context.key_uuid = uuid.uuid4()
440         self.mock_context._server_map = {
441             'baz3': baz3_server,
442             'foo2': foo2_server,
443         }
444
445         attr_name = 'foo.wow4'
446         result = self.test_context._get_server(attr_name)
447         self.assertIsNone(result)
448
449     def test__get_network(self):
450         network1 = mock.MagicMock()
451         network1.name = 'net_1'
452         network1.vld_id = 'vld111'
453         network1.segmentation_id = 'seg54'
454         network1.network_type = 'type_a'
455         network1.physical_network = 'phys'
456
457         network2 = mock.MagicMock()
458         network2.name = 'net_2'
459         network2.segmentation_id = 'seg45'
460         network2.network_type = 'type_b'
461         network2.physical_network = 'virt'
462
463         self.test_context.networks = {
464             'a': network1,
465             'b': network2,
466         }
467
468         attr_name = None
469         self.assertIsNone(self.test_context._get_network(attr_name))
470
471         attr_name = {}
472         self.assertIsNone(self.test_context._get_network(attr_name))
473
474         attr_name = {'network_type': 'nosuch'}
475         self.assertIsNone(self.test_context._get_network(attr_name))
476
477         attr_name = 'vld777'
478         self.assertIsNone(self.test_context._get_network(attr_name))
479
480         attr_name = {'segmentation_id': 'seg45'}
481         expected = {
482             "name": 'net_2',
483             "segmentation_id": 'seg45',
484             "network_type": 'type_b',
485             "physical_network": 'virt',
486         }
487         result = self.test_context._get_network(attr_name)
488         self.assertDictEqual(result, expected)
489
490         attr_name = 'a'
491         expected = {
492             "name": 'net_1',
493             "segmentation_id": 'seg54',
494             "network_type": 'type_a',
495             "physical_network": 'phys',
496         }
497         result = self.test_context._get_network(attr_name)
498         self.assertDictEqual(result, expected)