]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Only call FnGetAtt if resource is in acceptable state.
authorSteve Baker <sbaker@redhat.com>
Tue, 4 Jun 2013 04:40:12 +0000 (16:40 +1200)
committerSteve Baker <sbaker@redhat.com>
Wed, 5 Jun 2013 23:10:12 +0000 (11:10 +1200)
This will give resource type authors some certainty on what error
checking their FnGetAtt methods will require.

Fixes bug: #1184794

Change-Id: Iec456075c14cd609cf9607f07bce23e4c6b33c0c

heat/engine/template.py
heat/tests/test_metadata_refresh.py
heat/tests/test_parser.py

index 7c411126c8d11750b587ca87b91c571b7e59ff63..070ded30511a0e379a51b98a981b4ed4f1a7de98 100644 (file)
@@ -155,7 +155,13 @@ class Template(collections.Mapping):
         def handle_getatt(args):
             resource, att = args
             try:
-                return resources[resource].FnGetAtt(att)
+                r = resources[resource]
+                if r.state in (
+                        r.CREATE_IN_PROGRESS,
+                        r.CREATE_COMPLETE,
+                        r.UPDATE_IN_PROGRESS,
+                        r.UPDATE_COMPLETE):
+                    return r.FnGetAtt(att)
             except KeyError:
                 raise exception.InvalidTemplateAttribute(resource=resource,
                                                          key=att)
index 26c11015200285e6d3c0bf7057b8966e2b5af5ae..178110324b3bab47957fe9f262138542733d9d64 100644 (file)
@@ -179,6 +179,7 @@ class MetadataRefreshTest(HeatTestCase):
         s2 = self.stack.resources['S2']
         files = s1.metadata['AWS::CloudFormation::Init']['config']['files']
         cont = files['/tmp/random_file']['content']
+        self.assertEqual(s2.CREATE_COMPLETE, s2.state)
         self.assertEqual(cont, 's2-ip=1.2.3.5')
 
         s1.metadata_update()
@@ -247,7 +248,7 @@ class WaitCondMetadataUpdateTest(HeatTestCase):
 
         def check_empty(sleep_time):
             self.assertEqual(watch.FnGetAtt('Data'), '{}')
-            self.assertEqual(inst.metadata['test'], '{}')
+            self.assertEqual(inst.metadata['test'], None)
 
         def update_metadata(id, data, reason):
             self.man.metadata_update(self.ctx,
index adad9e6b2f3b053287a5dc75fed6fe577b23255e..dcdff3095e8c3f3b19cf83f82cedf509512d769b 100644 (file)
@@ -1203,3 +1203,41 @@ class StackTest(HeatTestCase):
                           parser.Template({}))
         self.assertRaises(ValueError, parser.Stack, None, '#test',
                           parser.Template({}))
+
+    @stack_delete_after
+    def test_resource_state_get_att(self):
+        tmpl = {
+            'Resources': {'AResource': {'Type': 'GenericResourceType'}},
+            'Outputs': {'TestOutput': {'Value': {
+                'Fn::GetAtt': ['AResource', 'Foo']}}
+            }
+        }
+
+        self.stack = parser.Stack(self.ctx, 'resource_state_get_att',
+                                  template.Template(tmpl))
+        self.stack.store()
+        self.stack.create()
+        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertTrue('AResource' in self.stack)
+        rsrc = self.stack['AResource']
+        rsrc.resource_id_set('aaaa')
+        self.assertEqual('AResource', rsrc.FnGetAtt('foo'))
+
+        for state in (
+                rsrc.CREATE_IN_PROGRESS,
+                rsrc.CREATE_COMPLETE,
+                rsrc.UPDATE_IN_PROGRESS,
+                rsrc.UPDATE_COMPLETE):
+            rsrc.state = state
+            self.assertEqual('AResource', self.stack.output('TestOutput'))
+        for state in (
+                rsrc.CREATE_FAILED,
+                rsrc.DELETE_IN_PROGRESS,
+                rsrc.DELETE_FAILED,
+                rsrc.DELETE_COMPLETE,
+                rsrc.UPDATE_FAILED,
+                None):
+            rsrc.state = state
+            self.assertEqual(None, self.stack.output('TestOutput'))
+
+        rsrc.state = rsrc.CREATE_COMPLETE