Raise and catch a specific error during validation

This changes stack creation to return an error message instead of an
exception when (some) validation fails. It doesn't convert all validation
errors to keep the patch at a reasonable size.

Change-Id: I6364bccacbc1d447a99ea61565c96fcc90bd21f9
Partial-Bug: #1276623
This commit is contained in:
Thomas Herve 2014-02-05 15:38:50 +01:00
parent f18bb8b5af
commit 573a15a7e1
6 changed files with 63 additions and 42 deletions

View File

@ -18,6 +18,8 @@ import re
from heat.engine import resources
from heat.common import exception
class InvalidSchemaError(Exception):
pass
@ -144,8 +146,11 @@ class Schema(collections.Mapping):
return float(value)
def validate_constraints(self, value, context=None):
for constraint in self.constraints:
constraint.validate(value, context)
try:
for constraint in self.constraints:
constraint.validate(value, context)
except ValueError as ex:
raise exception.StackValidationFailed(message=str(ex))
def __getitem__(self, key):
if key == self.TYPE:

View File

@ -79,7 +79,8 @@ class Schema(constr.Schema):
'string: %s') % str(err))
try:
self.validate_constraints(default_value)
except (ValueError, TypeError) as exc:
except (ValueError, TypeError,
exception.StackValidationFailed) as exc:
raise constr.InvalidSchemaError(_('Invalid default '
'%(default)s (%(exc)s)') %
dict(default=self.default,

View File

@ -936,19 +936,19 @@ class HOTParamValidatorTest(HeatTestCase):
return True
value = 'wp'
err = self.assertRaises(ValueError, v, value)
err = self.assertRaises(exception.StackValidationFailed, v, value)
self.assertIn(len_desc, str(err))
value = 'abcdefghijklmnopq'
err = self.assertRaises(ValueError, v, value)
err = self.assertRaises(exception.StackValidationFailed, v, value)
self.assertIn(len_desc, str(err))
value = 'abcdefgh1'
err = self.assertRaises(ValueError, v, value)
err = self.assertRaises(exception.StackValidationFailed, v, value)
self.assertIn(pattern_desc1, str(err))
value = 'Abcdefghi'
err = self.assertRaises(ValueError, v, value)
err = self.assertRaises(exception.StackValidationFailed, v, value)
self.assertIn(pattern_desc2, str(err))
value = 'abcdefghi'
@ -985,19 +985,23 @@ class HOTParamValidatorTest(HeatTestCase):
return True
value = 'wp'
err = self.assertRaises(ValueError, run_parameters, value)
err = self.assertRaises(exception.StackValidationFailed,
run_parameters, value)
self.assertIn(len_desc, str(err))
value = 'abcdefghijklmnopq'
err = self.assertRaises(ValueError, run_parameters, value)
err = self.assertRaises(exception.StackValidationFailed,
run_parameters, value)
self.assertIn(len_desc, str(err))
value = 'abcdefgh1'
err = self.assertRaises(ValueError, run_parameters, value)
err = self.assertRaises(exception.StackValidationFailed,
run_parameters, value)
self.assertIn(pattern_desc1, str(err))
value = 'Abcdefghi'
err = self.assertRaises(ValueError, run_parameters, value)
err = self.assertRaises(exception.StackValidationFailed,
run_parameters, value)
self.assertIn(pattern_desc2, str(err))
value = 'abcdefghi'
@ -1025,11 +1029,11 @@ class HOTParamValidatorTest(HeatTestCase):
return True
value = 29999
err = self.assertRaises(ValueError, v, value)
err = self.assertRaises(exception.StackValidationFailed, v, value)
self.assertIn(range_desc, str(err))
value = 50001
err = self.assertRaises(ValueError, v, value)
err = self.assertRaises(exception.StackValidationFailed, v, value)
self.assertIn(range_desc, str(err))
value = 30000
@ -1066,11 +1070,11 @@ class HOTParamValidatorTest(HeatTestCase):
return True
value = "1"
err = self.assertRaises(ValueError, v, value)
err = self.assertRaises(exception.StackValidationFailed, v, value)
self.assertEqual(desc, str(err))
value = "2"
err = self.assertRaises(ValueError, v, value)
err = self.assertRaises(exception.StackValidationFailed, v, value)
self.assertEqual(desc, str(err))
value = "0"

View File

@ -123,7 +123,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'String',
'ConstraintDescription': 'wibble',
'MinLength': '4'}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, 'foo')
self.assertIn('wibble', str(err))
@ -131,7 +131,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'String',
'ConstraintDescription': 'wibble',
'MaxLength': '2'}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, 'foo')
self.assertIn('wibble', str(err))
@ -145,7 +145,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'String',
'ConstraintDescription': 'wibble',
'AllowedPattern': '[a-z]*'}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, '1foo')
self.assertIn('wibble', str(err))
@ -153,7 +153,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'String',
'ConstraintDescription': 'wibble',
'AllowedPattern': '[a-z]*'}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, 'foo1')
self.assertIn('wibble', str(err))
@ -167,7 +167,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'String',
'ConstraintDescription': 'wibble',
'AllowedValues': ['foo', 'bar', 'baz']}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, 'blarg')
self.assertIn('wibble', str(err))
@ -189,7 +189,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'Number',
'ConstraintDescription': 'wibble',
'MinValue': '4'}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, '3')
self.assertIn('wibble', str(err))
@ -197,7 +197,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'Number',
'ConstraintDescription': 'wibble',
'MaxValue': '2'}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, '3')
self.assertIn('wibble', str(err))
@ -211,7 +211,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'Number',
'ConstraintDescription': 'wibble',
'AllowedValues': ['1', '3', '5']}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, '2')
self.assertIn('wibble', str(err))
@ -231,8 +231,9 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'CommaDelimitedList',
'ConstraintDescription': 'wibble',
'AllowedValues': ['foo', 'bar', 'baz']}
err = self.assertRaises(ValueError, self.new_parameter,
'p', schema, 'foo,baz,blarg')
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema,
'foo,baz,blarg')
self.assertIn('wibble', str(err))
def test_map_value(self):
@ -275,7 +276,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'Json',
'MinLength': 3}
val = {"foo": "bar", "items": [1, 2, 3]}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, val)
self.assertIn('out of range', str(err))
@ -284,7 +285,7 @@ class ParameterTest(testtools.TestCase):
schema = {'Type': 'Json',
'MaxLength': 1}
val = {"foo": "bar", "items": [1, 2, 3]}
err = self.assertRaises(ValueError,
err = self.assertRaises(exception.StackValidationFailed,
self.new_parameter, 'p', schema, val)
self.assertIn('out of range', str(err))

View File

@ -622,13 +622,15 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'String',
'AllowedPattern': '[a-z]*'}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, '1foo')
self.assertRaises(exception.StackValidationFailed,
p.validate_data, '1foo')
def test_string_pattern_bad_suffix(self):
schema = {'Type': 'String',
'AllowedPattern': '[a-z]*'}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, 'foo1')
self.assertRaises(exception.StackValidationFailed,
p.validate_data, 'foo1')
def test_string_value_list_good(self):
schema = {'Type': 'String',
@ -640,7 +642,8 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'String',
'AllowedValues': ['foo', 'bar', 'baz']}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, 'blarg')
self.assertRaises(exception.StackValidationFailed,
p.validate_data, 'blarg')
def test_string_maxlength_good(self):
schema = {'Type': 'String',
@ -652,7 +655,8 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'String',
'MaxLength': '5'}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, 'abcdef')
self.assertRaises(exception.StackValidationFailed,
p.validate_data, 'abcdef')
def test_string_length_in_range(self):
schema = {'Type': 'String',
@ -671,7 +675,8 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'String',
'MinLength': '5'}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, 'abcd')
self.assertRaises(exception.StackValidationFailed,
p.validate_data, 'abcd')
def test_int_good(self):
schema = {'Type': 'Integer',
@ -702,13 +707,13 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'Integer',
'MinValue': 4}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, 3)
self.assertRaises(exception.StackValidationFailed, p.validate_data, 3)
def test_integer_high(self):
schema = {'Type': 'Integer',
'MaxValue': 2}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, 3)
self.assertRaises(exception.StackValidationFailed, p.validate_data, 3)
def test_integer_value_list_good(self):
schema = {'Type': 'Integer',
@ -720,7 +725,7 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'Integer',
'AllowedValues': [1, 3, 5]}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, 2)
self.assertRaises(exception.StackValidationFailed, p.validate_data, 2)
def test_number_good(self):
schema = {'Type': 'Number',
@ -747,19 +752,22 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'Number',
'AllowedValues': ['1', '3', '5']}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, '2')
self.assertRaises(exception.StackValidationFailed,
p.validate_data, '2')
def test_number_low(self):
schema = {'Type': 'Number',
'MinValue': '4'}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, '3')
self.assertRaises(exception.StackValidationFailed,
p.validate_data, '3')
def test_number_high(self):
schema = {'Type': 'Number',
'MaxValue': '2'}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, '3')
self.assertRaises(exception.StackValidationFailed,
p.validate_data, '3')
def test_boolean_true(self):
p = properties.Property({'Type': 'Boolean'})
@ -799,7 +807,8 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'List',
'MaxLength': '2'}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, ['1', '2', '3'])
self.assertRaises(exception.StackValidationFailed,
p.validate_data, ['1', '2', '3'])
def test_list_length_in_range(self):
schema = {'Type': 'List',
@ -818,7 +827,8 @@ class PropertyTest(testtools.TestCase):
schema = {'Type': 'List',
'MinLength': '4'}
p = properties.Property(schema)
self.assertRaises(ValueError, p.validate_data, ['1', '2', '3'])
self.assertRaises(exception.StackValidationFailed,
p.validate_data, ['1', '2', '3'])
def test_map_string(self):
p = properties.Property({'Type': 'Map'})

View File

@ -1099,7 +1099,7 @@ class validateTest(HeatTestCase):
name='image_name')]
self.m.StubOutWithMock(self.fc.images, 'list')
self.fc.images.list().AndReturn(image_list)
self.fc.images.list().MultipleTimes().AndReturn(image_list)
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)
@ -1121,7 +1121,7 @@ class validateTest(HeatTestCase):
name='image_name')]
self.m.StubOutWithMock(self.fc.images, 'list')
self.fc.images.list().AndReturn(image_list)
self.fc.images.list().MultipleTimes().AndReturn(image_list)
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)