From e376c83cbd57c0720336848e4b82e3b7b804a347 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Wed, 6 Mar 2013 13:28:22 +1300 Subject: [PATCH] Test coverage for NestedStack, and fix FnGetRefId NestedStack now has 100% coverage. resource_id is now set during create instead of evaluated during FnGetRefId Fixes: Bug #1131534 Change-Id: I21966acc711a801d28a8a22c377758d2363dd096 --- heat/engine/resources/stack.py | 4 +- heat/engine/stack_resource.py | 2 +- heat/tests/test_nested_stack.py | 99 +++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 heat/tests/test_nested_stack.py diff --git a/heat/engine/resources/stack.py b/heat/engine/resources/stack.py index 589e1f0a..b196edb6 100644 --- a/heat/engine/resources/stack.py +++ b/heat/engine/resources/stack.py @@ -43,6 +43,7 @@ class NestedStack(stack_resource.StackResource): template = template_format.parse(template_data) self.create_with_template(template, self.properties[PROP_PARAMETERS]) + self.resource_id_set(self.nested().identifier().arn()) def handle_update(self, json_snippet): return self.UPDATE_REPLACE @@ -50,9 +51,6 @@ class NestedStack(stack_resource.StackResource): def handle_delete(self): self.delete_nested() - def FnGetRefId(self): - return self.nested().identifier().arn() - def FnGetAtt(self, key): if not key.startswith('Outputs.'): raise exception.InvalidTemplateAttribute( diff --git a/heat/engine/stack_resource.py b/heat/engine/stack_resource.py index bec2f721..9b8398be 100644 --- a/heat/engine/stack_resource.py +++ b/heat/engine/stack_resource.py @@ -87,7 +87,7 @@ class StackResource(resource.Resource): exception. ''' stack = self.nested() - if not stack: + if stack is None: return None if op not in stack.outputs: raise exception.InvalidTemplateAttribute( diff --git a/heat/tests/test_nested_stack.py b/heat/tests/test_nested_stack.py new file mode 100644 index 00000000..6568540b --- /dev/null +++ b/heat/tests/test_nested_stack.py @@ -0,0 +1,99 @@ +# 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 unittest +import mox + +from nose.plugins.attrib import attr + +from heat.common import context +from heat.common import exception +from heat.common import template_format +from heat.engine import parser +from heat.engine.resources import stack as nested_stack +from heat.common import urlfetch + + +@attr(tag=['unit', 'resource']) +@attr(speed='fast') +class NestedStackTest(unittest.TestCase): + test_template = ''' +HeatTemplateFormatVersion: '2012-12-12' +Resources: + the_nested: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: https://localhost/the.template + Parameters: + KeyName: foo +''' + + nested_template = ''' +HeatTemplateFormatVersion: '2012-12-12' +Outputs: + Foo: + Value: bar +''' + + def setUp(self): + self.m = mox.Mox() + self.m.StubOutWithMock(urlfetch, 'get') + + def tearDown(self): + self.m.UnsetStubs() + print "NestedStackTest teardown complete" + + def create_stack(self, template): + t = template_format.parse(template) + stack = self.parse_stack(t) + self.assertEqual(None, stack.create()) + return stack + + def parse_stack(self, t): + ctx = context.RequestContext.from_dict({ + 'tenant': 'test_tenant', + 'tenant_id': 'aaaa', + 'username': 'test_username', + 'password': 'password', + 'auth_url': 'http://localhost:5000/v2.0'}) + stack_name = 'test_stack' + tmpl = parser.Template(t) + params = parser.Parameters(stack_name, tmpl, {}) + stack = parser.Stack(ctx, stack_name, tmpl, params) + stack.store() + return stack + + def test_nested_stack(self): + urlfetch.get('https://localhost/the.template').AndReturn( + self.nested_template) + self.m.ReplayAll() + + stack = self.create_stack(self.test_template) + resource = stack['the_nested'] + self.assertTrue(resource.FnGetRefId().startswith( + 'arn:openstack:heat::aaaa:stacks/test_stack.the_nested/')) + + self.assertEqual(nested_stack.NestedStack.UPDATE_REPLACE, + resource.handle_update({})) + + self.assertEqual('bar', resource.FnGetAtt('Outputs.Foo')) + self.assertRaises( + exception.InvalidTemplateAttribute, resource.FnGetAtt, 'Foo') + + resource.delete() + self.assertTrue(resource.FnGetRefId().startswith( + 'arn:openstack:heat::aaaa:stacks/test_stack.the_nested/')) + + self.m.VerifyAll() -- 2.45.2