From: Randall Burt Date: Mon, 9 Sep 2013 21:16:17 +0000 (-0500) Subject: Add HOT functions to dependency checks X-Git-Tag: 2014.1~54 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=e88568dadabe53fda873d751f3cd7a802bef3265;p=openstack-build%2Fheat-build.git Add HOT functions to dependency checks Fixes bug 1223035 Change-Id: I7859a59490151885d4efe9bd36c612474d45b5f5 --- diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 87bcb9c7..60b44055 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -277,8 +277,9 @@ class Resource(object): def _add_dependencies(self, deps, path, fragment): if isinstance(fragment, dict): for key, value in fragment.items(): - if key in ('DependsOn', 'Ref', 'Fn::GetAtt'): - if key == 'Fn::GetAtt': + if key in ('DependsOn', 'Ref', 'Fn::GetAtt', 'get_attr', + 'get_resource'): + if key in ('Fn::GetAtt', 'get_attr'): value, att = value try: diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index 0394aa3e..89e810bb 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -614,6 +614,29 @@ class ResourceDependenciesTest(HeatTestCase): self.assertIn(res, graph) self.assertIn(stack['foo'], graph[res]) + def test_hot_ref(self): + '''Test that HOT get_resource creates dependencies.''' + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'properties': { + 'Foo': {'get_resource': 'foo'}, + } + } + } + }) + stack = parser.Stack(None, 'test', tmpl) + + res = stack['bar'] + res.add_dependencies(self.deps) + graph = self.deps.graph() + + self.assertIn(res, graph) + self.assertIn(stack['foo'], graph[res]) + def test_ref_nested_dict(self): tmpl = template.Template({ 'Resources': { @@ -635,6 +658,28 @@ class ResourceDependenciesTest(HeatTestCase): self.assertIn(res, graph) self.assertIn(stack['foo'], graph[res]) + def test_hot_ref_nested_dict(self): + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'properties': { + 'Foo': {'Fn::Base64': {'get_resource': 'foo'}}, + } + } + } + }) + stack = parser.Stack(None, 'test', tmpl) + + res = stack['bar'] + res.add_dependencies(self.deps) + graph = self.deps.graph() + + self.assertIn(res, graph) + self.assertIn(stack['foo'], graph[res]) + def test_ref_nested_deep(self): tmpl = template.Template({ 'Resources': { @@ -658,6 +703,30 @@ class ResourceDependenciesTest(HeatTestCase): self.assertIn(res, graph) self.assertIn(stack['foo'], graph[res]) + def test_hot_ref_nested_deep(self): + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'properties': { + 'foo': {'Fn::Join': [",", ["blarg", + {'get_resource': 'foo'}, + "wibble"]]}, + } + } + } + }) + stack = parser.Stack(None, 'test', tmpl) + + res = stack['bar'] + res.add_dependencies(self.deps) + graph = self.deps.graph() + + self.assertIn(res, graph) + self.assertIn(stack['foo'], graph[res]) + def test_ref_fail(self): tmpl = template.Template({ 'Resources': { @@ -675,6 +744,24 @@ class ResourceDependenciesTest(HeatTestCase): None, 'test', tmpl) self.assertIn('"baz" (in bar.Properties.Foo)', str(ex)) + def test_hot_ref_fail(self): + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'properties': { + 'Foo': {'get_resource': 'baz'}, + } + } + } + }) + ex = self.assertRaises(exception.InvalidTemplateReference, + parser.Stack, + None, 'test', tmpl) + self.assertIn('"baz" (in bar.Properties.Foo)', str(ex)) + def test_getatt(self): tmpl = template.Template({ 'Resources': { @@ -696,6 +783,28 @@ class ResourceDependenciesTest(HeatTestCase): self.assertIn(res, graph) self.assertIn(stack['foo'], graph[res]) + def test_hot_getatt(self): + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'Properties': { + 'Foo': {'get_attr': ['foo', 'bar']}, + } + } + } + }) + stack = parser.Stack(None, 'test', tmpl) + + res = stack['bar'] + res.add_dependencies(self.deps) + graph = self.deps.graph() + + self.assertIn(res, graph) + self.assertIn(stack['foo'], graph[res]) + def test_getatt_nested_dict(self): tmpl = template.Template({ 'Resources': { @@ -717,6 +826,28 @@ class ResourceDependenciesTest(HeatTestCase): self.assertIn(res, graph) self.assertIn(stack['foo'], graph[res]) + def test_hot_getatt_nested_dict(self): + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'properties': { + 'Foo': {'Fn::Base64': {'get_attr': ['foo', 'bar']}}, + } + } + } + }) + stack = parser.Stack(None, 'test', tmpl) + + res = stack['bar'] + res.add_dependencies(self.deps) + graph = self.deps.graph() + + self.assertIn(res, graph) + self.assertIn(stack['foo'], graph[res]) + def test_getatt_nested_deep(self): tmpl = template.Template({ 'Resources': { @@ -741,6 +872,31 @@ class ResourceDependenciesTest(HeatTestCase): self.assertIn(res, graph) self.assertIn(stack['foo'], graph[res]) + def test_hot_getatt_nested_deep(self): + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'properties': { + 'Foo': {'Fn::Join': [",", ["blarg", + {'get_attr': ['foo', + 'bar']}, + "wibble"]]}, + } + } + } + }) + stack = parser.Stack(None, 'test', tmpl) + + res = stack['bar'] + res.add_dependencies(self.deps) + graph = self.deps.graph() + + self.assertIn(res, graph) + self.assertIn(stack['foo'], graph[res]) + def test_getatt_fail(self): tmpl = template.Template({ 'Resources': { @@ -758,6 +914,24 @@ class ResourceDependenciesTest(HeatTestCase): None, 'test', tmpl) self.assertIn('"baz" (in bar.Properties.Foo)', str(ex)) + def test_hot_getatt_fail(self): + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'properties': { + 'Foo': {'get_attr': ['baz', 'bar']}, + } + } + } + }) + ex = self.assertRaises(exception.InvalidTemplateReference, + parser.Stack, + None, 'test', tmpl) + self.assertIn('"baz" (in bar.Properties.Foo)', str(ex)) + def test_getatt_fail_nested_deep(self): tmpl = template.Template({ 'Resources': { @@ -780,6 +954,29 @@ class ResourceDependenciesTest(HeatTestCase): None, 'test', tmpl) self.assertIn('"baz" (in bar.Properties.Foo.Fn::Join[1][3])', str(ex)) + def test_hot_getatt_fail_nested_deep(self): + tmpl = template.Template({ + 'heat_template_version': '2013-05-23', + 'resources': { + 'foo': {'type': 'GenericResourceType'}, + 'bar': { + 'type': 'ResourceWithPropsType', + 'properties': { + 'Foo': {'Fn::Join': [",", ["blarg", + {'get_attr': ['foo', + 'bar']}, + "wibble", + {'get_attr': ['baz', + 'bar']}]]}, + } + } + } + }) + ex = self.assertRaises(exception.InvalidTemplateReference, + parser.Stack, + None, 'test', tmpl) + self.assertIn('"baz" (in bar.Properties.Foo.Fn::Join[1][3])', str(ex)) + def test_dependson(self): tmpl = template.Template({ 'Resources': {