]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
engine : move update_template_diff functions into Resource
authorSteven Hardy <shardy@redhat.com>
Thu, 23 May 2013 10:21:16 +0000 (11:21 +0100)
committerSteven Hardy <shardy@redhat.com>
Thu, 23 May 2013 14:42:14 +0000 (15:42 +0100)
Move the update_template_diff and update_template_diff_properties
functions into resource.Resource - since they now raise
resource.UpdateReplace we can avoid ever calling handle_update if
the resource update will result in replacement

Note a further cleanup will probably be to combine the two diff
functions into one recursive diff, which will further simplify this

Change-Id: I839f0c4448a2d869f35e0a4f19d17f31c5c6f9af

21 files changed:
heat/engine/resource.py
heat/engine/resources/autoscaling.py
heat/engine/resources/cloud_watch.py
heat/engine/resources/instance.py
heat/tests/generic_resource.py
heat/tests/test_autoscaling.py
heat/tests/test_cw_alarm.py
heat/tests/test_eip.py
heat/tests/test_instance_group.py
heat/tests/test_loadbalancer.py
heat/tests/test_nested_stack.py
heat/tests/test_parser.py
heat/tests/test_quantum.py
heat/tests/test_resource.py
heat/tests/test_s3.py
heat/tests/test_security_group.py
heat/tests/test_swift.py
heat/tests/test_user.py
heat/tests/test_volume.py
heat/tests/test_vpc.py
heat/tests/test_waitcondition.py

index 2d20f5da2698131fc5cad4c67a64ad1175112bcd..706e1087c9c7da6c4be414cc8157fa2e04ec4b6e 100644 (file)
@@ -386,8 +386,10 @@ class Resource(object):
                                     self.stack.resolve_runtime_data,
                                     self.name)
             properties.validate()
+            tmpl_diff = self.update_template_diff(json_snippet)
+            prop_diff = self.update_template_diff_properties(json_snippet)
             if callable(getattr(self, 'handle_update', None)):
-                result = self.handle_update(json_snippet)
+                result = self.handle_update(json_snippet, tmpl_diff, prop_diff)
         except UpdateReplace:
             logger.debug("Resource %s update requires replacement" % self.name)
             raise
