blob: 971e9c5c768c4196170d732a7c24a6a9c4388eec [file] [log] [blame]
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -05001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -050013from heat_integrationtests.functional import functional_base
14
15test_template_one_resource = {
16 'heat_template_version': '2013-05-23',
17 'description': 'Test template to create one instance.',
18 'resources': {
19 'test1': {
20 'type': 'OS::Heat::TestResource',
21 'properties': {
22 'value': 'Test1',
23 'fail': False,
24 'update_replace': False,
25 'wait_secs': 0
26 }
27 }
28 }
29}
30
31test_template_two_resource = {
32 'heat_template_version': '2013-05-23',
33 'description': 'Test template to create two instance.',
34 'resources': {
35 'test1': {
36 'type': 'OS::Heat::TestResource',
37 'properties': {
38 'value': 'Test1',
39 'fail': False,
40 'update_replace': False,
41 'wait_secs': 0
42 }
43 },
44 'test2': {
45 'type': 'OS::Heat::TestResource',
46 'properties': {
47 'value': 'Test1',
48 'fail': False,
49 'update_replace': False,
50 'wait_secs': 0
51 }
52 }
53 }
54}
55
56
Steven Hardye6de2d62015-12-07 15:59:09 +000057class UpdatePreviewBase(functional_base.FunctionalTestsBase):
58
59 def assert_empty_sections(self, changes, empty_sections):
60 for section in empty_sections:
61 self.assertEqual([], changes[section])
62
63
64class UpdatePreviewStackTest(UpdatePreviewBase):
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -050065
Steven Hardy09ae1b02016-01-18 11:31:52 +000066 def test_add_resource(self):
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -050067 self.stack_identifier = self.stack_create(
68 template=test_template_one_resource)
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -050069 result = self.preview_update_stack(self.stack_identifier,
70 test_template_two_resource)
71 changes = result['resource_changes']
72
73 unchanged = changes['unchanged'][0]['resource_name']
74 self.assertEqual('test1', unchanged)
75
76 added = changes['added'][0]['resource_name']
77 self.assertEqual('test2', added)
78
Steven Hardye6de2d62015-12-07 15:59:09 +000079 self.assert_empty_sections(changes, ['updated', 'replaced', 'deleted'])
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -050080
81 def test_no_change(self):
Steven Hardy09ae1b02016-01-18 11:31:52 +000082 self.stack_identifier = self.stack_create(
83 template=test_template_one_resource)
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -050084 result = self.preview_update_stack(self.stack_identifier,
85 test_template_one_resource)
86 changes = result['resource_changes']
87
88 unchanged = changes['unchanged'][0]['resource_name']
89 self.assertEqual('test1', unchanged)
90
Steven Hardye6de2d62015-12-07 15:59:09 +000091 self.assert_empty_sections(
92 changes, ['updated', 'replaced', 'deleted', 'added'])
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -050093
94 def test_update_resource(self):
Steven Hardy09ae1b02016-01-18 11:31:52 +000095 self.stack_identifier = self.stack_create(
96 template=test_template_one_resource)
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -050097 test_template_updated_resource = {
98 'heat_template_version': '2013-05-23',
99 'description': 'Test template to create one instance.',
100 'resources': {
101 'test1': {
102 'type': 'OS::Heat::TestResource',
103 'properties': {
104 'value': 'Test1 foo',
105 'fail': False,
106 'update_replace': False,
107 'wait_secs': 0
108 }
109 }
110 }
111 }
112
113 result = self.preview_update_stack(self.stack_identifier,
114 test_template_updated_resource)
115 changes = result['resource_changes']
116
117 updated = changes['updated'][0]['resource_name']
118 self.assertEqual('test1', updated)
119
Steven Hardye6de2d62015-12-07 15:59:09 +0000120 self.assert_empty_sections(
121 changes, ['added', 'unchanged', 'replaced', 'deleted'])
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -0500122
123 def test_replaced_resource(self):
Steven Hardy09ae1b02016-01-18 11:31:52 +0000124 self.stack_identifier = self.stack_create(
125 template=test_template_one_resource)
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -0500126 new_template = {
127 'heat_template_version': '2013-05-23',
128 'description': 'Test template to create one instance.',
129 'resources': {
130 'test1': {
131 'type': 'OS::Heat::TestResource',
132 'properties': {
133 'update_replace': True,
134 }
135 }
136 }
137 }
138
Steven Hardy09ae1b02016-01-18 11:31:52 +0000139 result = self.preview_update_stack(self.stack_identifier, new_template)
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -0500140 changes = result['resource_changes']
141
142 replaced = changes['replaced'][0]['resource_name']
143 self.assertEqual('test1', replaced)
144
Steven Hardye6de2d62015-12-07 15:59:09 +0000145 self.assert_empty_sections(
146 changes, ['added', 'unchanged', 'updated', 'deleted'])
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -0500147
148 def test_delete_resource(self):
Steven Hardy09ae1b02016-01-18 11:31:52 +0000149 self.stack_identifier = self.stack_create(
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -0500150 template=test_template_two_resource)
Steven Hardy09ae1b02016-01-18 11:31:52 +0000151 result = self.preview_update_stack(self.stack_identifier,
Jason Dunsmoreb5aa9022015-09-09 16:57:04 -0500152 test_template_one_resource)
153 changes = result['resource_changes']
154
155 unchanged = changes['unchanged'][0]['resource_name']
156 self.assertEqual('test1', unchanged)
157
158 deleted = changes['deleted'][0]['resource_name']
159 self.assertEqual('test2', deleted)
160
Steven Hardye6de2d62015-12-07 15:59:09 +0000161 self.assert_empty_sections(changes, ['updated', 'replaced', 'added'])
162
163
164class UpdatePreviewStackTestNested(UpdatePreviewBase):
165 template_nested_parent = '''
166heat_template_version: 2016-04-08
167resources:
168 nested1:
169 type: nested1.yaml
170'''
171
172 template_nested1 = '''
173heat_template_version: 2016-04-08
174resources:
175 nested2:
176 type: nested2.yaml
177'''
178
179 template_nested2 = '''
180heat_template_version: 2016-04-08
181resources:
182 random:
183 type: OS::Heat::RandomString
184'''
185
186 template_nested2_2 = '''
187heat_template_version: 2016-04-08
188resources:
189 random:
190 type: OS::Heat::RandomString
191 random2:
192 type: OS::Heat::RandomString
193'''
194
195 def _get_by_resource_name(self, changes, name, action):
196 filtered_l = [x for x in changes[action]
197 if x['resource_name'] == name]
198 self.assertEqual(1, len(filtered_l))
199 return filtered_l[0]
200
201 def test_nested_resources_nochange(self):
202 files = {'nested1.yaml': self.template_nested1,
203 'nested2.yaml': self.template_nested2}
204 self.stack_identifier = self.stack_create(
205 template=self.template_nested_parent, files=files)
206 result = self.preview_update_stack(
207 self.stack_identifier,
208 template=self.template_nested_parent,
209 files=files, show_nested=True)
210 changes = result['resource_changes']
211
212 # The nested random resource should be unchanged, but we always
213 # update nested stacks even when there are no changes
214 self.assertEqual(1, len(changes['unchanged']))
215 self.assertEqual('random', changes['unchanged'][0]['resource_name'])
216 self.assertEqual('nested2', changes['unchanged'][0]['parent_resource'])
217
218 self.assertEqual(2, len(changes['updated']))
219 u_nested1 = self._get_by_resource_name(changes, 'nested1', 'updated')
220 self.assertNotIn('parent_resource', u_nested1)
221 u_nested2 = self._get_by_resource_name(changes, 'nested2', 'updated')
222 self.assertEqual('nested1', u_nested2['parent_resource'])
223
224 self.assert_empty_sections(changes, ['replaced', 'deleted', 'added'])
225
226 def test_nested_resources_add(self):
227 files = {'nested1.yaml': self.template_nested1,
228 'nested2.yaml': self.template_nested2}
229 self.stack_identifier = self.stack_create(
230 template=self.template_nested_parent, files=files)
231 files['nested2.yaml'] = self.template_nested2_2
232 result = self.preview_update_stack(
233 self.stack_identifier,
234 template=self.template_nested_parent,
235 files=files, show_nested=True)
236 changes = result['resource_changes']
237
238 # The nested random resource should be unchanged, but we always
239 # update nested stacks even when there are no changes
240 self.assertEqual(1, len(changes['unchanged']))
241 self.assertEqual('random', changes['unchanged'][0]['resource_name'])
242 self.assertEqual('nested2', changes['unchanged'][0]['parent_resource'])
243
244 self.assertEqual(1, len(changes['added']))
245 self.assertEqual('random2', changes['added'][0]['resource_name'])
246 self.assertEqual('nested2', changes['added'][0]['parent_resource'])
247
248 self.assert_empty_sections(changes, ['replaced', 'deleted'])
249
250 def test_nested_resources_delete(self):
251 files = {'nested1.yaml': self.template_nested1,
252 'nested2.yaml': self.template_nested2_2}
253 self.stack_identifier = self.stack_create(
254 template=self.template_nested_parent, files=files)
255 files['nested2.yaml'] = self.template_nested2
256 result = self.preview_update_stack(
257 self.stack_identifier,
258 template=self.template_nested_parent,
259 files=files, show_nested=True)
260 changes = result['resource_changes']
261
262 # The nested random resource should be unchanged, but we always
263 # update nested stacks even when there are no changes
264 self.assertEqual(1, len(changes['unchanged']))
265 self.assertEqual('random', changes['unchanged'][0]['resource_name'])
266 self.assertEqual('nested2', changes['unchanged'][0]['parent_resource'])
267
268 self.assertEqual(1, len(changes['deleted']))
269 self.assertEqual('random2', changes['deleted'][0]['resource_name'])
270 self.assertEqual('nested2', changes['deleted'][0]['parent_resource'])
271
272 self.assert_empty_sections(changes, ['replaced', 'added'])
273
274 def test_nested_resources_replace(self):
275 files = {'nested1.yaml': self.template_nested1,
276 'nested2.yaml': self.template_nested2}
277 self.stack_identifier = self.stack_create(
278 template=self.template_nested_parent, files=files)
279 parent_none = self.template_nested_parent.replace(
280 'nested1.yaml', 'OS::Heat::None')
281 result = self.preview_update_stack(
282 self.stack_identifier,
283 template=parent_none,
284 show_nested=True)
285 changes = result['resource_changes']
286
287 # The nested random resource should be unchanged, but we always
288 # update nested stacks even when there are no changes
289 self.assertEqual(1, len(changes['replaced']))
290 self.assertEqual('nested1', changes['replaced'][0]['resource_name'])
291
292 self.assertEqual(2, len(changes['deleted']))
293 d_random = self._get_by_resource_name(changes, 'random', 'deleted')
294 self.assertEqual('nested2', d_random['parent_resource'])
295 d_nested2 = self._get_by_resource_name(changes, 'nested2', 'deleted')
296 self.assertEqual('nested1', d_nested2['parent_resource'])
297
298 self.assert_empty_sections(changes, ['updated', 'unchanged', 'added'])