def __str__(self):
return '%s "%s"' % (self.__class__.__name__, self.name)
- def _add_dependencies(self, deps, head, fragment):
+ 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':
- value, head = value
+ value, att = value
try:
target = self.stack.resources[value]
except KeyError:
raise exception.InvalidTemplateReference(
resource=value,
- key=head)
+ key=path)
if key == 'DependsOn' or target.strict_dependency:
deps += (self, target)
else:
- self._add_dependencies(deps, key, value)
+ self._add_dependencies(deps, '%s.%s' % (path, key), value)
elif isinstance(fragment, list):
- for item in fragment:
- self._add_dependencies(deps, head, item)
+ for index, item in enumerate(fragment):
+ self._add_dependencies(deps, '%s[%d]' % (path, index), item)
def add_dependencies(self, deps):
- self._add_dependencies(deps, None, self.t)
+ self._add_dependencies(deps, self.name, self.t)
deps += (self, None)
def required_by(self):
self.assertIn(res, graph)
self.assertIn(stack['foo'], graph[res])
+ def test_ref_fail(self):
+ tmpl = template.Template({
+ 'Resources': {
+ 'foo': {'Type': 'GenericResourceType'},
+ 'bar': {
+ 'Type': 'ResourceWithPropsType',
+ 'Properties': {
+ 'Foo': {'Ref': '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': {
self.assertIn(res, graph)
self.assertIn(stack['foo'], graph[res])
+ def test_getatt_fail(self):
+ tmpl = template.Template({
+ 'Resources': {
+ 'foo': {'Type': 'GenericResourceType'},
+ 'bar': {
+ 'Type': 'ResourceWithPropsType',
+ 'Properties': {
+ 'Foo': {'Fn::GetAtt': ['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': {
+ 'foo': {'Type': 'GenericResourceType'},
+ 'bar': {
+ 'Type': 'ResourceWithPropsType',
+ 'Properties': {
+ 'Foo': {'Fn::Join': [",", ["blarg",
+ {'Fn::GetAtt': ['foo',
+ 'bar']},
+ "wibble",
+ {'Fn::GetAtt': ['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': {
self.assertIn(res, graph)
self.assertIn(stack['foo'], graph[res])
+ def test_dependson_fail(self):
+ tmpl = template.Template({
+ 'Resources': {
+ 'foo': {
+ 'Type': 'GenericResourceType',
+ 'DependsOn': 'wibble',
+ }
+ }
+ })
+ ex = self.assertRaises(exception.InvalidTemplateReference,
+ parser.Stack,
+ None, 'test', tmpl)
+ self.assertIn('"wibble" (in foo)', str(ex))
+
class MetadataTest(HeatTestCase):
def setUp(self):