Add transaction subsystem definition in the use case of
[parser.git] / tosca2heat / tosca-parser / toscaparser / tests / test_constraints.py
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
4 #
5 #         http://www.apache.org/licenses/LICENSE-2.0
6 #
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
11 #    under the License.
12
13 import datetime
14 import yaml
15
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
22
23
24 class ConstraintTest(TestCase):
25
26     def test_schema_dict(self):
27         tpl_snippet = '''
28         cpus:
29           type: integer
30           description: Number of CPUs for the server.
31         '''
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)
40
41     def test_schema_not_dict(self):
42         tpl_snippet = '''
43         cpus:
44           - type: integer
45           - description: Number of CPUs for the server.
46         '''
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.'),
51                          str(error))
52
53     def test_schema_miss_type(self):
54         tpl_snippet = '''
55         cpus:
56           description: Number of CPUs for the server.
57         '''
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))
63
64     def test_schema_none_description(self):
65         tpl_snippet = '''
66         cpus:
67           type: integer
68         '''
69         schema = yamlparser.simple_parse(tpl_snippet)
70         cpus_schema = Schema('cpus', schema['cpus'])
71         self.assertEqual('', cpus_schema.description)
72
73     def test_invalid_constraint_type(self):
74         schema = {'invalid_type': 2}
75         error = self.assertRaises(exception.InvalidSchemaError, Constraint,
76                                   'prop', Schema.INTEGER,
77                                   schema)
78         self.assertEqual(_('Invalid property "invalid_type".'),
79                          str(error))
80
81     def test_invalid_prop_type(self):
82         schema = {'length': 5}
83         error = self.assertRaises(exception.InvalidSchemaError, Constraint,
84                                   'prop', Schema.INTEGER,
85                                   schema)
86         self.assertEqual(_('Property "length" is not valid for data type '
87                            '"integer".'), str(error))
88
89     def test_invalid_validvalues(self):
90         schema = {'valid_values': 2}
91         error = self.assertRaises(exception.InvalidSchemaError, Constraint,
92                                   'prop', Schema.INTEGER,
93                                   schema)
94         self.assertEqual(_('The property "valid_values" expects a list.'),
95                          str(error))
96
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))
101
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]".'),
109                          str(error))
110
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,
116                                   schema)
117         self.assertEqual(_('The property "in_range" expects a list.'),
118                          str(error))
119
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)
125
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))
132
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))
140
141     def test_equal_validate(self):
142         schema = {'equal': 4}
143         constraint = Constraint('prop', Schema.INTEGER, schema)
144         self.assertIsNone(constraint.validate(4))
145
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 '
152                          '"4".', str(error))
153
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))
158
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))
166
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))
171
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,
177                                   schema)
178         self.assertEqual(_('The property "greater_than" expects comparable '
179                            'values.'), str(error))
180
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))
186
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".'),
194                          str(error))
195
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".'),
200                          str(error))
201
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,
207                                   schema)
208         self.assertEqual(_('The property "greater_or_equal" expects '
209                            'comparable values.'), str(error))
210
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)))
216
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,
221                                   constraint.validate,
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".'),
225                          str(error))
226
227         error = self.assertRaises(exception.ValidationError,
228                                   constraint.validate,
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".'),
232                          str(error))
233
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,
239                                   schema)
240         self.assertEqual(_('The property "less_than" expects comparable '
241                            'values.'), str(error))
242
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))
248
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))
256
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,
262                                   schema)
263         self.assertEqual(_('The property "less_or_equal" expects comparable '
264                            'values.'), str(error))
265
266     def test_invalid_length(self):
267         schema = {'length': 'four'}
268         error = self.assertRaises(exception.InvalidSchemaError, Constraint,
269                                   'prop', Schema.STRING,
270                                   schema)
271         self.assertEqual(_('The property "length" expects an integer.'),
272                          str(error))
273
274         schema = {'length': 4.5}
275         error = self.assertRaises(exception.InvalidSchemaError, Constraint,
276                                   'prop', Schema.STRING,
277                                   schema)
278         self.assertEqual(_('The property "length" expects an integer.'),
279                          str(error))
280
281     def test_length_validate(self):
282         schema = {'length': 4}
283         constraint = Constraint('prop', Schema.STRING, schema)
284         self.assertIsNone(constraint.validate('abcd'))
285
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))
293
294         error = self.assertRaises(exception.ValidationError,
295                                   constraint.validate,
296                                   'abcde')
297         self.assertEqual(_('Length of value "abcde" of property "prop" must '
298                            'be equal to "4".'), str(error))
299
300     def test_invalid_min_length(self):
301         schema = {'min_length': 'four'}
302         error = self.assertRaises(exception.InvalidSchemaError, Constraint,
303                                   'prop', Schema.STRING,
304                                   schema)
305         self.assertEqual(_('The property "min_length" expects an integer.'),
306                          str(error))
307
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'))
313
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))
321
322     def test_invalid_max_length(self):
323         schema = {'max_length': 'four'}
324         error = self.assertRaises(exception.InvalidSchemaError, Constraint,
325                                   'prop', Schema.STRING,
326                                   schema)
327         self.assertEqual(_('The property "max_length" expects an integer.'),
328                          str(error))
329
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'))
335
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,
340                                   constraint.validate,
341                                   'abcde')
342         self.assertEqual(_('Length of value "abcde" of property "prop" '
343                            'must be no greater than "4".'),
344                          str(error))
345
346     def test_pattern_validate(self):
347         schema = {'pattern': '[0-9]*'}
348         constraint = Constraint('prop', Schema.STRING, schema)
349         self.assertIsNone(constraint.validate('123'))
350
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))
358
359     def test_min_length_with_map(self):
360         schema = {'min_length': 1}
361         constraint = Constraint('prop', Schema.MAP, schema)
362         try:
363             constraint.validate({"k": "v"})
364         except Exception as ex:
365             self.fail(ex)
366
367     def test_max_length_with_map(self):
368         schema = {'max_length': 1}
369         constraint = Constraint('prop', Schema.MAP, schema)
370         try:
371             constraint.validate({"k": "v"})
372         except Exception as ex:
373             self.fail(ex)