Allow paths as lists in function.validate()
Previously when calling function.validate() we passed the path to the function in the template (used for debugging purposes) as a string. This change allows us to pass it as a list of path components, as we do elsewhere, so that higher-level code that catches StackValidationFailed can deal with its components separately. Change-Id: I017aa6f7511b8478ef8273522ab8087684ae71c6
This commit is contained in:
parent
38f1975cf7
commit
cb80df4f4a
|
@ -267,29 +267,30 @@ def resolve(snippet):
|
|||
return snippet
|
||||
|
||||
|
||||
def validate(snippet, path=''):
|
||||
def validate(snippet, path=None):
|
||||
if path is None:
|
||||
path = []
|
||||
elif isinstance(path, six.string_types):
|
||||
path = [path]
|
||||
|
||||
if isinstance(snippet, Function):
|
||||
try:
|
||||
snippet.validate()
|
||||
except AssertionError:
|
||||
raise
|
||||
except Exception as e:
|
||||
path = '.'.join([path, snippet.fn_name])
|
||||
raise exception.StackValidationFailed(
|
||||
path=path, message=six.text_type(e))
|
||||
path=path + [snippet.fn_name],
|
||||
message=six.text_type(e))
|
||||
elif isinstance(snippet, collections.Mapping):
|
||||
def mkpath(key):
|
||||
return '.'.join([path, key])
|
||||
|
||||
for k, v in six.iteritems(snippet):
|
||||
validate(v, mkpath(k))
|
||||
validate(v, path + [k])
|
||||
elif (not isinstance(snippet, six.string_types) and
|
||||
isinstance(snippet, collections.Iterable)):
|
||||
def mkpath(indx):
|
||||
return '.'.join([path, '[%d]' % indx])
|
||||
|
||||
basepath = list(path)
|
||||
parent = basepath.pop() if basepath else ''
|
||||
for i, v in enumerate(snippet):
|
||||
validate(v, mkpath(i))
|
||||
validate(v, basepath + ['%s[%d]' % (parent, i)])
|
||||
|
||||
|
||||
def dependencies(snippet, path=''):
|
||||
|
|
|
@ -180,7 +180,7 @@ class ValidateTest(common.HeatTestCase):
|
|||
self.assertIsNone(function.validate(self.func))
|
||||
self.func = TestFunction(None, 'foo', ['bar'])
|
||||
self.assertRaisesRegex(exception.StackValidationFailed,
|
||||
'.foo: Need more arguments',
|
||||
'foo: Need more arguments',
|
||||
function.validate, self.func)
|
||||
|
||||
def test_validate_dict(self):
|
||||
|
@ -190,7 +190,7 @@ class ValidateTest(common.HeatTestCase):
|
|||
self.func = TestFunction(None, 'foo', ['bar'])
|
||||
snippet = {'foo': 'bar', 'blarg': self.func}
|
||||
self.assertRaisesRegex(exception.StackValidationFailed,
|
||||
'.blarg.foo: Need more arguments',
|
||||
'blarg.foo: Need more arguments',
|
||||
function.validate, snippet)
|
||||
|
||||
def test_validate_list(self):
|
||||
|
@ -200,7 +200,7 @@ class ValidateTest(common.HeatTestCase):
|
|||
self.func = TestFunction(None, 'foo', ['bar'])
|
||||
snippet = {'foo': 'bar', 'blarg': self.func}
|
||||
self.assertRaisesRegex(exception.StackValidationFailed,
|
||||
'.blarg.foo: Need more arguments',
|
||||
'blarg.foo: Need more arguments',
|
||||
function.validate, snippet)
|
||||
|
||||
def test_validate_all(self):
|
||||
|
@ -210,7 +210,7 @@ class ValidateTest(common.HeatTestCase):
|
|||
self.func = TestFunction(None, 'foo', ['bar'])
|
||||
snippet = {'foo': 'bar', 'blarg': self.func}
|
||||
self.assertRaisesRegex(exception.StackValidationFailed,
|
||||
'.blarg.foo: Need more arguments',
|
||||
'blarg.foo: Need more arguments',
|
||||
function.validate, snippet)
|
||||
|
||||
|
||||
|
|
|
@ -864,7 +864,7 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
|
||||
ex = self.assertRaises(exception.StackValidationFailed,
|
||||
self.resolve, snippet, tmpl)
|
||||
self.assertIn('.str_replace: "str_replace" parameters must be a'
|
||||
self.assertIn('str_replace: "str_replace" parameters must be a'
|
||||
' mapping', six.text_type(ex))
|
||||
|
||||
def test_str_replace_invalid_param_type_init(self):
|
||||
|
@ -1027,13 +1027,13 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
l_tmpl = template.Template(hot_liberty_tpl_empty)
|
||||
exc = self.assertRaises(exception.StackValidationFailed,
|
||||
self.resolve, snippet, l_tmpl)
|
||||
self.assertIn('.list_join: Incorrect arguments to "list_join"',
|
||||
self.assertIn('list_join: Incorrect arguments to "list_join"',
|
||||
six.text_type(exc))
|
||||
|
||||
k_tmpl = template.Template(hot_kilo_tpl_empty)
|
||||
exc1 = self.assertRaises(exception.StackValidationFailed,
|
||||
self.resolve, snippet, k_tmpl)
|
||||
self.assertIn('.list_join: Incorrect arguments to "list_join"',
|
||||
self.assertIn('list_join: Incorrect arguments to "list_join"',
|
||||
six.text_type(exc1))
|
||||
|
||||
def test_join_int_invalid(self):
|
||||
|
@ -1041,25 +1041,25 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
l_tmpl = template.Template(hot_liberty_tpl_empty)
|
||||
exc = self.assertRaises(exception.StackValidationFailed,
|
||||
self.resolve, snippet, l_tmpl)
|
||||
self.assertIn('.list_join: Incorrect arguments', six.text_type(exc))
|
||||
self.assertIn('list_join: Incorrect arguments', six.text_type(exc))
|
||||
|
||||
k_tmpl = template.Template(hot_kilo_tpl_empty)
|
||||
exc1 = self.assertRaises(exception.StackValidationFailed,
|
||||
self.resolve, snippet, k_tmpl)
|
||||
self.assertIn('.list_join: Incorrect arguments', six.text_type(exc1))
|
||||
self.assertIn('list_join: Incorrect arguments', six.text_type(exc1))
|
||||
|
||||
def test_join_invalid_value(self):
|
||||
snippet = {'list_join': [',']}
|
||||
l_tmpl = template.Template(hot_liberty_tpl_empty)
|
||||
exc = self.assertRaises(exception.StackValidationFailed,
|
||||
self.resolve, snippet, l_tmpl)
|
||||
self.assertIn('.list_join: Incorrect arguments to "list_join"',
|
||||
self.assertIn('list_join: Incorrect arguments to "list_join"',
|
||||
six.text_type(exc))
|
||||
|
||||
k_tmpl = template.Template(hot_kilo_tpl_empty)
|
||||
exc1 = self.assertRaises(exception.StackValidationFailed,
|
||||
self.resolve, snippet, k_tmpl)
|
||||
self.assertIn('.list_join: Incorrect arguments to "list_join"',
|
||||
self.assertIn('list_join: Incorrect arguments to "list_join"',
|
||||
six.text_type(exc1))
|
||||
|
||||
def test_join_invalid_multiple(self):
|
||||
|
@ -1269,7 +1269,7 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
def test_yaql_non_map_args(self):
|
||||
snippet = {'yaql': 'invalid'}
|
||||
tmpl = template.Template(hot_newton_tpl_empty)
|
||||
msg = '.yaql: Arguments to "yaql" must be a map.'
|
||||
msg = 'yaql: Arguments to "yaql" must be a map.'
|
||||
self.assertRaisesRegex(exception.StackValidationFailed,
|
||||
msg, self.resolve, snippet, tmpl)
|
||||
|
||||
|
@ -1278,7 +1278,7 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
'data': {'var1': [1, 2, 3, 4]}}}
|
||||
tmpl = template.Template(hot_newton_tpl_empty)
|
||||
yaql = tmpl.parse(None, snippet)
|
||||
regxp = ('.yaql: Bad expression Parse error: unexpected end '
|
||||
regxp = ('yaql: Bad expression Parse error: unexpected end '
|
||||
'of statement.')
|
||||
self.assertRaisesRegex(exception.StackValidationFailed, regxp,
|
||||
function.validate, yaql)
|
||||
|
@ -1363,7 +1363,7 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
exc = self.assertRaises(exception.StackValidationFailed,
|
||||
self.resolve_condition, snippet, tmpl)
|
||||
|
||||
error_msg = ('.equals: Arguments to "equals" must be '
|
||||
error_msg = ('equals: Arguments to "equals" must be '
|
||||
'of the form: [value_1, value_2]')
|
||||
self.assertIn(error_msg, six.text_type(exc))
|
||||
|
||||
|
@ -1715,7 +1715,7 @@ resources:
|
|||
snippet = {'repeat': {'template': 'this is %var%',
|
||||
'for_each': '%var%'}}
|
||||
repeat = tmpl.parse(None, snippet)
|
||||
regxp = ('.repeat: The "for_each" argument to "repeat" '
|
||||
regxp = ('repeat: The "for_each" argument to "repeat" '
|
||||
'must contain a map')
|
||||
self.assertRaisesRegex(exception.StackValidationFailed, regxp,
|
||||
function.validate, repeat)
|
||||
|
@ -1968,7 +1968,7 @@ resources:
|
|||
snippet = {'Fn::GetAZs': ''}
|
||||
stack = parser.Stack(utils.dummy_context(), 'test_stack',
|
||||
template.Template(hot_juno_tpl_empty))
|
||||
regxp = '.Fn::GetAZs: The template version is invalid'
|
||||
regxp = 'Fn::GetAZs: The template version is invalid'
|
||||
self.assertRaisesRegex(exception.StackValidationFailed,
|
||||
regxp,
|
||||
function.validate,
|
||||
|
|
Loading…
Reference in New Issue