1 ##############################################################################
2 # Copyright (c) 2017 Intel Corporation
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 ##############################################################################
13 from oslo_serialization import jsonutils
14 from oslo_utils import uuidutils
18 from yardstick.benchmark.contexts import node
19 from yardstick.common import exceptions
20 from yardstick.orchestrator import heat
23 class FakeStack(object):
25 def __init__(self, outputs=None, status=None, id=None):
26 self.outputs = outputs
31 class HeatStackTestCase(unittest.TestCase):
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,
39 self.mock_stack_create = self._mock_stack_create.start()
40 self._mock_stack_delete = mock.patch.object(self.heatstack._cloud,
42 self.mock_stack_delete = self._mock_stack_delete.start()
44 self.addCleanup(self._cleanup)
47 self._mock_stack_create.stop()
48 self._mock_stack_delete.stop()
49 heat._DEPLOYED_STACKS = {}
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()
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)
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())
76 def test_delete_not_uuid(self):
77 self.assertIsNone(self.heatstack.delete())
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
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)
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()
99 ret = self.heatstack.delete(wait=True)
101 self.assertFalse(heat._DEPLOYED_STACKS)
102 self.mock_stack_delete.assert_called_once_with(id, wait=True)
105 class HeatTemplateTestCase(unittest.TestCase):
108 self.template = heat.HeatTemplate('test')
110 def test_add_tenant_network(self):
111 self.template.add_network('some-network')
113 self.assertEqual('OS::Neutron::Net',
114 self.template.resources['some-network']['type'])
116 def test_add_provider_network(self):
117 self.template.add_network('some-network', 'physnet2', 'sriov')
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')
124 def test_add_subnet(self):
125 netattrs = {'cidr': '10.0.0.0/24',
127 'external_network': 'ext_net'}
128 self.template.add_subnet('some-subnet', "some-network",
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')
136 def test_add_router(self):
137 self.template.add_router('some-router', 'ext-net', 'some-subnet')
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'])
144 def test_add_router_interface(self):
145 self.template.add_router_interface('some-router-if', 'some-router',
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'])
153 def test_add_servergroup(self):
154 self.template.add_servergroup('some-server-group', 'anti-affinity')
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'])
161 def test__add_resources_to_template_raw(self):
162 test_context = node.NodeContext()
163 test_context.name = 'foo'
164 test_context.template_file = '/tmp/some-heat-file'
165 test_context.heat_parameters = {'image': 'cirros'}
166 test_context.key_filename = "/tmp/1234"
167 test_context.keypair_name = "foo-key"
168 test_context.secgroup_name = "foo-secgroup"
169 test_context.key_uuid = "2f2e4997-0a8e-4eb7-9fa4-f3f8fbbc393b"
171 test_context.tmpfile = tempfile.NamedTemporaryFile(
172 delete=True, mode='w+t')
173 test_context.tmpfile.write("heat_template_version: 2015-04-30")
174 test_context.tmpfile.flush()
175 test_context.tmpfile.seek(0)
176 heat_template = heat.HeatTemplate('template name')
177 heat_template.resources = {}
179 heat_template.add_network("network1")
180 heat_template.add_network("network2")
181 heat_template.add_security_group("sec_group1")
182 heat_template.add_security_group("sec_group2")
183 heat_template.add_subnet("subnet1", "network1", "cidr1")
184 heat_template.add_subnet("subnet2", "network2", "cidr2")
185 heat_template.add_router("router1", "gw1", "subnet1")
186 heat_template.add_router_interface("router_if1", "router1", "subnet1")
187 heat_template.add_port("port1", "network1", "subnet1", "normal")
188 heat_template.add_port("port2", "network2", "subnet2", "normal",
189 sec_group_id="sec_group1", provider="not-sriov")
190 heat_template.add_port("port3", "network2", "subnet2", "normal",
191 sec_group_id="sec_group1", provider="sriov")
192 heat_template.add_floating_ip("floating_ip1", "network1", "port1",
194 heat_template.add_floating_ip("floating_ip2", "network2", "port2",
195 "router_if2", "foo-secgroup")
196 heat_template.add_floating_ip_association("floating_ip1_association",
197 "floating_ip1", "port1")
198 heat_template.add_servergroup("server_grp2", "affinity")
199 heat_template.add_servergroup("server_grp3", "anti-affinity")
200 heat_template.add_security_group("security_group")
201 heat_template.add_server(name="server1", image="image1",
202 flavor="flavor1", flavors=[])
203 heat_template.add_server_group(name="servergroup",
204 policies=["policy1", "policy2"])
205 heat_template.add_server_group(name="servergroup",
207 heat_template.add_server(
208 name="server2", image="image1", flavor="flavor1", flavors=[],
209 ports=["port1", "port2"], networks=["network1", "network2"],
210 scheduler_hints="hints1", user="user1", key_name="foo-key",
211 user_data="user", metadata={"cat": 1, "doc": 2},
212 additional_properties={"prop1": 1, "prop2": 2})
213 heat_template.add_server(
214 name="server2", image="image1", flavor="flavor1",
215 flavors=["flavor1", "flavor2"], ports=["port1", "port2"],
216 networks=["network1", "network2"], scheduler_hints="hints1",
217 user="user1", key_name="foo-key", user_data="user",
218 metadata={"cat": 1, "doc": 2},
219 additional_properties={"prop1": 1, "prop2": 2})
220 heat_template.add_server(
221 name="server2", image="image1", flavor="flavor1",
222 flavors=["flavor3", "flavor4"], ports=["port1", "port2"],
223 networks=["network1", "network2"], scheduler_hints="hints1",
224 user="user1", key_name="foo-key", user_data="user",
225 metadata={"cat": 1, "doc": 2},
226 additional_properties={"prop1": 1, "prop2": 2})
227 heat_template.add_flavor(name="flavor1", vcpus=1, ram=2048, disk=1,
228 extra_specs={"cat": 1, "dog": 2})
229 heat_template.add_flavor(name=None, vcpus=1, ram=2048)
230 heat_template.add_server(
231 name="server1", image="image1", flavor="flavor1", flavors=[],
232 ports=["port1", "port2"], networks=["network1", "network2"],
233 scheduler_hints="hints1", user="user1", key_name="foo-key",
234 user_data="user", metadata={"cat": 1, "doc": 2},
235 additional_properties={"prop1": 1, "prop2": 2})
236 heat_template.add_network("network1")
238 heat_template.add_flavor("test")
239 self.assertEqual(heat_template.resources['test']['type'],
242 def test_create_not_block(self):
243 heat_stack = mock.Mock()
244 with mock.patch.object(heat, 'HeatStack', return_value=heat_stack):
245 ret = self.template.create(block=False)
246 heat_stack.create.assert_called_once_with(
247 self.template._template, self.template.heat_parameters, False,
249 self.assertEqual(heat_stack, ret)
251 def test_create_block(self):
252 heat_stack = mock.Mock()
253 heat_stack.status = self.template.HEAT_STATUS_COMPLETE
254 with mock.patch.object(heat, 'HeatStack', return_value=heat_stack):
255 ret = self.template.create(block=False)
256 heat_stack.create.assert_called_once_with(
257 self.template._template, self.template.heat_parameters, False,
259 self.assertEqual(heat_stack, ret)
262 def test_create_block_status_no_complete(self):
263 heat_stack = mock.Mock()
264 heat_stack.status = 'other status'
265 with mock.patch.object(heat, 'HeatStack', return_value=heat_stack):
266 self.assertRaises(exceptions.HeatTemplateError,
267 self.template.create, block=True)
268 heat_stack.create.assert_called_once_with(
269 self.template._template, self.template.heat_parameters, True,