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