summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-08-05 10:03:30 +0000
committerGerrit Code Review <review@openstack.org>2018-08-05 10:03:30 +0000
commit99cbff3803096741bae5b790744a2eb52057cc0c (patch)
treebb52096b0816691f99e893177408e26f59ebaf53
parent950795a65fa194163a0e34810fffc59096c0ac8d (diff)
parent07f1dd016c1f1b6ebf11778852263874af3a1bf0 (diff)
downloadheat-99cbff3803096741bae5b790744a2eb52057cc0c.tar.gz
Merge "Handle exceptions in initial convergence traversal setup"
-rw-r--r--heat/engine/check_resource.py22
-rw-r--r--heat/engine/stack.py38
-rw-r--r--heat/tests/engine/service/test_stack_create.py4
-rw-r--r--heat/tests/engine/test_check_resource.py54
-rw-r--r--heat/tests/test_convg_stack.py7
-rw-r--r--heat/tests/test_resource.py44
-rw-r--r--heat/tests/test_stack.py11
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):