@@ -575,7 +577,7 @@ class Resource(object):
         '''
         return base64.b64encode(data)
 
-    def handle_update(self, json_snippet=None):
+    def handle_update(self, json_snippet=None, tmpl_diff=None, prop_diff=None):
         raise UpdateReplace(self.name)
 
     def metadata_update(self, new_metadata=None):
index fe4dc7b34cb61dc09aa382d38e30493f0f7843d6..7020aefe01e7511e9471d1f0e729a3ef686e21b9 100644 (file)
@@ -90,10 +90,7 @@ class InstanceGroup(resource.Resource):
         if creator is not None:
             creator.run_to_completion()
 
-    def handle_update(self, json_snippet):
-        tmpl_diff = self.update_template_diff(json_snippet)
-        prop_diff = self.update_template_diff_properties(json_snippet)
-
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
         # If Properties has changed, update self.properties, so we
         # get the new values during any subsequent adjustment
         if prop_diff:
@@ -280,10 +277,7 @@ class AutoScalingGroup(InstanceGroup, CooldownMixin):
 
         return self._adjust(num_to_create)
 
-    def handle_update(self, json_snippet):
-        tmpl_diff = self.update_template_diff(json_snippet)
-        prop_diff = self.update_template_diff_properties(json_snippet)
-
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
         # If Properties has changed, update self.properties, so we
         # get the new values during any subsequent adjustment
         if prop_diff:
@@ -411,10 +405,7 @@ class ScalingPolicy(resource.Resource, CooldownMixin):
     def __init__(self, name, json_snippet, stack):
         super(ScalingPolicy, self).__init__(name, json_snippet, stack)
 
-    def handle_update(self, json_snippet):
-        tmpl_diff = self.update_template_diff(json_snippet)
-        prop_diff = self.update_template_diff_properties(json_snippet)
-
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
         # If Properties has changed, update self.properties, so we
         # get the new values during any subsequent adjustment
         if prop_diff:
index 5b8d1d5bc42909fa44efa685ccccb23fe54e0901..7f110f6af6cde27d7ed7bfa379416bfbba557704 100644 (file)
@@ -90,10 +90,7 @@ class CloudWatchAlarm(resource.Resource):
                                  stack_id=self.stack.id)
         wr.store()
 
-    def handle_update(self, json_snippet):
-        self.update_template_diff(json_snippet)
-        prop_diff = self.update_template_diff_properties(json_snippet)
-
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
         # If Properties has changed, update self.properties, so we
         # get the new values during any subsequent adjustment
         if prop_diff:
index 2c9b85f1b90379c7cbd9add1216ce34b64174680..65847ca0e8c9be00dfe01527c4e355644c07f2be 100644 (file)
@@ -385,9 +385,7 @@ class Instance(resource.Resource):
                                                   vol['VolumeId'])
             scheduler.TaskRunner(detach_task)()
 
-    def handle_update(self, json_snippet):
-        tmpl_diff = self.update_template_diff(json_snippet)
-
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
         if 'Metadata' in tmpl_diff:
             self.metadata = tmpl_diff.get('Metadata', {})
 
index 5c068a2aafa030d9640fbc4f25821a382a01a30c..7cd267c4b5b2940b1d9f32d02098ed179a804e0d 100644 (file)
@@ -28,5 +28,5 @@ class GenericResource(resource.Resource):
     def handle_create(self):
         logger.warning('Creating generic resource (Type "%s")' % self.type())
 
-    def handle_update(self, json_snippet=None):
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
         logger.warning('Updating generic resource (Type "%s")' % self.type())
index 29283bf4c5638f078128a26e0238c56c9d95a796..f4b9d8043f8e9453c5cd3b1b68b8b63e2ed3c2b6 100644 (file)
@@ -138,7 +138,7 @@ class AutoScalingTest(HeatTestCase):
         for x in range(nmeta):
             Metadata.__set__(mox.IgnoreArg(), expected).AndReturn(None)
 
-    def test_scaling_group_update(self):
+    def test_scaling_group_update_replace(self):
         t = template_format.parse(as_template)
         stack = parse_stack(t)
 
@@ -151,8 +151,10 @@ class AutoScalingTest(HeatTestCase):
 
         self.assertEqual('WebServerGroup', rsrc.FnGetRefId())
         self.assertEqual('WebServerGroup-0', rsrc.resource_id)
+        update_snippet = copy.deepcopy(rsrc.parsed_template())
+        update_snippet['Properties']['LaunchConfigurationName'] = 'foo'
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.update, update_snippet)
 
         rsrc.delete()
         self.m.VerifyAll()
@@ -175,9 +177,11 @@ class AutoScalingTest(HeatTestCase):
         # Reduce the max size to 2, should complete without adjusting
         update_snippet = copy.deepcopy(rsrc.parsed_template())
         update_snippet['Properties']['MaxSize'] = '2'
-        self.assertEqual(None, rsrc.handle_update(update_snippet))
+        self.assertEqual(None, rsrc.update(update_snippet))
         self.assertEqual('WebServerGroup-0', rsrc.resource_id)
 
+        self.assertEqual('2', rsrc.properties['MaxSize'])
+
         rsrc.delete()
         self.m.VerifyAll()
 
@@ -204,9 +208,10 @@ class AutoScalingTest(HeatTestCase):
 
         update_snippet = copy.deepcopy(rsrc.parsed_template())
         update_snippet['Properties']['MinSize'] = '2'
-        self.assertEqual(None, rsrc.handle_update(update_snippet))
+        self.assertEqual(None, rsrc.update(update_snippet))
         self.assertEqual('WebServerGroup-0,WebServerGroup-1',
                          rsrc.resource_id)
+        self.assertEqual('2', rsrc.properties['MinSize'])
 
         rsrc.delete()
         self.m.VerifyAll()
@@ -234,10 +239,12 @@ class AutoScalingTest(HeatTestCase):
 
         update_snippet = copy.deepcopy(rsrc.parsed_template())
         update_snippet['Properties']['DesiredCapacity'] = '2'
-        self.assertEqual(None, rsrc.handle_update(update_snippet))
+        self.assertEqual(None, rsrc.update(update_snippet))
         self.assertEqual('WebServerGroup-0,WebServerGroup-1',
                          rsrc.resource_id)
 
+        self.assertEqual('2', rsrc.properties['DesiredCapacity'])
+
         rsrc.delete()
         self.m.VerifyAll()
 
@@ -260,10 +267,12 @@ class AutoScalingTest(HeatTestCase):
         # have no effect, it's an optional parameter
         update_snippet = copy.deepcopy(rsrc.parsed_template())
         del(update_snippet['Properties']['DesiredCapacity'])
-        self.assertEqual(None, rsrc.handle_update(update_snippet))
+        self.assertEqual(None, rsrc.update(update_snippet))
         self.assertEqual('WebServerGroup-0,WebServerGroup-1',
                          rsrc.resource_id)
 
+        self.assertEqual(None, rsrc.properties['DesiredCapacity'])
+
         rsrc.delete()
         self.m.VerifyAll()
 
@@ -284,7 +293,8 @@ class AutoScalingTest(HeatTestCase):
         self.assertEqual('WebServerGroup-0', rsrc.resource_id)
         update_snippet = copy.deepcopy(rsrc.parsed_template())
         update_snippet['Properties']['Cooldown'] = '61'
-        self.assertEqual(None, rsrc.handle_update(update_snippet))
+        self.assertEqual(None, rsrc.update(update_snippet))
+        self.assertEqual('61', rsrc.properties['Cooldown'])
 
         rsrc.delete()
         self.m.VerifyAll()
@@ -854,8 +864,7 @@ class AutoScalingTest(HeatTestCase):
         # Update scaling policy
         update_snippet = copy.deepcopy(up_policy.parsed_template())
         update_snippet['Properties']['ScalingAdjustment'] = '2'
-        self.assertEqual(None,
-                         up_policy.handle_update(update_snippet))
+        self.assertEqual(None, up_policy.update(update_snippet))
         self.assertEqual('2',
                          up_policy.properties['ScalingAdjustment'])
 
index 44c43afb77e12f28f2682f552a65708f1e1b5e56..a06f7901bf222676e62e906bb55c5b9106e83923 100644 (file)
@@ -91,7 +91,7 @@ class CloudWatchAlarmTest(HeatTestCase):
         snippet['Properties']['Statistic'] = 'Maximum'
         snippet['Properties']['Threshold'] = '39'
 
-        self.assertEqual(None, rsrc.handle_update(snippet))
+        self.assertEqual(None, rsrc.update(snippet))
 
         rsrc.delete()
         self.m.VerifyAll()
@@ -118,7 +118,7 @@ class CloudWatchAlarmTest(HeatTestCase):
         snippet['Properties']['MetricName'] = 'temp'
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, snippet)
+                          rsrc.update, snippet)
 
         rsrc.delete()
         self.m.VerifyAll()
index 05487fd42fad7f6f582b2cbe7458b87dccda4763..6a810d8bb565f4763b51411bea9f56c05bba9446 100644 (file)
@@ -94,7 +94,7 @@ class EIPTest(HeatTestCase):
             self.assertEqual('1', rsrc.FnGetAtt('AllocationId'))
 
             self.assertRaises(resource.UpdateReplace,
-                              rsrc.handle_update, {})
+                              rsrc.handle_update, {}, {}, {})
 
             self.assertRaises(eip.exception.InvalidTemplateAttribute,
                               rsrc.FnGetAtt, 'Foo')
index dac6dd1a6323fbda005062557eb7b537f45ba8be..0e6316e0826a7e8f04f948f02c9b5d2142330bd8 100644 (file)
@@ -100,8 +100,6 @@ class InstanceGroupTest(HeatTestCase):
         self.assertEqual('JobServerGroup', rsrc.FnGetRefId())
         self.assertEqual('1.2.3.4', rsrc.FnGetAtt('InstanceList'))
         self.assertEqual('JobServerGroup-0', rsrc.resource_id)
-        self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
 
         rsrc.delete()
         self.m.VerifyAll()
@@ -127,7 +125,7 @@ class InstanceGroupTest(HeatTestCase):
 
         self.m.VerifyAll()
 
-    def test_update_size(self):
+    def test_handle_update_size(self):
         t = template_format.parse(ig_template)
         properties = t['Resources']['JobServerGroup']['Properties']
         properties['Size'] = '2'
@@ -155,7 +153,10 @@ class InstanceGroupTest(HeatTestCase):
 
         update_snippet = copy.deepcopy(rsrc.parsed_template())
         update_snippet['Properties']['Size'] = '5'
-        self.assertEqual(None, rsrc.handle_update(update_snippet))
+        tmpl_diff = {'Properties': {'Size': '5'}}
+        prop_diff = {'Size': '5'}
+        self.assertEqual(None, rsrc.handle_update(update_snippet, tmpl_diff,
+                         prop_diff))
         assert_str = ','.join(['JobServerGroup-%s' % x for x in range(5)])
         self.assertEqual(assert_str,
                          rsrc.resource_id)
@@ -164,3 +165,47 @@ class InstanceGroupTest(HeatTestCase):
 
         rsrc.delete()
         self.m.VerifyAll()
+
+    def test_update_fail_badkey(self):
+        t = template_format.parse(ig_template)
+        properties = t['Resources']['JobServerGroup']['Properties']
+        properties['Size'] = '2'
+        stack = parse_stack(t)
+
+        self._stub_create(2)
+        self.m.ReplayAll()
+        rsrc = self.create_instance_group(t, stack, 'JobServerGroup')
+        self.assertEqual('JobServerGroup-0,JobServerGroup-1',
+                         rsrc.resource_id)
+
+        self.m.ReplayAll()
+
+        update_snippet = copy.deepcopy(rsrc.parsed_template())
+        update_snippet['Metadata'] = 'notallowedforupdate'
+        self.assertRaises(resource.UpdateReplace,
+                          rsrc.update, update_snippet)
+
+        rsrc.delete()
+        self.m.VerifyAll()
+
+    def test_update_fail_badprop(self):
+        t = template_format.parse(ig_template)
+        properties = t['Resources']['JobServerGroup']['Properties']
+        properties['Size'] = '2'
+        stack = parse_stack(t)
+
+        self._stub_create(2)
+        self.m.ReplayAll()
+        rsrc = self.create_instance_group(t, stack, 'JobServerGroup')
+        self.assertEqual('JobServerGroup-0,JobServerGroup-1',
+                         rsrc.resource_id)
+
+        self.m.ReplayAll()
+
+        update_snippet = copy.deepcopy(rsrc.parsed_template())
+        update_snippet['Properties']['LaunchConfigurationName'] = 'wibble'
+        self.assertRaises(resource.UpdateReplace,
+                          rsrc.update, update_snippet)
+
+        rsrc.delete()
+        self.m.VerifyAll()
index f9dfd40b6b0d8ce1d80d908b498b4e6931b2e352..1b290e970bde8be039307afd40c61994b01b5f58 100644 (file)
@@ -170,7 +170,7 @@ class LoadBalancerTest(HeatTestCase):
             pass
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         self.m.VerifyAll()
 
index 34e8e1a14cb795f17a5071433b3f1b2d1ae78086..753b214a01401ad42c66fb1a8738b57dbd0ce109 100644 (file)
@@ -78,7 +78,7 @@ Outputs:
             'arn:openstack:heat::aaaa:stacks/test_stack.the_nested/'))
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         self.assertEqual('bar', rsrc.FnGetAtt('Outputs.Foo'))
         self.assertRaises(
index 335c914a5e9fcde6be2694696536a0331a5463a3..92234462978744859b4bc0f12de890550ea0a35b 100644 (file)
@@ -560,11 +560,10 @@ class StackTest(HeatTestCase):
 
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
-        # patch in a dummy handle_update
-        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
+
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
@@ -588,6 +587,10 @@ class StackTest(HeatTestCase):
         self.stack.create()
         self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
 
+        res = self.stack['AResource']
+        res.update_allowed_keys = ('Properties',)
+        res.update_allowed_properties = ('Foo',)
+
         tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType',
                                              'Properties': {'Foo': 'xyz'}}}}
 
@@ -596,8 +599,11 @@ class StackTest(HeatTestCase):
 
         # patch in a dummy handle_update
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
+        tmpl_diff = {'Properties': {'Foo': 'xyz'}}
+        prop_diff = {'Foo': 'xyz'}
         generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(Exception("Foo"))
+            tmpl2['Resources']['AResource'], tmpl_diff,
+            prop_diff).AndRaise(Exception("Foo"))
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
@@ -626,11 +632,9 @@ class StackTest(HeatTestCase):
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
 
-        # patch in a dummy handle_update
-        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
 
         # make the update fail deleting the existing resource
         self.m.StubOutWithMock(resource.Resource, 'destroy')
@@ -666,11 +670,9 @@ class StackTest(HeatTestCase):
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
 
-        # patch in a dummy handle_update
-        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
 
         # patch in a dummy handle_create making the replace fail creating
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_create')
@@ -734,15 +736,9 @@ class StackTest(HeatTestCase):
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
 
-        # There will be two calls to handle_update, one for the new template
-        # then another (with the initial template) for rollback
-        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
-        generic_rsrc.GenericResource.handle_update(
-            tmpl['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
 
         # patch in a dummy handle_create making the replace fail when creating
         # the replacement rsrc, but succeed the second call (rollback)
@@ -778,15 +774,9 @@ class StackTest(HeatTestCase):
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
 
-        # There will be two calls to handle_update, one for the new template
-        # then another (with the initial template) for rollback
-        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
-        generic_rsrc.GenericResource.handle_update(
-            tmpl['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
 
         # patch in a dummy handle_create making the replace fail when creating
         # the replacement rsrc, and again on the second call (rollback)
@@ -891,15 +881,9 @@ class StackTest(HeatTestCase):
         self.assertEqual(self.stack['BResource'].properties['Foo'],
                          'AResource')
 
-        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
-
-        br2_snip = {'Type': 'GenericResourceType',
-                    'Properties': {'Foo': 'inst-007'}}
-        generic_rsrc.GenericResource.handle_update(
-            br2_snip).AndRaise(resource.UpdateReplace)
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
 
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'FnGetRefId')
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
@@ -949,25 +933,19 @@ class StackTest(HeatTestCase):
         self.assertEqual(self.stack['BResource'].properties['Foo'],
                          'AResource')
 
-        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'FnGetRefId')
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_create')
 
-        # mocks for first (failed update)
-        generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
+
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'AResource')
 
         # mock to make the replace fail when creating the replacement resource
         generic_rsrc.GenericResource.handle_create().AndRaise(Exception)
 
-        # mocks for second rollback update
-        generic_rsrc.GenericResource.handle_update(
-            tmpl['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
-
         generic_rsrc.GenericResource.handle_create().AndReturn(None)
         generic_rsrc.GenericResource.FnGetRefId().MultipleTimes().AndReturn(
             'AResource')
@@ -1016,18 +994,12 @@ class StackTest(HeatTestCase):
         self.assertEqual(self.stack['BResource'].properties['Foo'],
                          'AResource')
 
-        self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'FnGetRefId')
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_create')
 
-        # mocks for first and second (failed update)
-        generic_rsrc.GenericResource.handle_update(
-            tmpl2['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
-        br2_snip = {'Type': 'GenericResourceType',
-                    'Properties': {'Foo': 'inst-007'}}
-        generic_rsrc.GenericResource.handle_update(
-            br2_snip).AndRaise(resource.UpdateReplace)
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
 
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'AResource')
@@ -1054,14 +1026,9 @@ class StackTest(HeatTestCase):
         generic_rsrc.GenericResource.handle_create().AndReturn(None)
         generic_rsrc.GenericResource.handle_create().AndRaise(Exception)
 
-        # mocks for second rollback update
-        generic_rsrc.GenericResource.handle_update(
-            tmpl['Resources']['AResource']).AndRaise(
-                resource.UpdateReplace)
-        br2_snip = {'Type': 'GenericResourceType',
-                    'Properties': {'Foo': 'AResource'}}
-        generic_rsrc.GenericResource.handle_update(
-            br2_snip).AndRaise(resource.UpdateReplace)
+        # Calls to GenericResource.handle_update will raise
+        # resource.UpdateReplace because we've not specified the modified
+        # key/property in update_allowed_keys/update_allowed_properties
 
         # self.state_set(self.DELETE_IN_PROGRESS)
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
index 8a73a8f2758d810b389fcb3a586a508583808612..0b815ecbcb393038d22868e7267e2ab6f5d28dc7 100644 (file)
@@ -289,7 +289,7 @@ class QuantumNetTest(HeatTestCase):
                          rsrc.FnGetAtt('id'))
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         rsrc.delete()
         rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
@@ -386,7 +386,7 @@ class QuantumSubnetTest(HeatTestCase):
                          rsrc.FnGetAtt('id'))
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         self.assertEqual(rsrc.delete(), None)
         rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
@@ -514,7 +514,7 @@ class QuantumRouterTest(HeatTestCase):
                          rsrc.FnGetAtt('id'))
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         self.assertEqual(rsrc.delete(), None)
         rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again')
@@ -639,7 +639,7 @@ class QuantumFloatingIPTest(HeatTestCase):
         self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
                          fip.FnGetAtt('id'))
         self.assertRaises(resource.UpdateReplace,
-                          fip.handle_update, {})
+                          fip.handle_update, {}, {}, {})
         self.assertEqual(fip.delete(), None)
         fip.state_set(fip.CREATE_COMPLETE, 'to delete again')
         self.assertEqual(fip.delete(), None)
@@ -707,7 +707,7 @@ class QuantumFloatingIPTest(HeatTestCase):
                          p.FnGetAtt('id'))
 
         self.assertRaises(resource.UpdateReplace,
-                          p.handle_update, {})
+                          p.handle_update, {}, {}, {})
 
         self.m.VerifyAll()
 
@@ -800,7 +800,7 @@ class QuantumFloatingIPTest(HeatTestCase):
         port_id = p.FnGetRefId()
         self.assertEqual('%s:%s' % (fip_id, port_id), fipa_id)
         self.assertRaises(resource.UpdateReplace,
-                          fipa.handle_update, {})
+                          fipa.handle_update, {}, {}, {})
 
         self.assertEqual(fipa.delete(), None)
         self.assertEqual(p.delete(), None)
index 2f2baf9a5e6d332c41d0f0a50b167a6c860c2486..431a0f886c2a549d8c5fe566c1556118c4c6bc6b 100644 (file)
@@ -262,12 +262,17 @@ class ResourceTest(HeatTestCase):
 
         tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
         res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_keys = ('Properties',)
+        res.update_allowed_properties = ('Foo',)
         scheduler.TaskRunner(res.create)()
         self.assertEqual(res.CREATE_COMPLETE, res.state)
 
         utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}}
+        tmpl_diff = {'Properties': {'Foo': 'xyz'}}
+        prop_diff = {'Foo': 'xyz'}
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(utmpl).AndReturn(None)
+        generic_rsrc.GenericResource.handle_update(
+            utmpl, tmpl_diff, prop_diff).AndReturn(None)
         self.m.ReplayAll()
 
         self.assertEqual(None, res.update(utmpl))
@@ -281,13 +286,17 @@ class ResourceTest(HeatTestCase):
 
         tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
         res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_keys = ('Properties',)
+        res.update_allowed_properties = ('Foo',)
         scheduler.TaskRunner(res.create)()
         self.assertEqual(res.CREATE_COMPLETE, res.state)
 
         utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}}
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(utmpl).AndRaise(
-            resource.UpdateReplace())
+        tmpl_diff = {'Properties': {'Foo': 'xyz'}}
+        prop_diff = {'Foo': 'xyz'}
+        generic_rsrc.GenericResource.handle_update(
+            utmpl, tmpl_diff, prop_diff).AndRaise(resource.UpdateReplace())
         self.m.ReplayAll()
         # should be re-raised so parser.Stack can handle replacement
         self.assertRaises(resource.UpdateReplace, res.update, utmpl)
@@ -300,6 +309,8 @@ class ResourceTest(HeatTestCase):
 
         tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
         res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_keys = ('Properties',)
+        res.update_allowed_properties = ('Foo',)
         scheduler.TaskRunner(res.create)()
         self.assertEqual(res.CREATE_COMPLETE, res.state)
 
@@ -315,6 +326,8 @@ class ResourceTest(HeatTestCase):
 
         tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
         res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_keys = ('Properties',)
+        res.update_allowed_properties = ('Foo',)
         scheduler.TaskRunner(res.create)()
         self.assertEqual(res.CREATE_COMPLETE, res.state)
 
@@ -330,13 +343,17 @@ class ResourceTest(HeatTestCase):
 
         tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
         res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_keys = ('Properties',)
+        res.update_allowed_properties = ('Foo',)
         scheduler.TaskRunner(res.create)()
         self.assertEqual(res.CREATE_COMPLETE, res.state)
 
         utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}}
+        tmpl_diff = {'Properties': {'Foo': 'xyz'}}
+        prop_diff = {'Foo': 'xyz'}
         self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update')
-        generic_rsrc.GenericResource.handle_update(utmpl).AndRaise(
-            NotImplemented)
+        generic_rsrc.GenericResource.handle_update(utmpl, tmpl_diff, prop_diff
+                                                   ).AndRaise(NotImplemented)
         self.m.ReplayAll()
         self.assertRaises(exception.ResourceFailure, res.update, utmpl)
         self.assertEqual(res.UPDATE_FAILED, res.state)
index 2ef126bc792eb5d9d1056a7c39dd283c3f166ea8..3f08a9eb0dd9411dfb98b29652874e8167a1d02c 100644 (file)
@@ -119,7 +119,7 @@ class s3Test(HeatTestCase):
             pass
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         rsrc.delete()
         self.m.VerifyAll()
index ffb8c6530175f7d028956f249f56b705a59a0071..cfb496f5eb98b6493351d4e1750d45a4a6587f00 100644 (file)
@@ -193,7 +193,7 @@ Resources:
         stack = self.create_stack(self.test_template_nova)
 
         sg = stack['the_sg']
-        self.assertRaises(resource.UpdateReplace, sg.handle_update, {})
+        self.assertRaises(resource.UpdateReplace, sg.handle_update, {}, {}, {})
 
         self.assertResourceState(sg, 'the_sg')
 
@@ -266,7 +266,7 @@ Resources:
         stack = self.create_stack(self.test_template_nova)
 
         sg = stack['the_sg']
-        self.assertRaises(resource.UpdateReplace, sg.handle_update, {})
+        self.assertRaises(resource.UpdateReplace, sg.handle_update, {}, {}, {})
 
         self.assertResourceState(sg, 'the_sg')
 
@@ -410,7 +410,7 @@ Resources:
         stack = self.create_stack(self.test_template_quantum)
 
         sg = stack['the_sg']
-        self.assertRaises(resource.UpdateReplace, sg.handle_update, {})
+        self.assertRaises(resource.UpdateReplace, sg.handle_update, {}, {}, {})
 
         self.assertResourceState(sg, 'the_sg')
 
@@ -526,7 +526,7 @@ Resources:
         stack = self.create_stack(self.test_template_quantum)
 
         sg = stack['the_sg']
-        self.assertRaises(resource.UpdateReplace, sg.handle_update, {})
+        self.assertRaises(resource.UpdateReplace, sg.handle_update, {}, {}, {})
 
         self.assertResourceState(sg, 'the_sg')
 
index c537a5537f93c38065f6880b7e394d3e762a56db..1ad87ca3a9d02512e01e81788965cb1e16fedc00 100644 (file)
@@ -155,7 +155,7 @@ class swiftTest(HeatTestCase):
             pass
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         rsrc.delete()
         self.m.VerifyAll()
index fe784183fed09767c7e91b997a87cbb54f6d8f54..080aee3a8b67247b1c2fcafbcbfb56af8b6dd43d 100644 (file)
@@ -124,7 +124,7 @@ class UserTest(UserPolicyTestCase):
 
         self.assertEqual('CREATE_COMPLETE', rsrc.state)
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         rsrc.resource_id = None
         self.assertEqual(None, rsrc.delete())
@@ -279,7 +279,7 @@ class AccessKeyTest(UserPolicyTestCase):
         rsrc = self.create_access_key(t, stack, 'HostKeys')
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
         self.assertEqual(self.fc.access,
                          rsrc.resource_id)
 
@@ -379,7 +379,7 @@ class AccessPolicyTest(UserPolicyTestCase):
                                  t['Resources'][resource_name],
                                  stack)
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
     def test_accesspolicy_access_allowed(self):
         t = template_format.parse(user_policy_template)
index 530c030d82f14b6921507e732e331050bc30b4e4..b49c4f37aa193fb97929e0b2c2f79348bbedcd88 100644 (file)
@@ -133,7 +133,7 @@ class VolumeTest(HeatTestCase):
         self.assertEqual(fv.status, 'available')
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         fv.status = 'in-use'
         self.assertRaises(exception.ResourceFailure, rsrc.destroy)
@@ -251,7 +251,7 @@ class VolumeTest(HeatTestCase):
         rsrc = self.create_attachment(t, stack, 'MountPoint')
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         self.assertEqual(rsrc.delete(), None)
 
@@ -556,7 +556,8 @@ class VolumeTest(HeatTestCase):
         scheduler.TaskRunner(rsrc.create)()
         self.assertEqual(rsrc.state, vol.VolumeAttachment.CREATE_COMPLETE)
 
-        self.assertRaises(resource.UpdateReplace, rsrc.handle_update, {})
+        self.assertRaises(resource.UpdateReplace, rsrc.handle_update,
+                          {}, {}, {})
 
         self.assertEqual(rsrc.delete(), None)
 
index beea1795d3b55a9df17cd1d64bd8982c79179b9c..ebb1242025d44686232e5e8cdf30285c91fe4323 100644 (file)
@@ -229,7 +229,7 @@ Resources:
             'router_id': 'bbbb',
             'all_router_ids': ['bbbb']})
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
 
         self.assertEqual(None, rsrc.delete())
         self.m.VerifyAll()
@@ -274,7 +274,7 @@ Resources:
             'default_router_id': 'bbbb'})
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
         self.assertRaises(
             exception.InvalidTemplateAttribute,
             rsrc.FnGetAtt,
@@ -446,7 +446,7 @@ Resources:
             self.assertResourceState(rsrc, 'dddd')
 
             self.assertRaises(resource.UpdateReplace,
-                              rsrc.handle_update, {})
+                              rsrc.handle_update, {}, {}, {})
 
         finally:
             stack.delete()
@@ -564,12 +564,13 @@ Resources:
         gateway = stack['the_gateway']
         self.assertResourceState(gateway, 'the_gateway', {
             'external_network_id': 'eeee'})
-        self.assertRaises(resource.UpdateReplace, gateway.handle_update, {})
+        self.assertRaises(resource.UpdateReplace, gateway.handle_update,
+                          {}, {}, {})
 
         attachment = stack['the_attachment']
         self.assertResourceState(attachment, 'the_attachment')
         self.assertRaises(resource.UpdateReplace,
-                          attachment.handle_update, {})
+                          attachment.handle_update, {}, {}, {})
 
         stack.delete()
         self.m.VerifyAll()
@@ -653,13 +654,13 @@ Resources:
         self.assertResourceState(route_table, 'ffff', {})
         self.assertRaises(
             resource.UpdateReplace,
-            route_table.handle_update, {})
+            route_table.handle_update, {}, {}, {})
 
         association = stack['the_association']
         self.assertResourceState(association, 'the_association', {})
         self.assertRaises(
             resource.UpdateReplace,
-            association.handle_update, {})
+            association.handle_update, {}, {}, {})
 
         association.delete()
         route_table.delete()
index 6ead438624ecaac1be753121f5b148c39d738633..aeeaf29360aa4c15abbcbdc7530ee43c6f40fd2c 100644 (file)
@@ -243,7 +243,7 @@ class WaitConditionTest(HeatTestCase):
         self.assertTrue(reason.startswith('WaitConditionTimeout:'))
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
         self.m.VerifyAll()
 
     @stack_delete_after
@@ -450,7 +450,7 @@ class WaitConditionHandleTest(HeatTestCase):
         self.assertEqual(expected_url, rsrc.FnGetRefId())
 
         self.assertRaises(resource.UpdateReplace,
-                          rsrc.handle_update, {})
+                          rsrc.handle_update, {}, {}, {})
         self.m.VerifyAll()
 
     @stack_delete_after