diff options
author | ricolin <rico.l@inwinstack.com> | 2015-08-01 00:52:57 +0800 |
---|---|---|
committer | ricolin <rico.l@inwinstack.com> | 2015-08-20 01:13:16 +0800 |
commit | b76f6ec0e97a9c3aaf5b5140e7a449c9636b8f95 (patch) | |
tree | 92eb9fbd52e792d445e315901d31607acca62eda /heat/tests/test_stack_update.py | |
parent | 044b6cba316e3f24b43de56c93f32e7b8c591c58 (diff) | |
download | heat-b76f6ec0e97a9c3aaf5b5140e7a449c9636b8f95.tar.gz |
resource failure causes nested stacks to be rolled back
an update_cancel RPC call for a nested stacks whenever an update
operation was cancelled in the parent stack.Unfortunately this always
triggers a rollback.
In this change, resource failure with nested stacks will cancel any
in-progress update but not roll back by default (roll back only when
rollblack cancel exception raised).
The Operator can retry in this way without waiting for timeout
or overall roll back occurred.
Change-Id: I94d75a21367f39c17a9b40b5d23405a28873cd1a
Closes-Bug: #1475057
Diffstat (limited to 'heat/tests/test_stack_update.py')
-rw-r--r-- | heat/tests/test_stack_update.py | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/heat/tests/test_stack_update.py b/heat/tests/test_stack_update.py index 4845545f0..daff80e18 100644 --- a/heat/tests/test_stack_update.py +++ b/heat/tests/test_stack_update.py @@ -21,6 +21,7 @@ from heat.engine import resource from heat.engine import scheduler from heat.engine import stack from heat.engine import template +from heat.rpc import api as rpc_api from heat.tests import common from heat.tests import generic_resource as generic_rsrc from heat.tests import utils @@ -671,6 +672,54 @@ class StackUpdateTest(common.HeatTestCase): [mock.call(None), mock.call('c_res'), mock.call('b_res'), mock.call('a_res')]) + def _update_force_cancel(self, state, disable_rollback=False, + cancel_message=rpc_api.THREAD_CANCEL): + tmpl = {'HeatTemplateFormatVersion': '2012-12-12', + 'Resources': {'AResource': {'Type': 'GenericResourceType'}}} + + self.stack = stack.Stack(self.ctx, 'update_test_stack', + template.Template(tmpl)) + self.stack.store() + self.stack.create() + self.assertEqual((stack.Stack.CREATE, stack.Stack.COMPLETE), + self.stack.state) + + tmpl2 = {'HeatTemplateFormatVersion': '2012-12-12', + 'Resources': { + 'AResource': {'Type': 'GenericResourceType'}, + 'BResource': {'Type': 'GenericResourceType'}}} + updated_stack = stack.Stack(self.ctx, 'updated_stack', + template.Template(tmpl2), + disable_rollback=disable_rollback) + + evt_mock = mock.MagicMock() + evt_mock.ready.return_value = True + evt_mock.wait.return_value = cancel_message + + self.stack.update(updated_stack, event=evt_mock) + + self.assertEqual(state, self.stack.state) + evt_mock.ready.assert_called_once_with() + evt_mock.wait.assert_called_once_with() + + def test_update_force_cancel_no_rollback(self): + self._update_force_cancel( + state=(stack.Stack.UPDATE, stack.Stack.FAILED), + disable_rollback=True, + cancel_message=rpc_api.THREAD_CANCEL) + + def test_update_force_cancel_rollback(self): + self._update_force_cancel( + state=(stack.Stack.ROLLBACK, stack.Stack.COMPLETE), + disable_rollback=False, + cancel_message=rpc_api.THREAD_CANCEL) + + def test_update_force_cancel_force_rollback(self): + self._update_force_cancel( + state=(stack.Stack.ROLLBACK, stack.Stack.COMPLETE), + disable_rollback=False, + cancel_message=rpc_api.THREAD_CANCEL_WITH_ROLLBACK) + def test_update_add_signal(self): tmpl = {'HeatTemplateFormatVersion': '2012-12-12', 'Resources': {'AResource': {'Type': 'GenericResourceType'}}} |