diff options
author | Jan Provaznik <jprovazn@redhat.com> | 2014-10-01 15:26:45 +0200 |
---|---|---|
committer | Steven Hardy <shardy@redhat.com> | 2015-01-29 11:06:06 +0000 |
commit | b52c916da0759fb5b310ecbcce5db2608b67fdb1 (patch) | |
tree | a5c3c87a1add20fa1c6b363ad54537a48d9d1c98 | |
parent | 97bd3cca359b6cd59fb5330988e45135db52eefe (diff) | |
download | heat-b52c916da0759fb5b310ecbcce5db2608b67fdb1.tar.gz |
Convert bool/int values into string for string properties2014.2.2
Instead of rising an exception, boolean and integer values are
converted into string if string is expected.
Change-Id: I1e0014576c4df447bfa1595c530f1e24f411195d
Closes-Bug: #1367375
(cherry picked from commit 48214930bbec2e09569d848fa5b8759c429acd5b)
-rw-r--r-- | heat/engine/properties.py | 5 | ||||
-rw-r--r-- | heat/tests/generic_resource.py | 3 | ||||
-rw-r--r-- | heat/tests/test_autoscaling.py | 20 | ||||
-rw-r--r-- | heat/tests/test_engine_service.py | 6 | ||||
-rw-r--r-- | heat/tests/test_event.py | 2 | ||||
-rw-r--r-- | heat/tests/test_instance.py | 24 | ||||
-rw-r--r-- | heat/tests/test_properties.py | 29 |
7 files changed, 37 insertions, 52 deletions
diff --git a/heat/engine/properties.py b/heat/engine/properties.py index 0bec8fab5..bca7d552b 100644 --- a/heat/engine/properties.py +++ b/heat/engine/properties.py @@ -243,7 +243,10 @@ class Property(object): if value is None: value = self.has_default() and self.default() or '' if not isinstance(value, basestring): - raise ValueError(_('Value must be a string')) + if isinstance(value, (bool, int)): + value = six.text_type(value) + else: + raise ValueError(_('Value must be a string')) return value def _get_children(self, child_values, keys=None, validate=False): diff --git a/heat/tests/generic_resource.py b/heat/tests/generic_resource.py index 8e102d711..de3665041 100644 --- a/heat/tests/generic_resource.py +++ b/heat/tests/generic_resource.py @@ -76,7 +76,8 @@ class ResWithComplexPropsAndAttrs(GenericResource): class ResourceWithProps(GenericResource): - properties_schema = {'Foo': {'Type': 'String'}} + properties_schema = {'Foo': {'Type': 'String'}, + 'FooInt': {'Type': 'Integer'}} class ResourceWithPropsAndAttrs(ResourceWithProps): diff --git a/heat/tests/test_autoscaling.py b/heat/tests/test_autoscaling.py index 468d0035e..d57f688dc 100644 --- a/heat/tests/test_autoscaling.py +++ b/heat/tests/test_autoscaling.py @@ -1751,26 +1751,6 @@ class AutoScalingTest(HeatTestCase): self.assertIsNone(rsrc.resource_id) self.assertEqual('LaunchConfig', rsrc.FnGetRefId()) - def test_validate_BlockDeviceMappings_VolumeSize_invalid_str(self): - t = template_format.parse(as_template) - lcp = t['Resources']['LaunchConfig']['Properties'] - bdm = [{'DeviceName': 'vdb', - 'Ebs': {'SnapshotId': '1234', - 'VolumeSize': 10}}] - lcp['BlockDeviceMappings'] = bdm - stack = utils.parse_stack(t, params=self.params) - self.stub_ImageConstraint_validate() - self.m.ReplayAll() - - e = self.assertRaises(exception.StackValidationFailed, - self.create_scaling_group, t, - stack, 'LaunchConfig') - - expected_msg = "Value must be a string" - self.assertIn(expected_msg, six.text_type(e)) - - self.m.VerifyAll() - def test_validate_BlockDeviceMappings_without_Ebs_property(self): t = template_format.parse(as_template) lcp = t['Resources']['LaunchConfig']['Properties'] diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index fa8387fb2..1bcead69d 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -2202,6 +2202,12 @@ class StackServiceTest(HeatTestCase): 'update_allowed': False, 'immutable': False, }, + 'FooInt': { + 'type': 'integer', + 'required': False, + 'update_allowed': False, + 'immutable': False, + }, }, 'attributes': { 'foo': {'description': 'A generic attribute'}, diff --git a/heat/tests/test_event.py b/heat/tests/test_event.py index 1f756a568..638b0f685 100644 --- a/heat/tests/test_event.py +++ b/heat/tests/test_event.py @@ -149,7 +149,7 @@ class EventTest(HeatTestCase): rname = 'bad_resource' defn = rsrc_defn.ResourceDefinition(rname, 'ResourceWithRequiredProps', - {'Foo': False}) + {'IntFoo': False}) res = generic_rsrc.ResourceWithRequiredProps(rname, defn, self.stack) e = event.Event(self.ctx, self.stack, 'TEST', 'IN_PROGRESS', 'Testing', diff --git a/heat/tests/test_instance.py b/heat/tests/test_instance.py index 92698c362..e52198999 100644 --- a/heat/tests/test_instance.py +++ b/heat/tests/test_instance.py @@ -225,30 +225,6 @@ class InstancesTest(HeatTestCase): self.m.VerifyAll() - def test_validate_BlockDeviceMappings_VolumeSize_invalid_str(self): - stack_name = 'val_VolumeSize_valid' - tmpl, stack = self._setup_test_stack(stack_name) - bdm = [{'DeviceName': 'vdb', - 'Ebs': {'SnapshotId': '1234', - 'VolumeSize': 10}}] - wsp = tmpl.t['Resources']['WebServer']['Properties'] - wsp['BlockDeviceMappings'] = bdm - resource_defns = tmpl.resource_definitions(stack) - instance = instances.Instance('validate_volume_size', - resource_defns['WebServer'], stack) - - self._mock_get_image_id_success('F17-x86_64-gold', 1) - self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') - nova.NovaClientPlugin._create().MultipleTimes().AndReturn(self.fc) - - self.m.ReplayAll() - - exc = self.assertRaises(exception.StackValidationFailed, - instance.validate) - self.assertIn("Value must be a string", six.text_type(exc)) - - self.m.VerifyAll() - def test_validate_BlockDeviceMappings_without_Ebs_property(self): stack_name = 'without_Ebs' tmpl, stack = self._setup_test_stack(stack_name) diff --git a/heat/tests/test_properties.py b/heat/tests/test_properties.py index a92fa3b1f..616625a3b 100644 --- a/heat/tests/test_properties.py +++ b/heat/tests/test_properties.py @@ -703,6 +703,16 @@ class PropertyTest(testtools.TestCase): self.assertEqual("int() argument must be a string or a number, " "not 'list'", six.text_type(ex)) + def test_str_from_int(self): + schema = {'Type': 'String'} + p = properties.Property(schema) + self.assertEqual('3', p.get_value(3)) + + def test_str_from_bool(self): + schema = {'Type': 'String'} + p = properties.Property(schema) + self.assertEqual('True', p.get_value(True)) + def test_int_from_str_good(self): schema = {'Type': 'Integer'} p = properties.Property(schema) @@ -1514,16 +1524,25 @@ class PropertiesValidationTest(testtools.TestCase): props = properties.Properties(schema, {}) self.assertIsNone(props.validate()) - def test_bad_data(self): - schema = {'foo': {'Type': 'String'}} - props = properties.Properties(schema, {'foo': 42}) - self.assertRaises(exception.StackValidationFailed, props.validate) - def test_unknown_typo(self): schema = {'foo': {'Type': 'String'}} props = properties.Properties(schema, {'food': 42}) self.assertRaises(exception.StackValidationFailed, props.validate) + def test_list_instead_string(self): + schema = {'foo': {'Type': 'String'}} + props = properties.Properties(schema, {'foo': ['foo', 'bar']}) + ex = self.assertRaises(exception.StackValidationFailed, props.validate) + self.assertEqual('Property error : foo Value must be a string', + six.text_type(ex)) + + def test_dict_instead_string(self): + schema = {'foo': {'Type': 'String'}} + props = properties.Properties(schema, {'foo': {'foo': 'bar'}}) + ex = self.assertRaises(exception.StackValidationFailed, props.validate) + self.assertEqual('Property error : foo Value must be a string', + six.text_type(ex)) + def test_none_string(self): schema = {'foo': {'Type': 'String'}} props = properties.Properties(schema, {'foo': None}) |