heat/heat_integrationtests/functional/test_hooks.py
Steve Baker 5af6e34d4b test_hooks remove race-prone status wait
This resource status wait isn't needed since it is
followed by a stack status wait.

In change I1cff016805e4b8e7c2da887856d06f776425e6b0 this wait stalls
because rg is in UPDATE_COMPLETE. I don't know yet why changing the
scheduler timings makes rg be in UPDATE rather than CREATE.

Change-Id: If5a97ff4d9bcb948bdec988c749fdc78329751a3
2015-03-26 11:38:21 +13:00

288 lines
13 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
import yaml
from heat_integrationtests.common import test
LOG = logging.getLogger(__name__)
class HooksTest(test.HeatIntegrationTest):
def setUp(self):
super(HooksTest, self).setUp()
self.client = self.orchestration_client
self.template = {'heat_template_version': '2014-10-16',
'resources': {
'foo_step1': {'type': 'OS::Heat::RandomString'},
'foo_step2': {'type': 'OS::Heat::RandomString',
'depends_on': 'foo_step1'},
'foo_step3': {'type': 'OS::Heat::RandomString',
'depends_on': 'foo_step2'}}}
def test_hook_pre_create(self):
env = {'resource_registry':
{'resources':
{'foo_step2':
{'hooks': 'pre-create'}}}}
# Note we don't wait for CREATE_COMPLETE, because we need to
# signal to clear the hook before create will complete
stack_identifier = self.stack_create(
template=self.template,
environment=env,
expected_status='CREATE_IN_PROGRESS')
self._wait_for_resource_status(
stack_identifier, 'foo_step1', 'CREATE_COMPLETE')
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'INIT_COMPLETE')
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step2')
self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
self.client.resources.signal(stack_identifier, 'foo_step2',
data={'unset_hook': 'pre-create'})
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step2')
self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
def test_hook_pre_update_nochange(self):
env = {'resource_registry':
{'resources':
{'foo_step2':
{'hooks': 'pre-update'}}}}
stack_identifier = self.stack_create(
template=self.template,
environment=env)
res_before = self.client.resources.get(stack_identifier, 'foo_step2')
# Note we don't wait for UPDATE_COMPLETE, because we need to
# signal to clear the hook before update will complete
self.update_stack(
stack_identifier,
template=self.template,
environment=env,
expected_status='UPDATE_IN_PROGRESS')
# Note when a hook is specified, the resource status doesn't change
# when we hit the hook, so we look for the event, then assert the
# state is unchanged.
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='UPDATE paused until Hook pre-update is cleared',
rsrc_name='foo_step2')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self.client.resources.signal(stack_identifier, 'foo_step2',
data={'unset_hook': 'pre-update'})
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-update is cleared',
rsrc_name='foo_step2')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
res_after = self.client.resources.get(stack_identifier, 'foo_step2')
self.assertEqual(res_before.physical_resource_id,
res_after.physical_resource_id)
def test_hook_pre_update_replace(self):
env = {'resource_registry':
{'resources':
{'foo_step2':
{'hooks': 'pre-update'}}}}
stack_identifier = self.stack_create(
template=self.template,
environment=env)
res_before = self.client.resources.get(stack_identifier, 'foo_step2')
# Note we don't wait for UPDATE_COMPLETE, because we need to
# signal to clear the hook before update will complete
self.template['resources']['foo_step2']['properties'] = {'length': 10}
self.update_stack(
stack_identifier,
template=self.template,
environment=env,
expected_status='UPDATE_IN_PROGRESS')
# Note when a hook is specified, the resource status doesn't change
# when we hit the hook, so we look for the event, then assert the
# state is unchanged.
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='UPDATE paused until Hook pre-update is cleared',
rsrc_name='foo_step2')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self.client.resources.signal(stack_identifier, 'foo_step2',
data={'unset_hook': 'pre-update'})
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-update is cleared',
rsrc_name='foo_step2')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
res_after = self.client.resources.get(stack_identifier, 'foo_step2')
self.assertNotEqual(res_before.physical_resource_id,
res_after.physical_resource_id)
def test_hook_pre_update_in_place(self):
env = {'resource_registry':
{'resources':
{'rg':
{'hooks': 'pre-update'}}}}
template = {'heat_template_version': '2014-10-16',
'resources': {
'rg': {
'type': 'OS::Heat::ResourceGroup',
'properties': {
'count': 1,
'resource_def': {
'type': 'OS::Heat::RandomString'}}}}}
# Note we don't wait for CREATE_COMPLETE, because we need to
# signal to clear the hook before create will complete
stack_identifier = self.stack_create(
template=template,
environment=env)
res_before = self.client.resources.get(stack_identifier, 'rg')
template['resources']['rg']['properties']['count'] = 2
self.update_stack(
stack_identifier,
template=template,
environment=env,
expected_status='UPDATE_IN_PROGRESS')
# Note when a hook is specified, the resource status doesn't change
# when we hit the hook, so we look for the event, then assert the
# state is unchanged.
self._wait_for_resource_status(
stack_identifier, 'rg', 'CREATE_COMPLETE')
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='UPDATE paused until Hook pre-update is cleared',
rsrc_name='rg')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self.client.resources.signal(stack_identifier, 'rg',
data={'unset_hook': 'pre-update'})
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-update is cleared',
rsrc_name='rg')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
res_after = self.client.resources.get(stack_identifier, 'rg')
self.assertEqual(res_before.physical_resource_id,
res_after.physical_resource_id)
def test_hook_pre_create_nested(self):
files = {'nested.yaml': yaml.dump(self.template)}
env = {'resource_registry':
{'resources':
{'nested':
{'foo_step2':
{'hooks': 'pre-create'}}}}}
template = {'heat_template_version': '2014-10-16',
'resources': {
'nested': {'type': 'nested.yaml'}}}
# Note we don't wait for CREATE_COMPLETE, because we need to
# signal to clear the hook before create will complete
stack_identifier = self.stack_create(
template=template,
environment=env,
files=files,
expected_status='CREATE_IN_PROGRESS')
self._wait_for_resource_status(stack_identifier, 'nested',
'CREATE_IN_PROGRESS')
nested_identifier = self.assert_resource_is_a_stack(
stack_identifier, 'nested', wait=True)
self._wait_for_resource_status(
nested_identifier, 'foo_step1', 'CREATE_COMPLETE')
self._wait_for_resource_status(
nested_identifier, 'foo_step2', 'INIT_COMPLETE')
ev = self.wait_for_event_with_reason(
nested_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step2')
self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
self.client.resources.signal(nested_identifier, 'foo_step2',
data={'unset_hook': 'pre-create'})
ev = self.wait_for_event_with_reason(
nested_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step2')
self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
self._wait_for_resource_status(
nested_identifier, 'foo_step2', 'CREATE_COMPLETE')
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
def test_hook_pre_create_wildcard(self):
env = {'resource_registry':
{'resources':
{'foo_*':
{'hooks': 'pre-create'}}}}
# Note we don't wait for CREATE_COMPLETE, because we need to
# signal to clear the hook before create will complete
stack_identifier = self.stack_create(
template=self.template,
environment=env,
expected_status='CREATE_IN_PROGRESS')
self._wait_for_resource_status(
stack_identifier, 'foo_step1', 'INIT_COMPLETE')
self.wait_for_event_with_reason(
stack_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step1')
self.client.resources.signal(stack_identifier, 'foo_step1',
data={'unset_hook': 'pre-create'})
self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step1')
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'INIT_COMPLETE')
self.wait_for_event_with_reason(
stack_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step2')
self.client.resources.signal(stack_identifier, 'foo_step2',
data={'unset_hook': 'pre-create'})
self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step2')
self._wait_for_resource_status(
stack_identifier, 'foo_step3', 'INIT_COMPLETE')
self.wait_for_event_with_reason(
stack_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step3')
self.client.resources.signal(stack_identifier, 'foo_step3',
data={'unset_hook': 'pre-create'})
self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step3')
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')