1 # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 # not use this file except in compliance with the License. You may obtain
3 # a copy of the License at
5 # http://www.apache.org/licenses/LICENSE-2.0
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 # License for the specific language governing permissions and limitations
16 from toscaparser.common import exception
17 from toscaparser.elements.constraints import Constraint
18 from toscaparser.elements.constraints import Schema
19 from toscaparser.tests.base import TestCase
20 from toscaparser.utils.gettextutils import _
21 from toscaparser.utils import yamlparser
24 class ConstraintTest(TestCase):
26 def test_schema_dict(self):
30 description: Number of CPUs for the server.
32 schema = yamlparser.simple_parse(tpl_snippet)
33 cpus_schema = Schema('cpus', schema['cpus'])
34 self.assertEqual(len(cpus_schema), 2)
35 self.assertEqual('integer', cpus_schema.type)
36 self.assertEqual('Number of CPUs for the server.',
37 cpus_schema.description)
38 self.assertEqual(True, cpus_schema.required)
39 self.assertIsNone(cpus_schema.default)
41 def test_schema_not_dict(self):
45 - description: Number of CPUs for the server.
47 schema = yamlparser.simple_parse(tpl_snippet)
48 error = self.assertRaises(exception.InvalidSchemaError, Schema,
49 'cpus', schema['cpus'])
50 self.assertEqual(_('Schema definition of "cpus" must be a dict.'),
53 def test_schema_miss_type(self):
56 description: Number of CPUs for the server.
58 schema = yamlparser.simple_parse(tpl_snippet)
59 error = self.assertRaises(exception.InvalidSchemaError, Schema,
60 'cpus', schema['cpus'])
61 self.assertEqual(_('Schema definition of "cpus" must have a "type" '
62 'attribute.'), str(error))
64 def test_schema_none_description(self):
69 schema = yamlparser.simple_parse(tpl_snippet)
70 cpus_schema = Schema('cpus', schema['cpus'])
71 self.assertEqual('', cpus_schema.description)
73 def test_invalid_constraint_type(self):
74 schema = {'invalid_type': 2}
75 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
76 'prop', Schema.INTEGER,
78 self.assertEqual(_('Invalid property "invalid_type".'),
81 def test_invalid_prop_type(self):
82 schema = {'length': 5}
83 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
84 'prop', Schema.INTEGER,
86 self.assertEqual(_('Property "length" is not valid for data type '
87 '"integer".'), str(error))
89 def test_invalid_validvalues(self):
90 schema = {'valid_values': 2}
91 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
92 'prop', Schema.INTEGER,
94 self.assertEqual(_('The property "valid_values" expects a list.'),
97 def test_validvalues_validate(self):
98 schema = {'valid_values': [2, 4, 6, 8]}
99 constraint = Constraint('prop', Schema.INTEGER, schema)
100 self.assertIsNone(constraint.validate(4))
102 def test_validvalues_validate_fail(self):
103 schema = {'valid_values': [2, 4, 6, 8]}
104 constraint = Constraint('prop', Schema.INTEGER, schema)
105 error = self.assertRaises(exception.ValidationError,
106 constraint.validate, 5)
107 self.assertEqual(_('The value "5" of property "prop" is not valid. '
108 'Expected a value from "[2, 4, 6, 8]".'),
111 def test_invalid_in_range(self):
112 snippet = 'in_range: {2, 6}'
113 schema = yaml.load(snippet)
114 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
115 'prop', Schema.INTEGER,
117 self.assertEqual(_('The property "in_range" expects a list.'),
120 def test_in_range_min_max(self):
121 schema = {'in_range': [2, 6]}
122 constraint = Constraint('prop', Schema.INTEGER, schema)
123 self.assertEqual(2, constraint.min)
124 self.assertEqual(6, constraint.max)
126 def test_in_range_validate(self):
127 schema = {'in_range': [2, 6]}
128 constraint = Constraint('prop', Schema.INTEGER, schema)
129 self.assertIsNone(constraint.validate(2))
130 self.assertIsNone(constraint.validate(4))
131 self.assertIsNone(constraint.validate(6))
133 def test_in_range_validate_fail(self):
134 schema = {'in_range': [2, 6]}
135 constraint = Constraint('prop', Schema.INTEGER, schema)
136 error = self.assertRaises(exception.ValidationError,
137 constraint.validate, 8)
138 self.assertEqual(_('The value "8" of property "prop" is out of range '
139 '"(min:2, max:6)".'), str(error))
141 def test_equal_validate(self):
142 schema = {'equal': 4}
143 constraint = Constraint('prop', Schema.INTEGER, schema)
144 self.assertIsNone(constraint.validate(4))
146 def test_equal_validate_fail(self):
147 schema = {'equal': 4}
148 constraint = Constraint('prop', Schema.INTEGER, schema)
149 error = self.assertRaises(exception.ValidationError,
150 constraint.validate, 8)
151 self.assertEqual('The value "8" of property "prop" is not equal to '
154 def test_greater_than_validate(self):
155 schema = {'greater_than': 4}
156 constraint = Constraint('prop', Schema.INTEGER, schema)
157 self.assertIsNone(constraint.validate(6))
159 def test_greater_than_validate_fail(self):
160 schema = {'greater_than': 4}
161 constraint = Constraint('prop', Schema.INTEGER, schema)
162 error = self.assertRaises(exception.ValidationError,
163 constraint.validate, 3)
164 self.assertEqual(_('The value "3" of property "prop" must be greater '
165 'than "4".'), str(error))
167 error = self.assertRaises(exception.ValidationError,
168 constraint.validate, 4)
169 self.assertEqual(_('The value "4" of property "prop" must be greater '
170 'than "4".'), str(error))
172 def test_greater_than_invalid(self):
173 snippet = 'greater_than: {4}'
174 schema = yaml.load(snippet)
175 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
176 'prop', Schema.INTEGER,
178 self.assertEqual(_('The property "greater_than" expects comparable '
179 'values.'), str(error))
181 def test_greater_or_equal_validate(self):
182 schema = {'greater_or_equal': 3.9}
183 constraint = Constraint('prop', Schema.FLOAT, schema)
184 self.assertIsNone(constraint.validate(3.9))
185 self.assertIsNone(constraint.validate(4.0))
187 def test_greater_or_equal_validate_fail(self):
188 schema = {'greater_or_equal': 3.9}
189 constraint = Constraint('prop', Schema.FLOAT, schema)
190 error = self.assertRaises(exception.ValidationError,
191 constraint.validate, 3.0)
192 self.assertEqual(_('The value "3.0" of property "prop" must be '
193 'greater than or equal to "3.9".'),
196 error = self.assertRaises(exception.ValidationError,
197 constraint.validate, 3.8)
198 self.assertEqual(_('The value "3.8" of property "prop" must be '
199 'greater than or equal to "3.9".'),
202 def test_greater_or_equal_invalid(self):
203 snippet = 'greater_or_equal: {3.9}'
204 schema = yaml.load(snippet)
205 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
206 'prop', Schema.INTEGER,
208 self.assertEqual(_('The property "greater_or_equal" expects '
209 'comparable values.'), str(error))
211 def test_less_than_validate(self):
212 schema = {'less_than': datetime.date(2014, 0o7, 25)}
213 constraint = Constraint('prop', Schema.TIMESTAMP, schema)
214 self.assertIsNone(constraint.validate(datetime.date(2014, 0o7, 20)))
215 self.assertIsNone(constraint.validate(datetime.date(2014, 0o7, 24)))
217 def test_less_than_validate_fail(self):
218 schema = {'less_than': datetime.date(2014, 0o7, 25)}
219 constraint = Constraint('prop', Schema.TIMESTAMP, schema)
220 error = self.assertRaises(exception.ValidationError,
222 datetime.date(2014, 0o7, 25))
223 self.assertEqual(_('The value "2014-07-25" of property "prop" must be '
224 'less than "2014-07-25".'),
227 error = self.assertRaises(exception.ValidationError,
229 datetime.date(2014, 0o7, 27))
230 self.assertEqual(_('The value "2014-07-27" of property "prop" must be '
231 'less than "2014-07-25".'),
234 def test_less_than_invalid(self):
235 snippet = 'less_than: {3.9}'
236 schema = yaml.load(snippet)
237 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
238 'prop', Schema.INTEGER,
240 self.assertEqual(_('The property "less_than" expects comparable '
241 'values.'), str(error))
243 def test_less_or_equal_validate(self):
244 schema = {'less_or_equal': 4}
245 constraint = Constraint('prop', Schema.INTEGER, schema)
246 self.assertIsNone(constraint.validate(4))
247 self.assertIsNone(constraint.validate(3))
249 def test_less_or_equal_validate_fail(self):
250 schema = {'less_or_equal': 4}
251 constraint = Constraint('prop', Schema.INTEGER, schema)
252 error = self.assertRaises(exception.ValidationError,
253 constraint.validate, 5)
254 self.assertEqual(_('The value "5" of property "prop" must be less '
255 'than or equal to "4".'), str(error))
257 def test_less_or_equal_invalid(self):
258 snippet = 'less_or_equal: {3.9}'
259 schema = yaml.load(snippet)
260 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
261 'prop', Schema.INTEGER,
263 self.assertEqual(_('The property "less_or_equal" expects comparable '
264 'values.'), str(error))
266 def test_invalid_length(self):
267 schema = {'length': 'four'}
268 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
269 'prop', Schema.STRING,
271 self.assertEqual(_('The property "length" expects an integer.'),
274 schema = {'length': 4.5}
275 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
276 'prop', Schema.STRING,
278 self.assertEqual(_('The property "length" expects an integer.'),
281 def test_length_validate(self):
282 schema = {'length': 4}
283 constraint = Constraint('prop', Schema.STRING, schema)
284 self.assertIsNone(constraint.validate('abcd'))
286 def test_length_validate_fail(self):
287 schema = {'length': 4}
288 constraint = Constraint('prop', Schema.STRING, schema)
289 error = self.assertRaises(exception.ValidationError,
290 constraint.validate, 'abc')
291 self.assertEqual(_('Length of value "abc" of property "prop" must '
292 'be equal to "4".'), str(error))
294 error = self.assertRaises(exception.ValidationError,
297 self.assertEqual(_('Length of value "abcde" of property "prop" must '
298 'be equal to "4".'), str(error))
300 def test_invalid_min_length(self):
301 schema = {'min_length': 'four'}
302 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
303 'prop', Schema.STRING,
305 self.assertEqual(_('The property "min_length" expects an integer.'),
308 def test_min_length_validate(self):
309 schema = {'min_length': 4}
310 constraint = Constraint('prop', Schema.STRING, schema)
311 self.assertIsNone(constraint.validate('abcd'))
312 self.assertIsNone(constraint.validate('abcde'))
314 def test_min_length_validate_fail(self):
315 schema = {'min_length': 4}
316 constraint = Constraint('prop', Schema.STRING, schema)
317 error = self.assertRaises(exception.ValidationError,
318 constraint.validate, 'abc')
319 self.assertEqual(_('Length of value "abc" of property "prop" must '
320 'be at least "4".'), str(error))
322 def test_invalid_max_length(self):
323 schema = {'max_length': 'four'}
324 error = self.assertRaises(exception.InvalidSchemaError, Constraint,
325 'prop', Schema.STRING,
327 self.assertEqual(_('The property "max_length" expects an integer.'),
330 def test_max_length_validate(self):
331 schema = {'max_length': 4}
332 constraint = Constraint('prop', Schema.STRING, schema)
333 self.assertIsNone(constraint.validate('abcd'))
334 self.assertIsNone(constraint.validate('abc'))
336 def test_max_length_validate_fail(self):
337 schema = {'max_length': 4}
338 constraint = Constraint('prop', Schema.STRING, schema)
339 error = self.assertRaises(exception.ValidationError,
342 self.assertEqual(_('Length of value "abcde" of property "prop" '
343 'must be no greater than "4".'),
346 def test_pattern_validate(self):
347 schema = {'pattern': '[0-9]*'}
348 constraint = Constraint('prop', Schema.STRING, schema)
349 self.assertIsNone(constraint.validate('123'))
351 def test_pattern_validate_fail(self):
352 schema = {'pattern': '[0-9]*'}
353 constraint = Constraint('prop', Schema.STRING, schema)
354 error = self.assertRaises(exception.ValidationError,
355 constraint.validate, 'abc')
356 self.assertEqual(_('The value "abc" of property "prop" does not '
357 'match pattern "[0-9]*".'), str(error))
359 def test_min_length_with_map(self):
360 schema = {'min_length': 1}
361 constraint = Constraint('prop', Schema.MAP, schema)
363 constraint.validate({"k": "v"})
364 except Exception as ex:
367 def test_max_length_with_map(self):
368 schema = {'max_length': 1}
369 constraint = Constraint('prop', Schema.MAP, schema)
371 constraint.validate({"k": "v"})
372 except Exception as ex: