From 95ab69241ff786a80a3885fc64c0dec18216e761 Mon Sep 17 00:00:00 2001 From: Rakesh H S Date: Wed, 10 Jun 2015 01:10:48 +0530 Subject: [PATCH] Convergence soft delete stack after delete action is completed In an convergence enabled environment, when an stack-delete action is completed, the stack was not soft deleted from DB. This patch soft deletes the stack after all the required stack-delete operations are completed. Change-Id: I36d2b76223d3fc5f313b953b3976282d0923e92e --- heat/engine/stack.py | 7 +++++- heat/tests/test_stack.py | 52 +++++++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/heat/engine/stack.py b/heat/engine/stack.py index 8624b9facc..7652e7314c 100755 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -1615,7 +1615,7 @@ class Stack(collections.Mapping): self.name, self.id, traversal_id) prev_prev_id = self.prev_raw_template_id - self.prev_raw_template_id = self.t.id + self.prev_raw_template_id = None self.store() if (prev_prev_id is not None and @@ -1625,3 +1625,8 @@ class Stack(collections.Mapping): reason = 'Stack %s completed successfully' % self.action self.state_set(self.action, self.COMPLETE, reason) + if self.action == self.DELETE: + try: + stack_object.Stack.delete(self.context, self.id) + except exception.NotFound: + pass diff --git a/heat/tests/test_stack.py b/heat/tests/test_stack.py index 2e631681ce..f19430607d 100644 --- a/heat/tests/test_stack.py +++ b/heat/tests/test_stack.py @@ -2037,8 +2037,9 @@ class StackTest(common.HeatTestCase): self.assertEqual('foo', params.get('param1')) self.assertEqual('bar', params.get('param2')) + @mock.patch.object(stack_object.Stack, 'delete') @mock.patch.object(raw_template_object.RawTemplate, 'delete') - def test_mark_complete_create(self, mock_delete): + def test_mark_complete_create(self, mock_tmpl_delete, mock_stack_delete): tmpl = template.Template({ 'HeatTemplateFormatVersion': '2012-12-12', 'Resources': { @@ -2048,16 +2049,21 @@ class StackTest(common.HeatTestCase): tmpl_stack = stack.Stack(self.ctx, 'test', tmpl) tmpl_stack.store() + tmpl_stack.action = tmpl_stack.CREATE + tmpl_stack.status = tmpl_stack.IN_PROGRESS tmpl_stack.current_traversal = 'some-traversal' tmpl_stack.mark_complete('some-traversal') self.assertEqual(tmpl_stack.prev_raw_template_id, - tmpl_stack.t.id) - self.assertFalse(mock_delete.called) + None) + self.assertFalse(mock_tmpl_delete.called) + self.assertFalse(mock_stack_delete.called) self.assertEqual(tmpl_stack.status, tmpl_stack.COMPLETE) + @mock.patch.object(stack_object.Stack, 'delete') @mock.patch.object(raw_template_object.RawTemplate, 'delete') @mock.patch.object(stack.Stack, 'store') - def test_mark_complete_update(self, mock_store, mock_delete): + def test_mark_complete_update(self, mock_store, mock_tmpl_delete, + mock_stack_delete): tmpl = template.Template({ 'HeatTemplateFormatVersion': '2012-12-12', 'Resources': { @@ -2069,16 +2075,45 @@ class StackTest(common.HeatTestCase): tmpl_stack.id = 2 tmpl_stack.t.id = 2 tmpl_stack.prev_raw_template_id = 1 + tmpl_stack.action = tmpl_stack.UPDATE + tmpl_stack.status = tmpl_stack.IN_PROGRESS tmpl_stack.current_traversal = 'some-traversal' tmpl_stack.mark_complete('some-traversal') self.assertEqual(tmpl_stack.prev_raw_template_id, - tmpl_stack.t.id) - mock_delete.assert_called_once_with(self.ctx, 1) + None) + self.assertFalse(mock_stack_delete.called) + mock_tmpl_delete.assert_called_once_with(self.ctx, 1) self.assertEqual(tmpl_stack.status, tmpl_stack.COMPLETE) + @mock.patch.object(stack_object.Stack, 'delete') @mock.patch.object(raw_template_object.RawTemplate, 'delete') @mock.patch.object(stack.Stack, 'store') - def test_mark_complete_stale_traversal(self, mock_store, mock_delete): + def test_mark_complete_update_delete(self, mock_store, mock_tmpl_delete, + mock_stack_delete): + tmpl = template.Template({ + 'HeatTemplateFormatVersion': '2012-12-12', + 'Description': 'Empty Template' + }) + + tmpl_stack = stack.Stack(self.ctx, 'test', tmpl) + tmpl_stack.id = 2 + tmpl_stack.t.id = 2 + tmpl_stack.prev_raw_template_id = 1 + tmpl_stack.action = tmpl_stack.DELETE + tmpl_stack.status = tmpl_stack.IN_PROGRESS + tmpl_stack.current_traversal = 'some-traversal' + tmpl_stack.mark_complete('some-traversal') + self.assertEqual(tmpl_stack.prev_raw_template_id, + None) + mock_tmpl_delete.assert_called_once_with(self.ctx, 1) + mock_stack_delete.assert_called_once_with(self.ctx, 2) + self.assertEqual(tmpl_stack.status, tmpl_stack.COMPLETE) + + @mock.patch.object(stack_object.Stack, 'delete') + @mock.patch.object(raw_template_object.RawTemplate, 'delete') + @mock.patch.object(stack.Stack, 'store') + def test_mark_complete_stale_traversal(self, mock_store, mock_tmpl_delete, + mock_stack_delete): tmpl = template.Template({ 'HeatTemplateFormatVersion': '2012-12-12', 'Resources': { @@ -2089,7 +2124,8 @@ class StackTest(common.HeatTestCase): tmpl_stack = stack.Stack(self.ctx, 'test', tmpl) tmpl_stack.current_traversal = 'new-traversal' tmpl_stack.mark_complete('old-traversal') - self.assertFalse(mock_delete.called) + self.assertFalse(mock_tmpl_delete.called) + self.assertFalse(mock_stack_delete.called) self.assertIsNone(tmpl_stack.prev_raw_template_id) self.assertFalse(mock_store.called)