blob: bafb0ef19b8036921986774390265f7f62c42e2c [file] [log] [blame]
Steven Hardy03da0742015-03-19 00:13:17 -04001# 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
Steven Hardy03da0742015-03-19 00:13:17 -040013import yaml
14
Rabi Mishra477efc92015-07-31 13:01:45 +053015from heat_integrationtests.functional import functional_base
Steven Hardy03da0742015-03-19 00:13:17 -040016
17
Rabi Mishra477efc92015-07-31 13:01:45 +053018class HooksTest(functional_base.FunctionalTestsBase):
Steven Hardy03da0742015-03-19 00:13:17 -040019
20 def setUp(self):
21 super(HooksTest, self).setUp()
Steven Hardy03da0742015-03-19 00:13:17 -040022 self.template = {'heat_template_version': '2014-10-16',
23 'resources': {
24 'foo_step1': {'type': 'OS::Heat::RandomString'},
25 'foo_step2': {'type': 'OS::Heat::RandomString',
26 'depends_on': 'foo_step1'},
27 'foo_step3': {'type': 'OS::Heat::RandomString',
28 'depends_on': 'foo_step2'}}}
29
30 def test_hook_pre_create(self):
31 env = {'resource_registry':
32 {'resources':
33 {'foo_step2':
34 {'hooks': 'pre-create'}}}}
35 # Note we don't wait for CREATE_COMPLETE, because we need to
36 # signal to clear the hook before create will complete
37 stack_identifier = self.stack_create(
38 template=self.template,
39 environment=env,
40 expected_status='CREATE_IN_PROGRESS')
41 self._wait_for_resource_status(
42 stack_identifier, 'foo_step1', 'CREATE_COMPLETE')
43 self._wait_for_resource_status(
44 stack_identifier, 'foo_step2', 'INIT_COMPLETE')
45 ev = self.wait_for_event_with_reason(
46 stack_identifier,
47 reason='CREATE paused until Hook pre-create is cleared',
48 rsrc_name='foo_step2')
49 self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
50 self.client.resources.signal(stack_identifier, 'foo_step2',
51 data={'unset_hook': 'pre-create'})
52 ev = self.wait_for_event_with_reason(
53 stack_identifier,
54 reason='Hook pre-create is cleared',
55 rsrc_name='foo_step2')
56 self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
57 self._wait_for_resource_status(
58 stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
59 self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
60
61 def test_hook_pre_update_nochange(self):
62 env = {'resource_registry':
63 {'resources':
64 {'foo_step2':
65 {'hooks': 'pre-update'}}}}
66 stack_identifier = self.stack_create(
67 template=self.template,
68 environment=env)
69 res_before = self.client.resources.get(stack_identifier, 'foo_step2')
70 # Note we don't wait for UPDATE_COMPLETE, because we need to
71 # signal to clear the hook before update will complete
72 self.update_stack(
73 stack_identifier,
74 template=self.template,
75 environment=env,
76 expected_status='UPDATE_IN_PROGRESS')
77
78 # Note when a hook is specified, the resource status doesn't change
79 # when we hit the hook, so we look for the event, then assert the
80 # state is unchanged.
81 self._wait_for_resource_status(
82 stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
83 ev = self.wait_for_event_with_reason(
84 stack_identifier,
85 reason='UPDATE paused until Hook pre-update is cleared',
86 rsrc_name='foo_step2')
87 self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
88 self.client.resources.signal(stack_identifier, 'foo_step2',
89 data={'unset_hook': 'pre-update'})
90 ev = self.wait_for_event_with_reason(
91 stack_identifier,
92 reason='Hook pre-update is cleared',
93 rsrc_name='foo_step2')
94 self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
95 self._wait_for_resource_status(
96 stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
97 self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
98 res_after = self.client.resources.get(stack_identifier, 'foo_step2')
99 self.assertEqual(res_before.physical_resource_id,
100 res_after.physical_resource_id)
101
102 def test_hook_pre_update_replace(self):
103 env = {'resource_registry':
104 {'resources':
105 {'foo_step2':
106 {'hooks': 'pre-update'}}}}
107 stack_identifier = self.stack_create(
108 template=self.template,
109 environment=env)
110 res_before = self.client.resources.get(stack_identifier, 'foo_step2')
111 # Note we don't wait for UPDATE_COMPLETE, because we need to
112 # signal to clear the hook before update will complete
113 self.template['resources']['foo_step2']['properties'] = {'length': 10}
114 self.update_stack(
115 stack_identifier,
116 template=self.template,
117 environment=env,
118 expected_status='UPDATE_IN_PROGRESS')
119
120 # Note when a hook is specified, the resource status doesn't change
121 # when we hit the hook, so we look for the event, then assert the
122 # state is unchanged.
123 self._wait_for_resource_status(
124 stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
125 ev = self.wait_for_event_with_reason(
126 stack_identifier,
127 reason='UPDATE paused until Hook pre-update is cleared',
128 rsrc_name='foo_step2')
129 self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
130 self.client.resources.signal(stack_identifier, 'foo_step2',
131 data={'unset_hook': 'pre-update'})
132 ev = self.wait_for_event_with_reason(
133 stack_identifier,
134 reason='Hook pre-update is cleared',
135 rsrc_name='foo_step2')
136 self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
137 self._wait_for_resource_status(
138 stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
139 self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
140 res_after = self.client.resources.get(stack_identifier, 'foo_step2')
141 self.assertNotEqual(res_before.physical_resource_id,
142 res_after.physical_resource_id)
143
144 def test_hook_pre_update_in_place(self):
145 env = {'resource_registry':
146 {'resources':
147 {'rg':
148 {'hooks': 'pre-update'}}}}
149 template = {'heat_template_version': '2014-10-16',
150 'resources': {
151 'rg': {
152 'type': 'OS::Heat::ResourceGroup',
153 'properties': {
154 'count': 1,
155 'resource_def': {
156 'type': 'OS::Heat::RandomString'}}}}}
157 # Note we don't wait for CREATE_COMPLETE, because we need to
158 # signal to clear the hook before create will complete
159 stack_identifier = self.stack_create(
160 template=template,
161 environment=env)
162 res_before = self.client.resources.get(stack_identifier, 'rg')
163 template['resources']['rg']['properties']['count'] = 2
164 self.update_stack(
165 stack_identifier,
166 template=template,
167 environment=env,
168 expected_status='UPDATE_IN_PROGRESS')
169
170 # Note when a hook is specified, the resource status doesn't change
171 # when we hit the hook, so we look for the event, then assert the
172 # state is unchanged.
173 self._wait_for_resource_status(
174 stack_identifier, 'rg', 'CREATE_COMPLETE')
175 ev = self.wait_for_event_with_reason(
176 stack_identifier,
177 reason='UPDATE paused until Hook pre-update is cleared',
178 rsrc_name='rg')
179 self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
180 self.client.resources.signal(stack_identifier, 'rg',
181 data={'unset_hook': 'pre-update'})
182
183 ev = self.wait_for_event_with_reason(
184 stack_identifier,
185 reason='Hook pre-update is cleared',
186 rsrc_name='rg')
187 self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
Steven Hardy03da0742015-03-19 00:13:17 -0400188 self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
189 res_after = self.client.resources.get(stack_identifier, 'rg')
190 self.assertEqual(res_before.physical_resource_id,
191 res_after.physical_resource_id)
192
193 def test_hook_pre_create_nested(self):
Rabi Mishraa90e2622016-02-19 14:32:47 +0530194 files = {'nested.yaml': yaml.safe_dump(self.template)}
Steven Hardy03da0742015-03-19 00:13:17 -0400195 env = {'resource_registry':
196 {'resources':
197 {'nested':
198 {'foo_step2':
199 {'hooks': 'pre-create'}}}}}
200 template = {'heat_template_version': '2014-10-16',
201 'resources': {
202 'nested': {'type': 'nested.yaml'}}}
203 # Note we don't wait for CREATE_COMPLETE, because we need to
204 # signal to clear the hook before create will complete
205 stack_identifier = self.stack_create(
206 template=template,
207 environment=env,
208 files=files,
209 expected_status='CREATE_IN_PROGRESS')
210 self._wait_for_resource_status(stack_identifier, 'nested',
211 'CREATE_IN_PROGRESS')
212 nested_identifier = self.assert_resource_is_a_stack(
213 stack_identifier, 'nested', wait=True)
214 self._wait_for_resource_status(
215 nested_identifier, 'foo_step1', 'CREATE_COMPLETE')
216 self._wait_for_resource_status(
217 nested_identifier, 'foo_step2', 'INIT_COMPLETE')
218 ev = self.wait_for_event_with_reason(
219 nested_identifier,
220 reason='CREATE paused until Hook pre-create is cleared',
221 rsrc_name='foo_step2')
222 self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
223 self.client.resources.signal(nested_identifier, 'foo_step2',
224 data={'unset_hook': 'pre-create'})
225 ev = self.wait_for_event_with_reason(
226 nested_identifier,
227 reason='Hook pre-create is cleared',
228 rsrc_name='foo_step2')
229 self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
230 self._wait_for_resource_status(
231 nested_identifier, 'foo_step2', 'CREATE_COMPLETE')
232 self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
233
234 def test_hook_pre_create_wildcard(self):
235 env = {'resource_registry':
236 {'resources':
237 {'foo_*':
238 {'hooks': 'pre-create'}}}}
239 # Note we don't wait for CREATE_COMPLETE, because we need to
240 # signal to clear the hook before create will complete
241 stack_identifier = self.stack_create(
242 template=self.template,
243 environment=env,
244 expected_status='CREATE_IN_PROGRESS')
245 self._wait_for_resource_status(
246 stack_identifier, 'foo_step1', 'INIT_COMPLETE')
247 self.wait_for_event_with_reason(
248 stack_identifier,
249 reason='CREATE paused until Hook pre-create is cleared',
250 rsrc_name='foo_step1')
251 self.client.resources.signal(stack_identifier, 'foo_step1',
252 data={'unset_hook': 'pre-create'})
253 self.wait_for_event_with_reason(
254 stack_identifier,
255 reason='Hook pre-create is cleared',
256 rsrc_name='foo_step1')
257 self._wait_for_resource_status(
258 stack_identifier, 'foo_step2', 'INIT_COMPLETE')
259 self.wait_for_event_with_reason(
260 stack_identifier,
261 reason='CREATE paused until Hook pre-create is cleared',
262 rsrc_name='foo_step2')
263 self.client.resources.signal(stack_identifier, 'foo_step2',
264 data={'unset_hook': 'pre-create'})
265 self.wait_for_event_with_reason(
266 stack_identifier,
267 reason='Hook pre-create is cleared',
268 rsrc_name='foo_step2')
269 self._wait_for_resource_status(
270 stack_identifier, 'foo_step3', 'INIT_COMPLETE')
271 self.wait_for_event_with_reason(
272 stack_identifier,
273 reason='CREATE paused until Hook pre-create is cleared',
274 rsrc_name='foo_step3')
275 self.client.resources.signal(stack_identifier, 'foo_step3',
276 data={'unset_hook': 'pre-create'})
277 self.wait_for_event_with_reason(
278 stack_identifier,
279 reason='Hook pre-create is cleared',
280 rsrc_name='foo_step3')
281 self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')