Add qualified name to Context
[yardstick.git] / yardstick / tests / unit / orchestrator / test_heat.py
1 ##############################################################################
2 # Copyright (c) 2017 Intel Corporation
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 import tempfile
11
12 import mock
13 from oslo_serialization import jsonutils
14 from oslo_utils import uuidutils
15 import shade
16 import unittest
17
18 from yardstick.benchmark.contexts import node
19 from yardstick.common import exceptions
20 from yardstick.orchestrator import heat
21
22
23 class FakeStack(object):
24
25     def __init__(self, outputs=None, status=None, id=None):
26         self.outputs = outputs
27         self.status = status
28         self.id = id
29
30
31 class HeatStackTestCase(unittest.TestCase):
32
33     def setUp(self):
34         self.stack_name = 'STACK NAME'
35         with mock.patch.object(shade, 'openstack_cloud'):
36             self.heatstack = heat.HeatStack(self.stack_name)
37         self._mock_stack_create = mock.patch.object(self.heatstack._cloud,
38                                                     'create_stack')
39         self.mock_stack_create = self._mock_stack_create.start()
40         self._mock_stack_delete = mock.patch.object(self.heatstack._cloud,
41                                                     'delete_stack')
42         self.mock_stack_delete = self._mock_stack_delete.start()
43
44         self.addCleanup(self._cleanup)
45
46     def _cleanup(self):
47         self._mock_stack_create.stop()
48         self._mock_stack_delete.stop()
49         heat._DEPLOYED_STACKS = {}
50
51     def test_create(self):
52         template = {'tkey': 'tval'}
53         heat_parameters = {'pkey': 'pval'}
54         outputs = [{'output_key': 'okey', 'output_value': 'oval'}]
55         id = uuidutils.generate_uuid()
56         self.mock_stack_create.return_value = FakeStack(
57             outputs=outputs, status=mock.Mock(), id=id)
58         mock_tfile = mock.Mock()
59         with mock.patch.object(tempfile._TemporaryFileWrapper, '__enter__',
60                                return_value=mock_tfile):
61             self.heatstack.create(template, heat_parameters, True, 100)
62             mock_tfile.write.assert_called_once_with(jsonutils.dump_as_bytes(template))
63             mock_tfile.close.assert_called_once()
64
65         self.mock_stack_create.assert_called_once_with(
66             self.stack_name, template_file=mock_tfile.name, wait=True,
67             timeout=100, pkey='pval')
68         self.assertEqual({'okey': 'oval'}, self.heatstack.outputs)
69         self.assertEqual(heat._DEPLOYED_STACKS[id], self.heatstack._stack)
70
71     def test_stacks_exist(self):
72         self.assertEqual(0, self.heatstack.stacks_exist())
73         heat._DEPLOYED_STACKS['id'] = 'stack'
74         self.assertEqual(1, self.heatstack.stacks_exist())
75
76     def test_delete_not_uuid(self):
77         self.assertIsNone(self.heatstack.delete())
78
79     def test_delete_existing_uuid(self):
80         id = uuidutils.generate_uuid()
81         self.heatstack._stack = FakeStack(
82             outputs=mock.Mock(), status=mock.Mock(), id=id)
83         heat._DEPLOYED_STACKS[id] = self.heatstack._stack
84         delete_return = mock.Mock()
85         self.mock_stack_delete.return_value = delete_return
86
87         ret = self.heatstack.delete(wait=True)
88         self.assertEqual(delete_return, ret)
89         self.assertFalse(heat._DEPLOYED_STACKS)
90         self.mock_stack_delete.assert_called_once_with(id, wait=True)
91
92     def test_delete_bug_in_shade(self):
93         id = uuidutils.generate_uuid()
94         self.heatstack._stack = FakeStack(
95             outputs=mock.Mock(), status=mock.Mock(), id=id)
96         heat._DEPLOYED_STACKS[id] = self.heatstack._stack
97         self.mock_stack_delete.side_effect = TypeError()
98
99         ret = self.heatstack.delete(wait=True)
100         self.assertTrue(ret)
101         self.assertFalse(heat._DEPLOYED_STACKS)
102         self.mock_stack_delete.assert_called_once_with(id, wait=True)
103
104
105 class HeatTemplateTestCase(unittest.TestCase):
106
107     def setUp(self):
108         self.template = heat.HeatTemplate('test')
109
110     def test_add_tenant_network(self):
111         self.template.add_network('some-network')
112
113         self.assertEqual('OS::Neutron::Net',
114                          self.template.resources['some-network']['type'])
115
116     def test_add_provider_network(self):
117         self.template.add_network('some-network', 'physnet2', 'sriov')
118
119         self.assertEqual(self.template.resources['some-network']['type'],
120                          'OS::Neutron::ProviderNet')
121         self.assertEqual(self.template.resources['some-network'][
122                              'properties']['physical_network'], 'physnet2')
123
124     def test_add_subnet(self):
125         netattrs = {'cidr': '10.0.0.0/24',
126                     'provider': None,
127                     'external_network': 'ext_net'}
128         self.template.add_subnet('some-subnet', "some-network",
129                                  netattrs['cidr'])
130
131         self.assertEqual(self.template.resources['some-subnet']['type'],
132                          'OS::Neutron::Subnet')
133         self.assertEqual(self.template.resources['some-subnet']['properties'][
134                              'cidr'], '10.0.0.0/24')
135
136     def test_add_router(self):
137         self.template.add_router('some-router', 'ext-net', 'some-subnet')
138
139         self.assertEqual(self.template.resources['some-router']['type'],
140                          'OS::Neutron::Router')
141         self.assertIn('some-subnet',
142                       self.template.resources['some-router']['depends_on'])
143
144     def test_add_router_interface(self):
145         self.template.add_router_interface('some-router-if', 'some-router',
146                                            'some-subnet')
147
148         self.assertEqual(self.template.resources['some-router-if']['type'],
149                          'OS::Neutron::RouterInterface')
150         self.assertIn('some-subnet',
151                       self.template.resources['some-router-if']['depends_on'])
152
153     def test_add_servergroup(self):
154         self.template.add_servergroup('some-server-group', 'anti-affinity')
155
156         self.assertEqual(self.template.resources['some-server-group']['type'],
157                          'OS::Nova::ServerGroup')
158         self.assertEqual(self.template.resources['some-server-group'][
159                              'properties']['policies'], ['anti-affinity'])
160
161     def test__add_resources_to_template_raw(self):
162         test_context = node.NodeContext()
163         self.addCleanup(test_context._delete_context)
164         test_context._name = 'foo'
165         test_context.template_file = '/tmp/some-heat-file'
166         test_context.heat_parameters = {'image': 'cirros'}
167         test_context.key_filename = "/tmp/1234"
168         test_context.keypair_name = "foo-key"
169         test_context.secgroup_name = "foo-secgroup"
170         test_context.key_uuid = "2f2e4997-0a8e-4eb7-9fa4-f3f8fbbc393b"
171
172         test_context.tmpfile = tempfile.NamedTemporaryFile(
173             delete=True, mode='w+t')
174         test_context.tmpfile.write("heat_template_version: 2015-04-30")
175         test_context.tmpfile.flush()
176         test_context.tmpfile.seek(0)
177         heat_template = heat.HeatTemplate('template name')
178         heat_template.resources = {}
179
180         heat_template.add_network("network1")
181         heat_template.add_network("network2")
182         heat_template.add_security_group("sec_group1")
183         heat_template.add_security_group("sec_group2")
184         heat_template.add_subnet("subnet1", "network1", "cidr1")
185         heat_template.add_subnet("subnet2", "network2", "cidr2")
186         heat_template.add_router("router1", "gw1", "subnet1")
187         heat_template.add_router_interface("router_if1", "router1", "subnet1")
188         heat_template.add_port("port1", "network1", "subnet1", "normal")
189         heat_template.add_port("port2", "network2", "subnet2", "normal",
190                                sec_group_id="sec_group1", provider="not-sriov")
191         heat_template.add_port("port3", "network2", "subnet2", "normal",
192                                sec_group_id="sec_group1", provider="sriov")
193         heat_template.add_floating_ip("floating_ip1", "network1", "port1",
194                                       "router_if1")
195         heat_template.add_floating_ip("floating_ip2", "network2", "port2",
196                                       "router_if2", "foo-secgroup")
197         heat_template.add_floating_ip_association("floating_ip1_association",
198                                                   "floating_ip1", "port1")
199         heat_template.add_servergroup("server_grp2", "affinity")
200         heat_template.add_servergroup("server_grp3", "anti-affinity")
201         heat_template.add_security_group("security_group")
202         heat_template.add_server(name="server1", image="image1",
203                                  flavor="flavor1", flavors=[])
204         heat_template.add_server_group(name="servergroup",
205                                        policies=["policy1", "policy2"])
206         heat_template.add_server_group(name="servergroup",
207                                        policies="policy1")
208         heat_template.add_server(
209             name="server2", image="image1", flavor="flavor1", flavors=[],
210             ports=["port1", "port2"], networks=["network1", "network2"],
211             scheduler_hints="hints1", user="user1", key_name="foo-key",
212             user_data="user", metadata={"cat": 1, "doc": 2},
213             additional_properties={"prop1": 1, "prop2": 2})
214         heat_template.add_server(
215             name="server2", image="image1", flavor="flavor1",
216             flavors=["flavor1", "flavor2"], ports=["port1", "port2"],
217             networks=["network1", "network2"], scheduler_hints="hints1",
218             user="user1", key_name="foo-key", user_data="user",
219             metadata={"cat": 1, "doc": 2},
220             additional_properties={"prop1": 1, "prop2": 2})
221         heat_template.add_server(
222             name="server2", image="image1", flavor="flavor1",
223             flavors=["flavor3", "flavor4"], ports=["port1", "port2"],
224             networks=["network1", "network2"], scheduler_hints="hints1",
225             user="user1", key_name="foo-key", user_data="user",
226             metadata={"cat": 1, "doc": 2},
227             additional_properties={"prop1": 1, "prop2": 2})
228         heat_template.add_flavor(name="flavor1", vcpus=1, ram=2048, disk=1,
229                                  extra_specs={"cat": 1, "dog": 2})
230         heat_template.add_flavor(name=None, vcpus=1, ram=2048)
231         heat_template.add_server(
232             name="server1", image="image1", flavor="flavor1", flavors=[],
233             ports=["port1", "port2"], networks=["network1", "network2"],
234             scheduler_hints="hints1", user="user1", key_name="foo-key",
235             user_data="user", metadata={"cat": 1, "doc": 2},
236             additional_properties={"prop1": 1, "prop2": 2})
237         heat_template.add_network("network1")
238
239         heat_template.add_flavor("test")
240         self.assertEqual(heat_template.resources['test']['type'],
241                          'OS::Nova::Flavor')
242
243     def test_create_not_block(self):
244         heat_stack = mock.Mock()
245         with mock.patch.object(heat, 'HeatStack', return_value=heat_stack):
246             ret = self.template.create(block=False)
247         heat_stack.create.assert_called_once_with(
248             self.template._template, self.template.heat_parameters, False,
249             3600)
250         self.assertEqual(heat_stack, ret)
251
252     def test_create_block(self):
253         heat_stack = mock.Mock()
254         heat_stack.status = self.template.HEAT_STATUS_COMPLETE
255         with mock.patch.object(heat, 'HeatStack', return_value=heat_stack):
256             ret = self.template.create(block=False)
257         heat_stack.create.assert_called_once_with(
258             self.template._template, self.template.heat_parameters, False,
259             3600)
260         self.assertEqual(heat_stack, ret)
261
262
263     def test_create_block_status_no_complete(self):
264         heat_stack = mock.Mock()
265         heat_stack.status = 'other status'
266         with mock.patch.object(heat, 'HeatStack', return_value=heat_stack):
267             self.assertRaises(exceptions.HeatTemplateError,
268                               self.template.create, block=True)
269         heat_stack.create.assert_called_once_with(
270             self.template._template, self.template.heat_parameters, True,
271             3600)