From 0eaeeac888d008ae9f22f9bce6c7451a088f5fe4 Mon Sep 17 00:00:00 2001 From: Steven Hardy Date: Thu, 23 May 2013 11:21:16 +0100 Subject: [PATCH] engine : move update_template_diff functions into Resource 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 --- heat/engine/resource.py | 6 +- heat/engine/resources/autoscaling.py | 15 +--- heat/engine/resources/cloud_watch.py | 5 +- heat/engine/resources/instance.py | 4 +- heat/tests/generic_resource.py | 2 +- heat/tests/test_autoscaling.py | 27 ++++--- heat/tests/test_cw_alarm.py | 4 +- heat/tests/test_eip.py | 2 +- heat/tests/test_instance_group.py | 53 ++++++++++++- heat/tests/test_loadbalancer.py | 2 +- heat/tests/test_nested_stack.py | 2 +- heat/tests/test_parser.py | 107 +++++++++------------------ heat/tests/test_quantum.py | 12 +-- heat/tests/test_resource.py | 27 +++++-- heat/tests/test_s3.py | 2 +- heat/tests/test_security_group.py | 8 +- heat/tests/test_swift.py | 2 +- heat/tests/test_user.py | 6 +- heat/tests/test_volume.py | 7 +- heat/tests/test_vpc.py | 15 ++-- heat/tests/test_waitcondition.py | 4 +- 21 files changed, 170 insertions(+), 142 deletions(-) diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 2d20f5da..706e1087 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -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): diff --git a/heat/engine/resources/autoscaling.py b/heat/engine/resources/autoscaling.py index fe4dc7b3..7020aefe 100644 --- a/heat/engine/resources/autoscaling.py +++ b/heat/engine/resources/autoscaling.py @@ -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: diff --git a/heat/engine/resources/cloud_watch.py b/heat/engine/resources/cloud_watch.py index 5b8d1d5b..7f110f6a 100644 --- a/heat/engine/resources/cloud_watch.py +++ b/heat/engine/resources/cloud_watch.py @@ -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: diff --git a/heat/engine/resources/instance.py b/heat/engine/resources/instance.py index 2c9b85f1..65847ca0 100644 --- a/heat/engine/resources/instance.py +++ b/heat/engine/resources/instance.py @@ -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', {}) diff --git a/heat/tests/generic_resource.py b/heat/tests/generic_resource.py index 5c068a2a..7cd267c4 100644 --- a/heat/tests/generic_resource.py +++ b/heat/tests/generic_resource.py @@ -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()) diff --git a/heat/tests/test_autoscaling.py b/heat/tests/test_autoscaling.py index 29283bf4..f4b9d804 100644 --- a/heat/tests/test_autoscaling.py +++ b/heat/tests/test_autoscaling.py @@ -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']) diff --git a/heat/tests/test_cw_alarm.py b/heat/tests/test_cw_alarm.py index 44c43afb..a06f7901 100644 --- a/heat/tests/test_cw_alarm.py +++ b/heat/tests/test_cw_alarm.py @@ -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() diff --git a/heat/tests/test_eip.py b/heat/tests/test_eip.py index 05487fd4..6a810d8b 100644 --- a/heat/tests/test_eip.py +++ b/heat/tests/test_eip.py @@ -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') diff --git a/heat/tests/test_instance_group.py b/heat/tests/test_instance_group.py index dac6dd1a..0e6316e0 100644 --- a/heat/tests/test_instance_group.py +++ b/heat/tests/test_instance_group.py @@ -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() diff --git a/heat/tests/test_loadbalancer.py b/heat/tests/test_loadbalancer.py index f9dfd40b..1b290e97 100644 --- a/heat/tests/test_loadbalancer.py +++ b/heat/tests/test_loadbalancer.py @@ -170,7 +170,7 @@ class LoadBalancerTest(HeatTestCase): pass self.assertRaises(resource.UpdateReplace, - rsrc.handle_update, {}) + rsrc.handle_update, {}, {}, {}) self.m.VerifyAll() diff --git a/heat/tests/test_nested_stack.py b/heat/tests/test_nested_stack.py index 34e8e1a1..753b214a 100644 --- a/heat/tests/test_nested_stack.py +++ b/heat/tests/test_nested_stack.py @@ -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( diff --git a/heat/tests/test_parser.py b/heat/tests/test_parser.py index 335c914a..92234462 100644 --- a/heat/tests/test_parser.py +++ b/heat/tests/test_parser.py @@ -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( diff --git a/heat/tests/test_quantum.py b/heat/tests/test_quantum.py index 8a73a8f2..0b815ecb 100644 --- a/heat/tests/test_quantum.py +++ b/heat/tests/test_quantum.py @@ -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) diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index 2f2baf9a..431a0f88 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -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) diff --git a/heat/tests/test_s3.py b/heat/tests/test_s3.py index 2ef126bc..3f08a9eb 100644 --- a/heat/tests/test_s3.py +++ b/heat/tests/test_s3.py @@ -119,7 +119,7 @@ class s3Test(HeatTestCase): pass self.assertRaises(resource.UpdateReplace, - rsrc.handle_update, {}) + rsrc.handle_update, {}, {}, {}) rsrc.delete() self.m.VerifyAll() diff --git a/heat/tests/test_security_group.py b/heat/tests/test_security_group.py index ffb8c653..cfb496f5 100644 --- a/heat/tests/test_security_group.py +++ b/heat/tests/test_security_group.py @@ -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') diff --git a/heat/tests/test_swift.py b/heat/tests/test_swift.py index c537a553..1ad87ca3 100644 --- a/heat/tests/test_swift.py +++ b/heat/tests/test_swift.py @@ -155,7 +155,7 @@ class swiftTest(HeatTestCase): pass self.assertRaises(resource.UpdateReplace, - rsrc.handle_update, {}) + rsrc.handle_update, {}, {}, {}) rsrc.delete() self.m.VerifyAll() diff --git a/heat/tests/test_user.py b/heat/tests/test_user.py index fe784183..080aee3a 100644 --- a/heat/tests/test_user.py +++ b/heat/tests/test_user.py @@ -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) diff --git a/heat/tests/test_volume.py b/heat/tests/test_volume.py index 530c030d..b49c4f37 100644 --- a/heat/tests/test_volume.py +++ b/heat/tests/test_volume.py @@ -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) diff --git a/heat/tests/test_vpc.py b/heat/tests/test_vpc.py index beea1795..ebb12420 100644 --- a/heat/tests/test_vpc.py +++ b/heat/tests/test_vpc.py @@ -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() diff --git a/heat/tests/test_waitcondition.py b/heat/tests/test_waitcondition.py index 6ead4386..aeeaf293 100644 --- a/heat/tests/test_waitcondition.py +++ b/heat/tests/test_waitcondition.py @@ -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 -- 2.45.2