diff --git a/heat/engine/stack.py b/heat/engine/stack.py index 2d379b438c..f8574064c9 100644 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -1568,9 +1568,14 @@ class Stack(collections.Mapping): # and new stack resources, we should have user params of both. existing_params.load(newstack.t.env.user_env_as_dict()) self.t.env = existing_params + # Update the template version, in case new things were used + self.t.t[newstack.t.version[0]] = max( + newstack.t.version[1], self.t.version[1]) self.t.merge_snippets(newstack.t) self.t.store(self.context) backup_stack.t.env = existing_params + backup_stack.t.t[newstack.t.version[0]] = max( + newstack.t.version[1], self.t.version[1]) backup_stack.t.merge_snippets(newstack.t) backup_stack.t.store(self.context) self.store() diff --git a/heat_integrationtests/functional/test_create_update.py b/heat_integrationtests/functional/test_create_update.py index 771404ab5d..ae81463d30 100644 --- a/heat_integrationtests/functional/test_create_update.py +++ b/heat_integrationtests/functional/test_create_update.py @@ -625,3 +625,51 @@ resources: self.assertEqual({'test1': 'OS::Heat::TestResource', 'test2': 'My::TestResource'}, self.list_resources(stack_identifier)) + + def test_stack_update_with_new_version(self): + """Update handles new template version in failure. + + If a stack update fails while changing the template version, update is + able to handle the new version fine. + """ + stack_identifier = self.stack_create( + template=test_template_one_resource) + + # Update with a new function and make the update fails + template = _change_rsrc_properties(test_template_two_resource, + ['test1'], {'fail': True}) + + template['heat_template_version'] = '2015-10-15' + template['resources']['test2']['properties']['value'] = { + 'list_join': [',', ['a'], ['b']]} + self.update_stack(stack_identifier, + template=template, + expected_status='UPDATE_FAILED') + + template = _change_rsrc_properties(template, + ['test2'], {'value': 'Test2'}) + self.update_stack(stack_identifier, + template=template, + expected_status='UPDATE_FAILED') + self._stack_delete(stack_identifier) + + def test_stack_update_with_old_version(self): + """Update handles old template version in failure. + + If a stack update fails while changing the template version, update is + able to handle the old version fine. + """ + template = _change_rsrc_properties( + test_template_one_resource, + ['test1'], {'value': {'list_join': [',', ['a'], ['b']]}}) + template['heat_template_version'] = '2015-10-15' + stack_identifier = self.stack_create( + template=template) + + # Update with a new function and make the update fails + template = _change_rsrc_properties(test_template_one_resource, + ['test1'], {'fail': True}) + self.update_stack(stack_identifier, + template=template, + expected_status='UPDATE_FAILED') + self._stack_delete(stack_identifier)