From 84841e53fd2db6cc72dbeaec8d3bf1d4d8145552 Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Fri, 6 Jul 2012 17:03:17 +0200 Subject: [PATCH] Allow Status(Reason) access through Stack/Resource objects It would be better not to have to go looking in the database for this information, so cache it in the Stack/Resource objects themselves. Change-Id: Id96fbd229898fecc8917a61f19480f70fc2135d9 Signed-off-by: Zane Bitter --- heat/engine/parser.py | 26 ++++++++++++------ heat/engine/resources.py | 3 +++ heat/tests/test_parser.py | 23 ++++++++++++++++ heat/tests/test_resource.py | 54 +++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 heat/tests/test_resource.py diff --git a/heat/engine/parser.py b/heat/engine/parser.py index 555c8144..b0f8d5c6 100644 --- a/heat/engine/parser.py +++ b/heat/engine/parser.py @@ -235,7 +235,7 @@ class Stack(object): DELETE_COMPLETE = 'DELETE_COMPLETE' def __init__(self, context, stack_name, template, parameters=None, - stack_id=None): + stack_id=None, state=None, state_description=''): ''' Initialise from a context, name, Template object and (optionally) Parameters object. The database ID may also be initialised, if the @@ -245,6 +245,8 @@ class Stack(object): self.context = context self.t = template self.name = stack_name + self.state = state + self.state_description = state_description if parameters is None: parameters = Parameters(stack_name, template) @@ -274,7 +276,8 @@ class Stack(object): template = Template.load(context, s.raw_template_id) params = Parameters(s.name, template, s.parameters) - stack = cls(context, s.name, template, params, stack_id) + stack = cls(context, s.name, template, params, + stack_id, s.status, s.status_reason) return stack @@ -283,12 +286,16 @@ class Stack(object): if self.id is None: new_creds = db_api.user_creds_create(self.context.to_dict()) - s = {'name': self.name, - 'raw_template_id': self.t.store(), - 'parameters': self.parameters.user_parameters(), - 'owner_id': owner and owner.id, - 'user_creds_id': new_creds.id, - 'username': self.context.username} + s = { + 'name': self.name, + 'raw_template_id': self.t.store(), + 'parameters': self.parameters.user_parameters(), + 'owner_id': owner and owner.id, + 'user_creds_id': new_creds.id, + 'username': self.context.username, + 'status': self.state, + 'status_reason': self.state_description, + } new_s = db_api.stack_create(self.context, s) self.id = new_s.id @@ -368,6 +375,9 @@ class Stack(object): def state_set(self, new_status, reason): '''Update the stack state in the database''' + self.state = new_status + self.state_description = reason + if self.id is None: return diff --git a/heat/engine/resources.py b/heat/engine/resources.py index 381ac138..55a0d3ff 100644 --- a/heat/engine/resources.py +++ b/heat/engine/resources.py @@ -83,10 +83,12 @@ class Resource(object): if resource: self.instance_id = resource.nova_instance self.state = resource.state + self.state_description = resource.state_description self.id = resource.id else: self.instance_id = None self.state = None + self.state_description = '' self.id = None self._nova = {} self._keystone = None @@ -259,6 +261,7 @@ class Resource(object): def state_set(self, new_state, reason="state changed"): self.state, old_state = new_state, self.state + self.state_description = reason if self.id is not None: try: diff --git a/heat/tests/test_parser.py b/heat/tests/test_parser.py index 3a8511cb..7b809092 100644 --- a/heat/tests/test_parser.py +++ b/heat/tests/test_parser.py @@ -315,6 +315,29 @@ class ParametersTest(unittest.TestCase): self.assertEqual(params2['Defaulted'], 'foobar') +@attr(tag=['unit', 'parser', 'stack']) +@attr(speed='fast') +class StackTest(unittest.TestCase): + def test_state_defaults(self): + stack = parser.Stack(None, 'test_stack', parser.Template({})) + self.assertEqual(stack.state, None) + self.assertEqual(stack.state_description, '') + + def test_state(self): + stack = parser.Stack(None, 'test_stack', parser.Template({}), + state='foo') + self.assertEqual(stack.state, 'foo') + stack.state_set('bar', '') + self.assertEqual(stack.state, 'bar') + + def test_state_description(self): + stack = parser.Stack(None, 'test_stack', parser.Template({}), + state_description='quux') + self.assertEqual(stack.state_description, 'quux') + stack.state_set('blarg', 'wibble') + self.assertEqual(stack.state_description, 'wibble') + + # allows testing of the test directly, shown below if __name__ == '__main__': sys.argv.append(__file__) diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py new file mode 100644 index 00000000..cc3011d3 --- /dev/null +++ b/heat/tests/test_resource.py @@ -0,0 +1,54 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +import nose +import unittest +from nose.plugins.attrib import attr +import mox + +import json +from heat.engine import parser +from heat.engine import resources + + +@attr(tag=['unit', 'parser', 'stack']) +@attr(speed='fast') +class ResourceTest(unittest.TestCase): + def setUp(self): + self.stack = parser.Stack(None, 'test_stack', parser.Template({})) + + def test_state_defaults(self): + tmpl = {'Type': 'Foo'} + res = resources.GenericResource('test_resource', tmpl, self.stack) + self.assertEqual(res.state, None) + self.assertEqual(res.state_description, '') + + def test_state(self): + tmpl = {'Type': 'Foo'} + res = resources.GenericResource('test_resource', tmpl, self.stack) + res.state_set('bar') + self.assertEqual(res.state, 'bar') + + def test_state_description(self): + tmpl = {'Type': 'Foo'} + res = resources.GenericResource('test_resource', tmpl, self.stack) + res.state_set('blarg', 'wibble') + self.assertEqual(res.state_description, 'wibble') + + +# allows testing of the test directly, shown below +if __name__ == '__main__': + sys.argv.append(__file__) + nose.main() -- 2.45.2