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