Call _persist_state for UPDATE in 'state_set'

UPDATE flow doesn't call 'state_set', to set the state.
However, this is called in 'set_stack_and_resource_to_failed',
to set the stack status to FAILED. This includes reset during
stack UPDATE.

With https://review.openstack.org/#/c/245810/5, we removed UPDATE
from persisting the state as part of releasing the lock. This has
resulted in the state not being persisted for UPDATE when
'reset_stack_status' is called.

Change-Id: I8a80e329604fdec6498acca0a71723100d412384
Closes-Bug: #1523717
This commit is contained in:
Rabi Mishra 2015-12-08 14:02:39 +05:30
parent 2467d83377
commit e1d0b6c041
2 changed files with 66 additions and 34 deletions

View File

@ -779,10 +779,10 @@ class Stack(collections.Mapping):
return updated
# Persist state to db only if status == IN_PROGRESS
# or action == self.DELETE/self.ROLLBACK. Else, it would
# or action == UPDATE/DELETE/ROLLBACK. Else, it would
# be done before releasing the stack lock.
if status == self.IN_PROGRESS or action in (
self.DELETE, self.ROLLBACK):
self.UPDATE, self.DELETE, self.ROLLBACK):
self._persist_state()
def _persist_state(self):

View File

@ -176,19 +176,6 @@ class StackTest(common.HeatTestCase):
self.m.VerifyAll()
def test_state(self):
self.stack = stack.Stack(self.ctx, 'test_stack', self.tmpl,
action=stack.Stack.CREATE,
status=stack.Stack.IN_PROGRESS)
self.assertEqual((stack.Stack.CREATE, stack.Stack.IN_PROGRESS),
self.stack.state)
self.stack.state_set(stack.Stack.CREATE, stack.Stack.COMPLETE, 'test')
self.assertEqual((stack.Stack.CREATE, stack.Stack.COMPLETE),
self.stack.state)
self.stack.state_set(stack.Stack.DELETE, stack.Stack.COMPLETE, 'test')
self.assertEqual((stack.Stack.DELETE, stack.Stack.COMPLETE),
self.stack.state)
def test_state_deleted(self):
self.stack = stack.Stack(self.ctx, 'test_stack', self.tmpl,
action=stack.Stack.CREATE,
@ -200,25 +187,6 @@ class StackTest(common.HeatTestCase):
stack.Stack.COMPLETE,
'test'))
def test_state_bad(self):
self.stack = stack.Stack(self.ctx, 'test_stack', self.tmpl,
action=stack.Stack.CREATE,
status=stack.Stack.IN_PROGRESS)
self.assertEqual((stack.Stack.CREATE, stack.Stack.IN_PROGRESS),
self.stack.state)
self.assertRaises(ValueError, self.stack.state_set,
'baad', stack.Stack.COMPLETE, 'test')
self.assertRaises(ValueError, self.stack.state_set,
stack.Stack.CREATE, 'oops', 'test')
def test_status_reason(self):
self.stack = stack.Stack(self.ctx, 'test_stack', self.tmpl,
status_reason='quux')
self.assertEqual('quux', self.stack.status_reason)
self.stack.state_set(stack.Stack.CREATE, stack.Stack.IN_PROGRESS,
'wibble')
self.assertEqual('wibble', self.stack.status_reason)
def test_load_nonexistant_id(self):
self.assertRaises(exception.NotFound, stack.Stack.load,
None, -1)
@ -2591,3 +2559,67 @@ class ResetStateOnErrorTest(common.HeatTestCase):
exc = self.assertRaises(BaseException, dummy.raise_exit_exception)
self.assertIn('bye', str(exc))
self.assertTrue(dummy.state_set.called)
class StackStateSetTest(common.HeatTestCase):
scenarios = [
('in_progress', dict(action=stack.Stack.CREATE,
status=stack.Stack.IN_PROGRESS,
persist_count=1, error=False)),
('create_complete', dict(action=stack.Stack.CREATE,
status=stack.Stack.COMPLETE,
persist_count=0, error=False)),
('create_failed', dict(action=stack.Stack.CREATE,
status=stack.Stack.FAILED,
persist_count=0, error=False)),
('update_complete', dict(action=stack.Stack.UPDATE,
status=stack.Stack.COMPLETE,
persist_count=1, error=False)),
('update_failed', dict(action=stack.Stack.UPDATE,
status=stack.Stack.FAILED,
persist_count=1, error=False)),
('delete_complete', dict(action=stack.Stack.DELETE,
status=stack.Stack.COMPLETE,
persist_count=1, error=False)),
('delete_failed', dict(action=stack.Stack.DELETE,
status=stack.Stack.FAILED,
persist_count=1, error=False)),
('adopt_complete', dict(action=stack.Stack.ADOPT,
status=stack.Stack.COMPLETE,
persist_count=0, error=False)),
('adopt_failed', dict(action=stack.Stack.ADOPT,
status=stack.Stack.FAILED,
persist_count=0, error=False)),
('rollback_complete', dict(action=stack.Stack.ROLLBACK,
status=stack.Stack.COMPLETE,
persist_count=1, error=False)),
('rollback_failed', dict(action=stack.Stack.ROLLBACK,
status=stack.Stack.FAILED,
persist_count=1, error=False)),
('invalid_action', dict(action='action',
status=stack.Stack.FAILED,
persist_count=0, error=True)),
('invalid_status', dict(action=stack.Stack.CREATE,
status='status',
persist_count=0, error=True)),
]
def test_state(self):
self.tmpl = template.Template(copy.deepcopy(empty_template))
self.ctx = utils.dummy_context()
self.stack = stack.Stack(self.ctx, 'test_stack', self.tmpl,
action=stack.Stack.CREATE,
status=stack.Stack.IN_PROGRESS)
persist_state = self.patchobject(self.stack, '_persist_state')
self.assertEqual((stack.Stack.CREATE, stack.Stack.IN_PROGRESS),
self.stack.state)
if self.error:
self.assertRaises(ValueError, self.stack.state_set,
self.action, self.status, 'test')
else:
self.assertIsNone(self.stack.state_set(self.action,
self.status, 'test'))
self.assertEqual((self.action, self.status), self.stack.state)
self.assertEqual('test', self.stack.status_reason)
self.assertEqual(self.persist_count, persist_state.call_count)