diff options
author | Zuul <zuul@review.openstack.org> | 2018-08-05 10:03:30 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2018-08-05 10:03:30 +0000 |
commit | 99cbff3803096741bae5b790744a2eb52057cc0c (patch) | |
tree | bb52096b0816691f99e893177408e26f59ebaf53 | |
parent | 950795a65fa194163a0e34810fffc59096c0ac8d (diff) | |
parent | 07f1dd016c1f1b6ebf11778852263874af3a1bf0 (diff) | |
download | heat-99cbff3803096741bae5b790744a2eb52057cc0c.tar.gz |
Merge "Handle exceptions in initial convergence traversal setup"
-rw-r--r-- | heat/engine/check_resource.py | 22 | ||||
-rw-r--r-- | heat/engine/stack.py | 38 | ||||
-rw-r--r-- | heat/tests/engine/service/test_stack_create.py | 4 | ||||
-rw-r--r-- | heat/tests/engine/test_check_resource.py | 54 | ||||
-rw-r--r-- | heat/tests/test_convg_stack.py | 7 | ||||
-rw-r--r-- | heat/tests/test_resource.py | 44 | ||||
-rw-r--r-- | heat/tests/test_stack.py | 11 |
7 files changed, 98 insertions, 82 deletions
diff --git a/heat/engine/check_resource.py b/heat/engine/check_resource.py index 48838f423..366567634 100644 --- a/heat/engine/check_resource.py +++ b/heat/engine/check_resource.py @@ -92,27 +92,9 @@ class CheckResource(object): LOG.debug('Resource id=%d modified by another traversal', rsrc.id) return False - def _trigger_rollback(self, stack): - LOG.info("Triggering rollback of %(stack_name)s %(action)s ", - {'action': stack.action, 'stack_name': stack.name}) - stack.rollback() - - def _handle_failure(self, cnxt, stack, failure_reason): - updated = stack.state_set(stack.action, stack.FAILED, failure_reason) - if not updated: - return False - - if (not stack.disable_rollback and - stack.action in (stack.CREATE, stack.ADOPT, stack.UPDATE, - stack.RESTORE)): - self._trigger_rollback(stack) - else: - stack.purge_db() - return True - def _handle_resource_failure(self, cnxt, is_update, rsrc_id, stack, failure_reason): - failure_handled = self._handle_failure(cnxt, stack, failure_reason) + failure_handled = stack.mark_failed(failure_reason) if not failure_handled: # Another concurrent update has taken over. But there is a # possibility for that update to be waiting for this rsrc to @@ -131,7 +113,7 @@ class CheckResource(object): def _handle_stack_timeout(self, cnxt, stack): failure_reason = u'Timed out' - self._handle_failure(cnxt, stack, failure_reason) + stack.mark_failed(failure_reason) def _handle_resource_replacement(self, cnxt, current_traversal, new_tmpl_id, requires, diff --git a/heat/engine/stack.py b/heat/engine/stack.py index 66eba3cbe..068f5d791 100644 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -90,10 +90,10 @@ def reset_state_on_error(func): LOG.info('Stopped due to %(msg)s in %(func)s', {'func': func.__name__, 'msg': errmsg}) finally: - if stack.status == stack.IN_PROGRESS: + if ((not stack.convergence or errmsg is not None) and + stack.status == stack.IN_PROGRESS): rtnmsg = _("Unexpected exit while IN_PROGRESS.") - stack.state_set(stack.action, stack.FAILED, - errmsg if errmsg is not None else rtnmsg) + stack.mark_failed(errmsg if errmsg is not None else rtnmsg) assert errmsg is not None, "Returned while IN_PROGRESS." return handle_exceptions @@ -1306,6 +1306,7 @@ class Stack(collections.Mapping): updater() @profiler.trace('Stack.converge_stack', hide_args=False) + @reset_state_on_error def converge_stack(self, template, action=UPDATE, new_stack=None, pre_converge=None): """Update the stack template and trigger convergence for resources.""" @@ -1364,6 +1365,7 @@ class Stack(collections.Mapping): self.thread_group_mgr.start(self.id, self._converge_create_or_update, pre_converge=pre_converge) + @reset_state_on_error def _converge_create_or_update(self, pre_converge=None): current_resources = self._update_or_store_resources() self._compute_convg_dependencies(self.ext_rsrcs_db, self.dependencies, @@ -2107,13 +2109,31 @@ class Stack(collections.Mapping): 'tags': self.tags, } - def mark_complete(self): - """Mark the update as complete. + def mark_failed(self, failure_reason): + """Mark the convergence update as failed.""" + updated = self.state_set(self.action, self.FAILED, failure_reason) + if not updated: + return False - This currently occurs when all resources have been updated; there may - still be resources being cleaned up, but the Stack should now be in - service. - """ + if not self.convergence: + # This function is not generally used in the legacy path, but to + # allow it to be used by any kind of stack in the + # reset_state_on_error decorator, bail out before the + # convergence-specific part in legacy stacks. + return + + if (not self.disable_rollback and + self.action in (self.CREATE, self.ADOPT, self.UPDATE, + self.RESTORE)): + LOG.info("Triggering rollback of %(stack_name)s %(action)s ", + {'action': self.action, 'stack_name': self.name}) + self.rollback() + else: + self.purge_db() + return True + + def mark_complete(self): + """Mark the convergence update as complete.""" LOG.info('[%(name)s(%(id)s)] update traversal %(tid)s complete', {'name': self.name, 'id': self.id, diff --git a/heat/tests/engine/service/test_stack_create.py b/heat/tests/engine/service/test_stack_create.py index 29b99355e..6975651d9 100644 --- a/heat/tests/engine/service/test_stack_create.py +++ b/heat/tests/engine/service/test_stack_create.py @@ -42,6 +42,7 @@ class StackCreateTest(common.HeatTestCase): self.ctx = utils.dummy_context() self.man = service.EngineService('a-host', 'a-topic') self.man.thread_group_mgr = service.ThreadGroupManager() + cfg.CONF.set_override('convergence_engine', False) @mock.patch.object(threadgroup, 'ThreadGroup') @mock.patch.object(stack.Stack, 'validate') @@ -53,7 +54,8 @@ class StackCreateTest(common.HeatTestCase): params = {'foo': 'bar'} template = '{ "Template": "data" }' - stk = tools.get_stack(stack_name, self.ctx) + stk = tools.get_stack(stack_name, self.ctx, + convergence=cfg.CONF.convergence_engine) files = None if files_container: diff --git a/heat/tests/engine/test_check_resource.py b/heat/tests/engine/test_check_resource.py index 8bf23a9e6..486c15ea7 100644 --- a/heat/tests/engine/test_check_resource.py +++ b/heat/tests/engine/test_check_resource.py @@ -205,7 +205,7 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): self.assertFalse(res) mock_ss.assert_not_called() - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') + @mock.patch.object(stack.Stack, 'rollback') def test_resource_update_failure_sets_stack_state_as_failed( self, mock_tr, mock_cru, mock_crc, mock_pcr, mock_csc): self.stack.state_set(self.stack.UPDATE, self.stack.IN_PROGRESS, '') @@ -224,7 +224,7 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): 'ResourceNotAvailable: resources.A: The Resource (A)' ' is not available.', s.status_reason) - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') + @mock.patch.object(stack.Stack, 'rollback') def test_resource_cleanup_failure_sets_stack_state_as_failed( self, mock_tr, mock_cru, mock_crc, mock_pcr, mock_csc): self.is_update = False # invokes check_resource_cleanup @@ -244,9 +244,9 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): 'ResourceNotAvailable: resources.A: The Resource (A)' ' is not available.', s.status_reason) - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') def test_resource_update_failure_triggers_rollback_if_enabled( - self, mock_tr, mock_cru, mock_crc, mock_pcr, mock_csc): + self, mock_cru, mock_crc, mock_pcr, mock_csc): + mock_tr = self.stack.rollback = mock.Mock(return_value=None) self.stack.disable_rollback = False self.stack.store() dummy_ex = exception.ResourceNotAvailable( @@ -257,14 +257,11 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): self.stack.current_traversal, {}, self.is_update, None) self.assertTrue(mock_tr.called) - # make sure the rollback is called on given stack - call_args, call_kwargs = mock_tr.call_args - called_stack = call_args[0] - self.assertEqual(self.stack.id, called_stack.id) + mock_tr.assert_called_once_with() - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') def test_resource_cleanup_failure_triggers_rollback_if_enabled( - self, mock_tr, mock_cru, mock_crc, mock_pcr, mock_csc): + self, mock_cru, mock_crc, mock_pcr, mock_csc): + mock_tr = self.stack.rollback = mock.Mock(return_value=None) self.is_update = False # invokes check_resource_cleanup self.stack.disable_rollback = False self.stack.store() @@ -275,13 +272,9 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): self.worker.check_resource(self.ctx, self.resource.id, self.stack.current_traversal, {}, self.is_update, None) - self.assertTrue(mock_tr.called) - # make sure the rollback is called on given stack - call_args, call_kwargs = mock_tr.call_args - called_stack = call_args[0] - self.assertEqual(self.stack.id, called_stack.id) + mock_tr.assert_called_once_with() - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') + @mock.patch.object(stack.Stack, 'rollback') def test_rollback_is_not_triggered_on_rollback_disabled_stack( self, mock_tr, mock_cru, mock_crc, mock_pcr, mock_csc): self.stack.disable_rollback = True @@ -295,7 +288,7 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): self.is_update, None) self.assertFalse(mock_tr.called) - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') + @mock.patch.object(stack.Stack, 'rollback') def test_rollback_not_re_triggered_for_a_rolling_back_stack( self, mock_tr, mock_cru, mock_crc, mock_pcr, mock_csc): self.stack.disable_rollback = False @@ -435,23 +428,23 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): @mock.patch.object(stack.Stack, 'purge_db') def test_handle_failure(self, mock_purgedb, mock_cru, mock_crc, mock_pcr, mock_csc): - self.cr._handle_failure(self.ctx, self.stack, 'dummy-reason') + self.stack.mark_failed('dummy-reason') mock_purgedb.assert_called_once_with() self.assertEqual('dummy-reason', self.stack.status_reason) - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') - def test_handle_failure_rollback(self, mock_tr, mock_cru, mock_crc, + def test_handle_failure_rollback(self, mock_cru, mock_crc, mock_pcr, mock_csc): + mock_tr = self.stack.rollback = mock.Mock(return_value=None) self.stack.disable_rollback = False self.stack.state_set(self.stack.UPDATE, self.stack.IN_PROGRESS, '') - self.cr._handle_failure(self.ctx, self.stack, 'dummy-reason') - mock_tr.assert_called_once_with(self.stack) + self.stack.mark_failed('dummy-reason') + mock_tr.assert_called_once_with() @mock.patch.object(stack.Stack, 'purge_db') @mock.patch.object(stack.Stack, 'state_set') @mock.patch.object(check_resource.CheckResource, 'retrigger_check_resource') - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') + @mock.patch.object(stack.Stack, 'rollback') def test_handle_rsrc_failure_when_update_fails( self, mock_tr, mock_rcr, mock_ss, mock_pdb, mock_cru, mock_crc, mock_pcr, mock_csc): @@ -469,7 +462,7 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): @mock.patch.object(stack.Stack, 'state_set') @mock.patch.object(check_resource.CheckResource, 'retrigger_check_resource') - @mock.patch.object(check_resource.CheckResource, '_trigger_rollback') + @mock.patch.object(stack.Stack, 'rollback') def test_handle_rsrc_failure_when_update_fails_different_traversal( self, mock_tr, mock_rcr, mock_ss, mock_pdb, mock_cru, mock_crc, mock_pcr, mock_csc): @@ -492,22 +485,21 @@ class CheckWorkflowUpdateTest(common.HeatTestCase): self.assertFalse(mock_pdb.called) self.assertFalse(mock_tr.called) - @mock.patch.object(check_resource.CheckResource, '_handle_failure') - def test_handle_stack_timeout(self, mock_hf, mock_cru, mock_crc, mock_pcr, + def test_handle_stack_timeout(self, mock_cru, mock_crc, mock_pcr, mock_csc): + mock_mf = self.stack.mark_failed = mock.Mock(return_value=True) self.cr._handle_stack_timeout(self.ctx, self.stack) - mock_hf.assert_called_once_with(self.ctx, self.stack, u'Timed out') + mock_mf.assert_called_once_with(u'Timed out') - @mock.patch.object(check_resource.CheckResource, - '_handle_failure') def test_do_check_resource_marks_stack_as_failed_if_stack_timesout( - self, mock_hf, mock_cru, mock_crc, mock_pcr, mock_csc): + self, mock_cru, mock_crc, mock_pcr, mock_csc): + mock_mf = self.stack.mark_failed = mock.Mock(return_value=True) mock_cru.side_effect = scheduler.Timeout(None, 60) self.is_update = True self.cr._do_check_resource(self.ctx, self.stack.current_traversal, self.stack.t, {}, self.is_update, self.resource, self.stack, {}) - mock_hf.assert_called_once_with(self.ctx, self.stack, u'Timed out') + mock_mf.assert_called_once_with(u'Timed out') @mock.patch.object(check_resource.CheckResource, '_handle_stack_timeout') diff --git a/heat/tests/test_convg_stack.py b/heat/tests/test_convg_stack.py index 8e6c5d87f..5aa681615 100644 --- a/heat/tests/test_convg_stack.py +++ b/heat/tests/test_convg_stack.py @@ -489,7 +489,8 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase): def test_sync_point_delete_stack_create(self, mock_syncpoint_del, mock_ccu, mock_cr): stack = parser.Stack(utils.dummy_context(), 'convg_updated_time_test', - templatem.Template.create_empty_template()) + templatem.Template.create_empty_template(), + convergence=True) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(template=stack.t, action=stack.CREATE) self.assertFalse(mock_syncpoint_del.called) @@ -503,7 +504,7 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase): tmpl = {'HeatTemplateFormatVersion': '2012-12-12', 'Resources': {'R1': {'Type': 'GenericResourceType'}}} stack = parser.Stack(utils.dummy_context(), 'updated_time_test', - templatem.Template(tmpl)) + templatem.Template(tmpl), convergence=True) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.current_traversal = 'prev_traversal' stack.converge_stack(template=stack.t, action=stack.UPDATE) @@ -514,7 +515,7 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase): tmpl = {'HeatTemplateFormatVersion': '2012-12-12', 'Resources': {'R1': {'Type': 'GenericResourceType'}}} stack = parser.Stack(utils.dummy_context(), 'updated_time_test', - templatem.Template(tmpl)) + templatem.Template(tmpl), convergence=True) stack.current_traversal = 'prev_traversal' stack.action, stack.status = stack.CREATE, stack.COMPLETE stack.store() diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index 9c3736a97..935f792dd 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -2043,6 +2043,7 @@ class ResourceTest(common.HeatTestCase): self.assertEqual(atomic_key, rs.atomic_key) def test_create_convergence(self): + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) res.action = res.CREATE @@ -2059,6 +2060,7 @@ class ResourceTest(common.HeatTestCase): self._assert_resource_lock(res.id, None, None) def test_create_convergence_throws_timeout(self): + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) res.action = res.CREATE @@ -2074,6 +2076,7 @@ class ResourceTest(common.HeatTestCase): Ensure that requires are computed correctly even if resource create fails. """ + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) res.store() @@ -2089,6 +2092,7 @@ class ResourceTest(common.HeatTestCase): @mock.patch.object(resource.Resource, 'adopt') def test_adopt_convergence_ok(self, mock_adopt): + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) res.action = res.ADOPT @@ -2106,6 +2110,7 @@ class ResourceTest(common.HeatTestCase): self._assert_resource_lock(res.id, None, None) def test_adopt_convergence_bad_data(self): + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) res.action = res.ADOPT @@ -2127,7 +2132,7 @@ class ResourceTest(common.HeatTestCase): 'test_res': {'Type': 'ResourceWithPropsType'} }}, env=self.env) stack = parser.Stack(utils.dummy_context(), 'test_stack', - tmpl) + tmpl, convergence=True) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(stack.t, action=stack.CREATE) res = stack.resources['test_res'] @@ -2144,8 +2149,8 @@ class ResourceTest(common.HeatTestCase): }}, env=self.env) new_temp.store(stack.context) new_stack = parser.Stack(utils.dummy_context(), 'test_stack', - new_temp, stack_id=self.stack.id) - res.stack.convergence = True + new_temp, stack_id=self.stack.id, + convergence=True) tr = scheduler.TaskRunner(res.update_convergence, new_temp.id, {4, 3}, 'engine-007', 120, new_stack) @@ -2163,7 +2168,7 @@ class ResourceTest(common.HeatTestCase): 'test_res': {'Type': 'ResourceWithPropsType'} }}, env=self.env) stack = parser.Stack(utils.dummy_context(), 'test_stack', - tmpl) + tmpl, convergence=True) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(stack.t, action=stack.CREATE) res = stack.resources['test_res'] @@ -2177,7 +2182,8 @@ class ResourceTest(common.HeatTestCase): }}, env=self.env) new_temp.store(stack.context) new_stack = parser.Stack(utils.dummy_context(), 'test_stack', - new_temp, stack_id=self.stack.id) + new_temp, stack_id=self.stack.id, + convergence=True) tr = scheduler.TaskRunner(res.update_convergence, new_temp.id, set(), 'engine-007', -1, new_stack, @@ -2185,6 +2191,7 @@ class ResourceTest(common.HeatTestCase): self.assertRaises(scheduler.Timeout, tr) def test_update_convergence_with_substitute_class(self): + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'GenericResourceType') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) @@ -2198,13 +2205,15 @@ class ResourceTest(common.HeatTestCase): }}, env=self.env) new_temp.store(self.stack.context) new_stack = parser.Stack(utils.dummy_context(), 'test_stack', - new_temp, stack_id=self.stack.id) + new_temp, stack_id=self.stack.id, + convergence=True) self.assertRaises(resource.UpdateReplace, res.update_convergence, new_temp.id, set(), 'engine-007', -1, new_stack) def test_update_convergence_checks_resource_class(self): + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'GenericResourceType') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) @@ -2219,7 +2228,8 @@ class ResourceTest(common.HeatTestCase): ctx = utils.dummy_context() new_temp.store(ctx) new_stack = parser.Stack(ctx, 'test_stack', - new_temp, stack_id=self.stack.id) + new_temp, stack_id=self.stack.id, + convergence=True) tr = scheduler.TaskRunner(res.update_convergence, new_temp.id, set(), 'engine-007', -1, new_stack, @@ -2245,7 +2255,8 @@ class ResourceTest(common.HeatTestCase): 'test_res': {'Type': 'ResourceWithPropsType'} }}, env=self.env) new_stack = parser.Stack(utils.dummy_context(), 'test_stack', - tmpl, stack_id=self.stack.id) + tmpl, stack_id=self.stack.id, + convergence=True) tr = scheduler.TaskRunner(res.update_convergence, 'template_key', {4, 3}, 'engine-007', self.dummy_timeout, new_stack) @@ -2268,7 +2279,7 @@ class ResourceTest(common.HeatTestCase): 'test_res': {'Type': 'ResourceWithPropsType'} }}, env=self.env) stack = parser.Stack(utils.dummy_context(), 'test_stack', - tmpl) + tmpl, convergence=True) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(stack.t, action=stack.CREATE) res = stack.resources['test_res'] @@ -2285,7 +2296,8 @@ class ResourceTest(common.HeatTestCase): new_temp.store(stack.context) new_stack = parser.Stack(utils.dummy_context(), 'test_stack', - new_temp, stack_id=self.stack.id) + new_temp, stack_id=self.stack.id, + convergence=True) res.stack.convergence = True res._calling_engine_id = 'engine-9' @@ -2309,7 +2321,7 @@ class ResourceTest(common.HeatTestCase): 'test_res': {'Type': 'ResourceWithPropsType'} }}, env=self.env) stack = parser.Stack(utils.dummy_context(), 'test_stack', - tmpl) + tmpl, convergence=True) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(stack.t, action=stack.CREATE) res = stack.resources['test_res'] @@ -2341,6 +2353,7 @@ class ResourceTest(common.HeatTestCase): self._assert_resource_lock(res.id, None, 2) def test_convergence_update_replace_rollback(self): + self.stack.convergence = True rsrc_def = rsrc_defn.ResourceDefinition('test_res', 'ResourceWithPropsType') res = generic_rsrc.ResourceWithProps('test_res', rsrc_def, self.stack) @@ -2354,7 +2367,8 @@ class ResourceTest(common.HeatTestCase): 'Properties': {'Foo': 'abc'}} }}, env=self.env) new_stack = parser.Stack(utils.dummy_context(), 'test_stack', - new_temp, stack_id=self.stack.id) + new_temp, stack_id=self.stack.id, + convergence=True) self.stack.state_set(self.stack.ROLLBACK, self.stack.IN_PROGRESS, 'Simulate rollback') res.restore_prev_rsrc = mock.Mock() @@ -2365,6 +2379,7 @@ class ResourceTest(common.HeatTestCase): self.assertTrue(res.restore_prev_rsrc.called) def test_convergence_update_replace_rollback_restore_prev_rsrc_error(self): + self.stack.convergence = True rsrc_def = rsrc_defn.ResourceDefinition('test_res', 'ResourceWithPropsType') res = generic_rsrc.ResourceWithProps('test_res', rsrc_def, self.stack) @@ -2378,7 +2393,8 @@ class ResourceTest(common.HeatTestCase): 'Properties': {'Foo': 'abc'}} }}, env=self.env) new_stack = parser.Stack(utils.dummy_context(), 'test_stack', - new_temp, stack_id=self.stack.id) + new_temp, stack_id=self.stack.id, + convergence=True) self.stack.state_set(self.stack.ROLLBACK, self.stack.IN_PROGRESS, 'Simulate rollback') res.restore_prev_rsrc = mock.Mock(side_effect=Exception) @@ -2390,6 +2406,7 @@ class ResourceTest(common.HeatTestCase): self.assertEqual((res.UPDATE, res.FAILED), res.state) def test_delete_convergence_ok(self): + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) res.current_template_id = 1 @@ -2409,6 +2426,7 @@ class ResourceTest(common.HeatTestCase): self._assert_resource_lock(res.id, None, None) def test_delete_convergence_does_not_delete_same_template_resource(self): + self.stack.convergence = True tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo') res = generic_rsrc.GenericResource('test_res', tmpl, self.stack) res.current_template_id = 'same-template' diff --git a/heat/tests/test_stack.py b/heat/tests/test_stack.py index c1d994725..2aec4ad91 100644 --- a/heat/tests/test_stack.py +++ b/heat/tests/test_stack.py @@ -2985,7 +2985,8 @@ class ResetStateOnErrorTest(common.HeatTestCase): status = COMPLETE def __init__(self): - self.state_set = mock.MagicMock() + self.mark_failed = mock.MagicMock() + self.convergence = False @stack.reset_state_on_error def raise_exception(self): @@ -3010,27 +3011,27 @@ class ResetStateOnErrorTest(common.HeatTestCase): dummy = self.DummyStack() self.assertEqual('Hello world', dummy.succeed()) - self.assertFalse(dummy.state_set.called) + self.assertFalse(dummy.mark_failed.called) def test_failure(self): dummy = self.DummyStack() self.assertEqual('Hello world', dummy.fail()) - self.assertFalse(dummy.state_set.called) + self.assertFalse(dummy.mark_failed.called) def test_reset_state_exception(self): dummy = self.DummyStack() exc = self.assertRaises(ValueError, dummy.raise_exception) self.assertIn('oops', str(exc)) - self.assertTrue(dummy.state_set.called) + self.assertTrue(dummy.mark_failed.called) def test_reset_state_exit_exception(self): dummy = self.DummyStack() exc = self.assertRaises(BaseException, dummy.raise_exit_exception) self.assertIn('bye', str(exc)) - self.assertTrue(dummy.state_set.called) + self.assertTrue(dummy.mark_failed.called) class StackStateSetTest(common.HeatTestCase): |