Update the upstream of tosco-parser and heat-translator to stable
[parser.git] / tosca2heat / tosca-parser / toscaparser / tests / test_toscatplvalidation.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 os
14 import six
15
16 from toscaparser.common import exception
17 from toscaparser.imports import ImportsLoader
18 from toscaparser.nodetemplate import NodeTemplate
19 from toscaparser.parameters import Input
20 from toscaparser.parameters import Output
21 from toscaparser.policy import Policy
22 from toscaparser.relationship_template import RelationshipTemplate
23 from toscaparser.repositories import Repository
24 from toscaparser.tests.base import TestCase
25 from toscaparser.topology_template import TopologyTemplate
26 from toscaparser.tosca_template import ToscaTemplate
27 from toscaparser.triggers import Triggers
28 from toscaparser.utils.gettextutils import _
29 import toscaparser.utils.yamlparser
30
31
32 class ToscaTemplateValidationTest(TestCase):
33
34     def test_well_defined_template(self):
35         tpl_path = os.path.join(
36             os.path.dirname(os.path.abspath(__file__)),
37             "data/tosca_single_instance_wordpress.yaml")
38         self.assertIsNotNone(ToscaTemplate(tpl_path))
39
40     def test_first_level_sections(self):
41         tpl_path = os.path.join(
42             os.path.dirname(os.path.abspath(__file__)),
43             "data/test_tosca_top_level_error1.yaml")
44         self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
45         exception.ExceptionCollector.assertExceptionMessage(
46             exception.MissingRequiredFieldError,
47             _('Template is missing required field '
48               '"tosca_definitions_version".'))
49
50         tpl_path = os.path.join(
51             os.path.dirname(os.path.abspath(__file__)),
52             "data/test_tosca_top_level_error2.yaml")
53         self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
54         exception.ExceptionCollector.assertExceptionMessage(
55             exception.UnknownFieldError,
56             _('Template contains unknown field "node_template". Refer to the '
57               'definition to verify valid values.'))
58
59     def test_template_with_imports_validation(self):
60         tpl_path = os.path.join(
61             os.path.dirname(os.path.abspath(__file__)),
62             "data/tosca_imports_validation.yaml")
63         self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
64         exception.ExceptionCollector.assertExceptionMessage(
65             exception.UnknownFieldError,
66             _('Template custom_types/imported_sample.yaml contains unknown '
67               'field "descriptions". Refer to the definition'
68               ' to verify valid values.'))
69         exception.ExceptionCollector.assertExceptionMessage(
70             exception.UnknownFieldError,
71             _('Template custom_types/imported_sample.yaml contains unknown '
72               'field "node_typess". Refer to the definition to '
73               'verify valid values.'))
74         exception.ExceptionCollector.assertExceptionMessage(
75             exception.UnknownFieldError,
76             _('Template custom_types/imported_sample.yaml contains unknown '
77               'field "tosca1_definitions_version". Refer to the definition'
78               ' to verify valid values.'))
79         exception.ExceptionCollector.assertExceptionMessage(
80             exception.InvalidTemplateVersion,
81             _('The template version "tosca_simple_yaml_1_10 in '
82               'custom_types/imported_sample.yaml" is invalid. '
83               'Valid versions are "tosca_simple_yaml_1_0, '
84               'tosca_simple_profile_for_nfv_1_0_0".'))
85         exception.ExceptionCollector.assertExceptionMessage(
86             exception.UnknownFieldError,
87             _('Template custom_types/imported_sample.yaml contains unknown '
88               'field "policy_types1". Refer to the definition to '
89               'verify valid values.'))
90         exception.ExceptionCollector.assertExceptionMessage(
91             exception.UnknownFieldError,
92             _('Nodetype"tosca.nodes.SoftwareComponent.Logstash" contains '
93               'unknown field "capabilities1". Refer to the definition '
94               'to verify valid values.'))
95         exception.ExceptionCollector.assertExceptionMessage(
96             exception.UnknownFieldError,
97             _('Policy "mycompany.mytypes.myScalingPolicy" contains unknown '
98               'field "derived1_from". Refer to the definition to '
99               'verify valid values.'))
100
101     def test_unsupported_type(self):
102         tpl_snippet = '''
103         node_templates:
104           invalid_type:
105             type: tosca.test.invalidtype
106             properties:
107               size: { get_input: storage_size }
108               snapshot_id: { get_input: storage_snapshot_id }
109         '''
110         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
111         err = self.assertRaises(exception.UnsupportedTypeError,
112                                 TopologyTemplate, tpl, None)
113         expectedmessage = _('Type "tosca.test.invalidtype" is valid'
114                             ' TOSCA type but not supported at this time.')
115         self.assertEqual(expectedmessage, err.__str__())
116
117     def test_inputs(self):
118         tpl_snippet1 = '''
119         inputs:
120           cpus:
121             type: integer
122             description: Number of CPUs for the server.
123             constraint:
124               - valid_values: [ 1, 2, 4 ]
125             required: yes
126             status: supported
127         '''
128         tpl_snippet2 = '''
129         inputs:
130           cpus:
131             type: integer
132             description: Number of CPUs for the server.
133             constraints:
134               - valid_values: [ 1, 2, 4 ]
135             required: yes
136             status: supported
137         '''
138         inputs1 = (toscaparser.utils.yamlparser.
139                    simple_parse(tpl_snippet1)['inputs'])
140         name1, attrs1 = list(inputs1.items())[0]
141         inputs2 = (toscaparser.utils.yamlparser.
142                    simple_parse(tpl_snippet2)['inputs'])
143         name2, attrs2 = list(inputs2.items())[0]
144         try:
145             Input(name1, attrs1)
146         except Exception as err:
147             # err=self.assertRaises(exception.UnknownFieldError,
148             #                       input1.validate)
149             self.assertEqual(_('Input "cpus" contains unknown field '
150                                '"constraint". Refer to the definition to '
151                                'verify valid values.'),
152                              err.__str__())
153         input2 = Input(name2, attrs2)
154         self.assertTrue(input2.required)
155
156     def _imports_content_test(self, tpl_snippet, path, custom_type_def):
157         imports = (toscaparser.utils.yamlparser.
158                    simple_parse(tpl_snippet)['imports'])
159         loader = ImportsLoader(imports, path, custom_type_def)
160         return loader.get_custom_defs()
161
162     def test_imports_without_templates(self):
163         tpl_snippet = '''
164         imports:
165           # omitted here for brevity
166         '''
167         path = 'toscaparser/tests/data/tosca_elk.yaml'
168         errormsg = _('"imports" keyname is defined without including '
169                      'templates.')
170         err = self.assertRaises(exception.ValidationError,
171                                 self._imports_content_test,
172                                 tpl_snippet,
173                                 path,
174                                 "node_types")
175         self.assertEqual(errormsg, err.__str__())
176
177     def test_imports_with_name_without_templates(self):
178         tpl_snippet = '''
179         imports:
180           - some_definitions:
181         '''
182         path = 'toscaparser/tests/data/tosca_elk.yaml'
183         errormsg = _('A template file name is not provided with import '
184                      'definition "some_definitions".')
185         err = self.assertRaises(exception.ValidationError,
186                                 self._imports_content_test,
187                                 tpl_snippet, path, None)
188         self.assertEqual(errormsg, err.__str__())
189
190     def test_imports_without_import_name(self):
191         tpl_snippet = '''
192         imports:
193           - custom_types/paypalpizzastore_nodejs_app.yaml
194           - https://raw.githubusercontent.com/openstack/\
195 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
196         '''
197         path = 'toscaparser/tests/data/tosca_elk.yaml'
198         custom_defs = self._imports_content_test(tpl_snippet,
199                                                  path,
200                                                  "node_types")
201         self.assertTrue(custom_defs)
202
203     def test_imports_wth_import_name(self):
204         tpl_snippet = '''
205         imports:
206           - some_definitions: custom_types/paypalpizzastore_nodejs_app.yaml
207           - more_definitions:
208               file: 'https://raw.githubusercontent.com/openstack/tosca-parser\
209 /master/toscaparser/tests/data/custom_types/wordpress.yaml'
210               namespace_prefix: single_instance_wordpress
211         '''
212         path = 'toscaparser/tests/data/tosca_elk.yaml'
213         custom_defs = self._imports_content_test(tpl_snippet,
214                                                  path,
215                                                  "node_types")
216         self.assertTrue(custom_defs.get("single_instance_wordpress.tosca."
217                                         "nodes.WebApplication.WordPress"))
218
219     def test_imports_wth_namespace_prefix(self):
220         tpl_snippet = '''
221         imports:
222           - more_definitions:
223               file: custom_types/nested_rsyslog.yaml
224               namespace_prefix: testprefix
225         '''
226         path = 'toscaparser/tests/data/tosca_elk.yaml'
227         custom_defs = self._imports_content_test(tpl_snippet,
228                                                  path,
229                                                  "node_types")
230         self.assertTrue(custom_defs.get("testprefix.Rsyslog"))
231
232     def test_imports_with_no_main_template(self):
233         tpl_snippet = '''
234         imports:
235           - some_definitions: https://raw.githubusercontent.com/openstack/\
236 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
237           - some_definitions:
238               file: my_defns/my_typesdefs_n.yaml
239         '''
240         errormsg = _('Input tosca template is not provided.')
241         err = self.assertRaises(exception.ValidationError,
242                                 self._imports_content_test,
243                                 tpl_snippet, None, None)
244         self.assertEqual(errormsg, err.__str__())
245
246     def test_imports_duplicate_name(self):
247         tpl_snippet = '''
248         imports:
249           - some_definitions: https://raw.githubusercontent.com/openstack/\
250 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
251           - some_definitions:
252               file: my_defns/my_typesdefs_n.yaml
253         '''
254         errormsg = _('Duplicate import name "some_definitions" was found.')
255         path = 'toscaparser/tests/data/tosca_elk.yaml'
256         err = self.assertRaises(exception.ValidationError,
257                                 self._imports_content_test,
258                                 tpl_snippet, path, None)
259         self.assertEqual(errormsg, err.__str__())
260
261     def test_imports_missing_req_field_in_def(self):
262         tpl_snippet = '''
263         imports:
264           - more_definitions:
265               file1: my_defns/my_typesdefs_n.yaml
266               repository: my_company_repo
267               namespace_uri: http://mycompany.com/ns/tosca/2.0
268               namespace_prefix: mycompany
269         '''
270         errormsg = _('Import of template "more_definitions" is missing '
271                      'required field "file".')
272         path = 'toscaparser/tests/data/tosca_elk.yaml'
273         err = self.assertRaises(exception.MissingRequiredFieldError,
274                                 self._imports_content_test,
275                                 tpl_snippet, path, None)
276         self.assertEqual(errormsg, err.__str__())
277
278     def test_imports_file_with_uri(self):
279         tpl_snippet = '''
280         imports:
281           - more_definitions:
282               file: https://raw.githubusercontent.com/openstack/\
283 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
284         '''
285         path = 'https://raw.githubusercontent.com/openstack/\
286 tosca-parser/master/toscaparser/tests/data/\
287 tosca_single_instance_wordpress_with_url_import.yaml'
288         custom_defs = self._imports_content_test(tpl_snippet,
289                                                  path,
290                                                  "node_types")
291         self.assertTrue(custom_defs.get("tosca.nodes."
292                                         "WebApplication.WordPress"))
293
294     def test_imports_file_namespace_fields(self):
295         tpl_snippet = '''
296         imports:
297           - more_definitions:
298              file: https://raw.githubusercontent.com/openstack/\
299 heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
300              namespace_prefix: mycompany
301              namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0
302         '''
303         path = 'toscaparser/tests/data/tosca_elk.yaml'
304         custom_defs = self._imports_content_test(tpl_snippet,
305                                                  path,
306                                                  "node_types")
307         self.assertTrue(custom_defs.get("mycompany.tosca.nodes."
308                                         "WebApplication.WordPress"))
309
310     def test_import_error_file_uri(self):
311         tpl_snippet = '''
312         imports:
313           - more_definitions:
314              file: mycompany.com/ns/tosca/2.0/toscaparser/tests/data\
315 /tosca_elk.yaml
316              namespace_prefix: mycompany
317              namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0
318         '''
319         path = 'toscaparser/tests/data/tosca_elk.yaml'
320         self.assertRaises(ImportError,
321                           self._imports_content_test,
322                           tpl_snippet, path, None)
323
324     def test_import_single_line_error(self):
325         tpl_snippet = '''
326         imports:
327           - some_definitions: abc.com/tests/data/tosca_elk.yaml
328         '''
329         errormsg = _('Import "abc.com/tests/data/tosca_elk.yaml" is not '
330                      'valid.')
331         path = 'toscaparser/tests/data/tosca_elk.yaml'
332         err = self.assertRaises(ImportError,
333                                 self._imports_content_test,
334                                 tpl_snippet, path, None)
335         self.assertEqual(errormsg, err.__str__())
336
337     def test_outputs(self):
338         tpl_snippet = '''
339         outputs:
340           server_address:
341             description: IP address of server instance.
342             values: { get_property: [server, private_address] }
343         '''
344         outputs = (toscaparser.utils.yamlparser.
345                    simple_parse(tpl_snippet)['outputs'])
346         name, attrs = list(outputs.items())[0]
347         output = Output(name, attrs)
348         try:
349             output.validate()
350         except Exception as err:
351             self.assertTrue(
352                 isinstance(err, exception.MissingRequiredFieldError))
353             self.assertEqual(_('Output "server_address" is missing required '
354                                'field "value".'), err.__str__())
355
356         tpl_snippet = '''
357         outputs:
358           server_address:
359             descriptions: IP address of server instance.
360             value: { get_property: [server, private_address] }
361         '''
362         outputs = (toscaparser.utils.yamlparser.
363                    simple_parse(tpl_snippet)['outputs'])
364         name, attrs = list(outputs.items())[0]
365         output = Output(name, attrs)
366         try:
367             output.validate()
368         except Exception as err:
369             self.assertTrue(isinstance(err, exception.UnknownFieldError))
370             self.assertEqual(_('Output "server_address" contains unknown '
371                                'field "descriptions". Refer to the definition '
372                                'to verify valid values.'),
373                              err.__str__())
374
375     def _repo_content(self, path):
376         repositories = path['repositories']
377         reposit = []
378         for name, val in repositories.items():
379             reposits = Repository(name, val)
380             reposit.append(reposits)
381         return reposit
382
383     def test_repositories(self):
384         tpl_snippet = '''
385         repositories:
386            repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
387            repo_code1:
388               description: My project's code Repository in github usercontent.
389               url: https://github.com/nandinivemula/intern
390               credential:
391                  user: nandini
392                  password: tcs@12345
393            repo_code2:
394               description: My Project's code Repository in github.
395               url: https://github.com/nandinivemula/intern
396               credential:
397                  user: xyzw
398                  password: xyz@123
399         '''
400         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
401         repoobject = self._repo_content(tpl)
402         actualrepo_names = []
403         for repo in repoobject:
404             repos = repo.name
405             actualrepo_names.append(repos)
406         reposname = list(tpl.values())
407         reposnames = reposname[0]
408         expected_reponames = list(reposnames.keys())
409         self.assertEqual(expected_reponames, actualrepo_names)
410
411     def test_repositories_with_missing_required_field(self):
412         tpl_snippet = '''
413         repositories:
414            repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
415            repo_code1:
416               description: My project's code Repository in github usercontent.
417               credential:
418                  user: nandini
419                  password: tcs@12345
420            repo_code2:
421               description: My Project's code Repository in github.
422               url: https://github.com/nandinivemula/intern
423               credential:
424                  user: xyzw
425                  password: xyz@123
426         '''
427         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
428         err = self.assertRaises(exception.MissingRequiredFieldError,
429                                 self._repo_content, tpl)
430         expectedmessage = _('Repository "repo_code1" is missing '
431                             'required field "url".')
432         self.assertEqual(expectedmessage, err.__str__())
433
434     def test_repositories_with_unknown_field(self):
435         tpl_snippet = '''
436         repositories:
437            repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
438            repo_code1:
439               description: My project's code Repository in github usercontent.
440               url: https://github.com/nandinivemula/intern
441               credential:
442                  user: nandini
443                  password: tcs@12345
444            repo_code2:
445               descripton: My Project's code Repository in github.
446               url: https://github.com/nandinivemula/intern
447               credential:
448                  user: xyzw
449                  password: xyz@123
450         '''
451         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
452         err = self.assertRaises(exception.UnknownFieldError,
453                                 self._repo_content, tpl)
454         expectedmessage = _('repositories "repo_code2" contains unknown field'
455                             ' "descripton". Refer to the definition to verify'
456                             ' valid values.')
457         self.assertEqual(expectedmessage, err.__str__())
458
459     def test_repositories_with_invalid_url(self):
460         tpl_snippet = '''
461         repositories:
462            repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
463            repo_code1:
464               description: My project's code Repository in github usercontent.
465               url: h
466               credential:
467                  user: nandini
468                  password: tcs@12345
469            repo_code2:
470               description: My Project's code Repository in github.
471               url: https://github.com/nandinivemula/intern
472               credential:
473                  user: xyzw
474                  password: xyz@123
475         '''
476         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
477         err = self.assertRaises(exception.URLException,
478                                 self._repo_content, tpl)
479         expectedmessage = _('repsositories "repo_code1" Invalid Url')
480         self.assertEqual(expectedmessage, err.__str__())
481
482     def test_groups(self):
483         tpl_snippet = '''
484         node_templates:
485           server:
486             type: tosca.nodes.Compute
487             requirements:
488               - log_endpoint:
489                   capability: log_endpoint
490
491           mysql_dbms:
492             type: tosca.nodes.DBMS
493             properties:
494               root_password: aaa
495               port: 3376
496
497         groups:
498           webserver_group:
499             type: tosca.groups.Root
500             members: [ server, mysql_dbms ]
501         '''
502         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
503         TopologyTemplate(tpl, None)
504
505     def test_groups_with_missing_required_field(self):
506         tpl_snippet = '''
507         node_templates:
508           server:
509             type: tosca.nodes.Compute
510             requirements:
511               - log_endpoint:
512                   capability: log_endpoint
513
514           mysql_dbms:
515             type: tosca.nodes.DBMS
516             properties:
517               root_password: aaa
518               port: 3376
519
520         groups:
521           webserver_group:
522               members: ['server', 'mysql_dbms']
523         '''
524         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
525         err = self.assertRaises(exception.MissingRequiredFieldError,
526                                 TopologyTemplate, tpl, None)
527         expectedmessage = _('Template "webserver_group" is missing '
528                             'required field "type".')
529         self.assertEqual(expectedmessage, err.__str__())
530
531     def test_groups_with_unknown_target(self):
532         tpl_snippet = '''
533         node_templates:
534           server:
535             type: tosca.nodes.Compute
536             requirements:
537               - log_endpoint:
538                   capability: log_endpoint
539
540           mysql_dbms:
541             type: tosca.nodes.DBMS
542             properties:
543               root_password: aaa
544               port: 3376
545
546         groups:
547           webserver_group:
548             type: tosca.groups.Root
549             members: [ serv, mysql_dbms ]
550         '''
551         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
552         expectedmessage = _('"Target member "serv" is not found in '
553                             'node_templates"')
554         err = self.assertRaises(exception.InvalidGroupTargetException,
555                                 TopologyTemplate, tpl, None)
556         self.assertEqual(expectedmessage, err.__str__())
557
558     def test_groups_with_repeated_targets(self):
559         tpl_snippet = '''
560         node_templates:
561           server:
562             type: tosca.nodes.Compute
563             requirements:
564               - log_endpoint:
565                   capability: log_endpoint
566
567           mysql_dbms:
568             type: tosca.nodes.DBMS
569             properties:
570               root_password: aaa
571               port: 3376
572
573         groups:
574           webserver_group:
575             type: tosca.groups.Root
576             members: [ server, server, mysql_dbms ]
577         '''
578         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
579         expectedmessage = _('"Member nodes '
580                             '"[\'server\', \'server\', \'mysql_dbms\']" '
581                             'should be >= 1 and not repeated"')
582         err = self.assertRaises(exception.InvalidGroupTargetException,
583                                 TopologyTemplate, tpl, None)
584         self.assertEqual(expectedmessage, err.__str__())
585
586     def test_groups_with_only_one_target(self):
587         tpl_snippet = '''
588         node_templates:
589           server:
590             type: tosca.nodes.Compute
591             requirements:
592               - log_endpoint:
593                   capability: log_endpoint
594
595           mysql_dbms:
596             type: tosca.nodes.DBMS
597             properties:
598               root_password: aaa
599               port: 3376
600
601         groups:
602           webserver_group:
603             type: tosca.groups.Root
604             members: []
605         '''
606         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
607         expectedmessage = _('"Member nodes "[]" should be >= 1 '
608                             'and not repeated"')
609         err = self.assertRaises(exception.InvalidGroupTargetException,
610                                 TopologyTemplate, tpl, None)
611         self.assertEqual(expectedmessage, err.__str__())
612
613     def _custom_types(self):
614         custom_types = {}
615         def_file = os.path.join(
616             os.path.dirname(os.path.abspath(__file__)),
617             "data/custom_types/wordpress.yaml")
618         custom_type = toscaparser.utils.yamlparser.load_yaml(def_file)
619         node_types = custom_type['node_types']
620         for name in node_types:
621             defintion = node_types[name]
622             custom_types[name] = defintion
623         return custom_types
624
625     def _single_node_template_content_test(self, tpl_snippet):
626         nodetemplates = (toscaparser.utils.yamlparser.
627                          simple_ordered_parse(tpl_snippet))['node_templates']
628         name = list(nodetemplates.keys())[0]
629         nodetemplate = NodeTemplate(name, nodetemplates,
630                                     self._custom_types())
631         nodetemplate.validate()
632         nodetemplate.requirements
633         nodetemplate.get_capabilities_objects()
634         nodetemplate.get_properties_objects()
635         nodetemplate.interfaces
636
637     def test_node_templates(self):
638         tpl_snippet = '''
639         node_templates:
640           server:
641             capabilities:
642               host:
643                 properties:
644                   disk_size: 10
645                   num_cpus: 4
646                   mem_size: 4096
647               os:
648                 properties:
649                   architecture: x86_64
650                   type: Linux
651                   distribution: Fedora
652                   version: 18.0
653         '''
654         expectedmessage = _('Template "server" is missing required field '
655                             '"type".')
656         err = self.assertRaises(
657             exception.MissingRequiredFieldError,
658             lambda: self._single_node_template_content_test(tpl_snippet))
659         self.assertEqual(expectedmessage, err.__str__())
660
661     def test_node_template_with_wrong_properties_keyname(self):
662         """Node template keyname 'properties' given as 'propertiessss'."""
663         tpl_snippet = '''
664         node_templates:
665           mysql_dbms:
666             type: tosca.nodes.DBMS
667             propertiessss:
668               root_password: aaa
669               port: 3376
670         '''
671         expectedmessage = _('Node template "mysql_dbms" contains unknown '
672                             'field "propertiessss". Refer to the definition '
673                             'to verify valid values.')
674         err = self.assertRaises(
675             exception.UnknownFieldError,
676             lambda: self._single_node_template_content_test(tpl_snippet))
677         self.assertEqual(expectedmessage, err.__str__())
678
679     def test_node_template_with_wrong_requirements_keyname(self):
680         """Node template keyname 'requirements' given as 'requirement'."""
681         tpl_snippet = '''
682         node_templates:
683           mysql_dbms:
684             type: tosca.nodes.DBMS
685             properties:
686               root_password: aaa
687               port: 3376
688             requirement:
689               - host: server
690         '''
691         expectedmessage = _('Node template "mysql_dbms" contains unknown '
692                             'field "requirement". Refer to the definition to '
693                             'verify valid values.')
694         err = self.assertRaises(
695             exception.UnknownFieldError,
696             lambda: self._single_node_template_content_test(tpl_snippet))
697         self.assertEqual(expectedmessage, err.__str__())
698
699     def test_node_template_with_wrong_interfaces_keyname(self):
700         """Node template keyname 'interfaces' given as 'interfac'."""
701         tpl_snippet = '''
702         node_templates:
703           mysql_dbms:
704             type: tosca.nodes.DBMS
705             properties:
706               root_password: aaa
707               port: 3376
708             requirements:
709               - host: server
710             interfac:
711               Standard:
712                 configure: mysql_database_configure.sh
713         '''
714         expectedmessage = _('Node template "mysql_dbms" contains unknown '
715                             'field "interfac". Refer to the definition to '
716                             'verify valid values.')
717         err = self.assertRaises(
718             exception.UnknownFieldError,
719             lambda: self._single_node_template_content_test(tpl_snippet))
720         self.assertEqual(expectedmessage, err.__str__())
721
722     def test_node_template_with_wrong_capabilities_keyname(self):
723         """Node template keyname 'capabilities' given as 'capabilitiis'."""
724         tpl_snippet = '''
725         node_templates:
726           mysql_database:
727             type: tosca.nodes.Database
728             properties:
729               db_name: { get_input: db_name }
730               db_user: { get_input: db_user }
731               db_password: { get_input: db_pwd }
732             capabilitiis:
733               database_endpoint:
734                 properties:
735                   port: { get_input: db_port }
736         '''
737         expectedmessage = _('Node template "mysql_database" contains unknown '
738                             'field "capabilitiis". Refer to the definition to '
739                             'verify valid values.')
740         err = self.assertRaises(
741             exception.UnknownFieldError,
742             lambda: self._single_node_template_content_test(tpl_snippet))
743         self.assertEqual(expectedmessage, err.__str__())
744
745     def test_node_template_with_wrong_artifacts_keyname(self):
746         """Node template keyname 'artifacts' given as 'artifactsss'."""
747         tpl_snippet = '''
748         node_templates:
749           mysql_database:
750             type: tosca.nodes.Database
751             artifactsss:
752               db_content:
753                 implementation: files/my_db_content.txt
754                 type: tosca.artifacts.File
755         '''
756         expectedmessage = _('Node template "mysql_database" contains unknown '
757                             'field "artifactsss". Refer to the definition to '
758                             'verify valid values.')
759         err = self.assertRaises(
760             exception.UnknownFieldError,
761             lambda: self._single_node_template_content_test(tpl_snippet))
762         self.assertEqual(expectedmessage, err.__str__())
763
764     def test_node_template_with_multiple_wrong_keynames(self):
765         """Node templates given with multiple wrong keynames."""
766         tpl_snippet = '''
767         node_templates:
768           mysql_dbms:
769             type: tosca.nodes.DBMS
770             propertieees:
771               root_password: aaa
772               port: 3376
773             requirements:
774               - host: server
775             interfacs:
776               Standard:
777                 configure: mysql_database_configure.sh
778         '''
779         expectedmessage = _('Node template "mysql_dbms" contains unknown '
780                             'field "propertieees". Refer to the definition to '
781                             'verify valid values.')
782         err = self.assertRaises(
783             exception.UnknownFieldError,
784             lambda: self._single_node_template_content_test(tpl_snippet))
785         self.assertEqual(expectedmessage, err.__str__())
786
787         tpl_snippet = '''
788         node_templates:
789           mysql_database:
790             type: tosca.nodes.Database
791             properties:
792               name: { get_input: db_name }
793               user: { get_input: db_user }
794               password: { get_input: db_pwd }
795             capabilitiiiies:
796               database_endpoint:
797               properties:
798                 port: { get_input: db_port }
799             requirementsss:
800               - host:
801                   node: mysql_dbms
802             interfac:
803               Standard:
804                  configure: mysql_database_configure.sh
805
806         '''
807         expectedmessage = _('Node template "mysql_database" contains unknown '
808                             'field "capabilitiiiies". Refer to the definition '
809                             'to verify valid values.')
810         err = self.assertRaises(
811             exception.UnknownFieldError,
812             lambda: self._single_node_template_content_test(tpl_snippet))
813         self.assertEqual(expectedmessage, err.__str__())
814
815     def test_node_template_type(self):
816         tpl_snippet = '''
817         node_templates:
818           mysql_database:
819             type: tosca.nodes.Databases
820             properties:
821               db_name: { get_input: db_name }
822               db_user: { get_input: db_user }
823               db_password: { get_input: db_pwd }
824             capabilities:
825               database_endpoint:
826                 properties:
827                   port: { get_input: db_port }
828             requirements:
829               - host: mysql_dbms
830             interfaces:
831               Standard:
832                  configure: mysql_database_configure.sh
833         '''
834         expectedmessage = _('Type "tosca.nodes.Databases" is not '
835                             'a valid type.')
836         err = self.assertRaises(
837             exception.InvalidTypeError,
838             lambda: self._single_node_template_content_test(tpl_snippet))
839         self.assertEqual(expectedmessage, err.__str__())
840
841     def test_node_template_requirements(self):
842         tpl_snippet = '''
843         node_templates:
844           webserver:
845             type: tosca.nodes.WebServer
846             requirements:
847               host: server
848             interfaces:
849               Standard:
850                 create: webserver_install.sh
851                 start: d.sh
852         '''
853         expectedmessage = _('"requirements" of template "webserver" must be '
854                             'of type "list".')
855         err = self.assertRaises(
856             exception.TypeMismatchError,
857             lambda: self._single_node_template_content_test(tpl_snippet))
858         self.assertEqual(expectedmessage, err.__str__())
859
860         tpl_snippet = '''
861         node_templates:
862           mysql_database:
863             type: tosca.nodes.Database
864             properties:
865               db_name: { get_input: db_name }
866               db_user: { get_input: db_user }
867               db_password: { get_input: db_pwd }
868             capabilities:
869               database_endpoint:
870                 properties:
871                   port: { get_input: db_port }
872             requirements:
873               - host: mysql_dbms
874               - database_endpoint: mysql_database
875             interfaces:
876               Standard:
877                  configure: mysql_database_configure.sh
878         '''
879         expectedmessage = _('"requirements" of template "mysql_database" '
880                             'contains unknown field "database_endpoint". '
881                             'Refer to the definition to verify valid values.')
882         err = self.assertRaises(
883             exception.UnknownFieldError,
884             lambda: self._single_node_template_content_test(tpl_snippet))
885         self.assertEqual(expectedmessage, err.__str__())
886
887     def test_node_template_requirements_with_wrong_node_keyname(self):
888         """Node template requirements keyname 'node' given as 'nodes'."""
889         tpl_snippet = '''
890         node_templates:
891           mysql_database:
892             type: tosca.nodes.Database
893             requirements:
894               - host:
895                   nodes: mysql_dbms
896
897         '''
898         expectedmessage = _('"requirements" of template "mysql_database" '
899                             'contains unknown field "nodes". Refer to the '
900                             'definition to verify valid values.')
901         err = self.assertRaises(
902             exception.UnknownFieldError,
903             lambda: self._single_node_template_content_test(tpl_snippet))
904         self.assertEqual(expectedmessage, err.__str__())
905
906     def test_node_template_requirements_with_wrong_capability_keyname(self):
907         """Incorrect node template requirements keyname
908
909         Node template requirements keyname 'capability' given as
910         'capabilityy'.
911         """
912         tpl_snippet = '''
913         node_templates:
914           mysql_database:
915             type: tosca.nodes.Database
916             requirements:
917               - host:
918                   node: mysql_dbms
919               - log_endpoint:
920                   node: logstash
921                   capabilityy: log_endpoint
922                   relationship:
923                     type: tosca.relationships.ConnectsTo
924
925         '''
926         expectedmessage = _('"requirements" of template "mysql_database" '
927                             'contains unknown field "capabilityy". Refer to '
928                             'the definition to verify valid values.')
929         err = self.assertRaises(
930             exception.UnknownFieldError,
931             lambda: self._single_node_template_content_test(tpl_snippet))
932         self.assertEqual(expectedmessage, err.__str__())
933
934     def test_node_template_requirements_with_wrong_relationship_keyname(self):
935         """Incorrect node template requirements keyname
936
937         Node template requirements keyname 'relationship' given as
938         'relationshipppp'.
939         """
940         tpl_snippet = '''
941         node_templates:
942           mysql_database:
943             type: tosca.nodes.Database
944             requirements:
945               - host:
946                   node: mysql_dbms
947               - log_endpoint:
948                   node: logstash
949                   capability: log_endpoint
950                   relationshipppp:
951                     type: tosca.relationships.ConnectsTo
952
953         '''
954         expectedmessage = _('"requirements" of template "mysql_database" '
955                             'contains unknown field "relationshipppp". Refer '
956                             'to the definition to verify valid values.')
957         err = self.assertRaises(
958             exception.UnknownFieldError,
959             lambda: self._single_node_template_content_test(tpl_snippet))
960         self.assertEqual(expectedmessage, err.__str__())
961
962     def test_node_template_requirements_with_wrong_occurrences_keyname(self):
963         """Incorrect node template requirements keyname
964
965         Node template requirements keyname 'occurrences' given as
966         'occurences'.
967         """
968         tpl_snippet = '''
969         node_templates:
970           mysql_database:
971             type: tosca.nodes.Database
972             requirements:
973               - host:
974                   node: mysql_dbms
975               - log_endpoint:
976                   node: logstash
977                   capability: log_endpoint
978                   relationship:
979                     type: tosca.relationships.ConnectsTo
980                   occurences: [0, UNBOUNDED]
981         '''
982         expectedmessage = _('"requirements" of template "mysql_database" '
983                             'contains unknown field "occurences". Refer to '
984                             'the definition to verify valid values.')
985         err = self.assertRaises(
986             exception.UnknownFieldError,
987             lambda: self._single_node_template_content_test(tpl_snippet))
988         self.assertEqual(expectedmessage, err.__str__())
989
990     def test_node_template_requirements_with_multiple_wrong_keynames(self):
991         """Node templates given with multiple wrong requirements keynames."""
992         tpl_snippet = '''
993         node_templates:
994           mysql_database:
995             type: tosca.nodes.Database
996             requirements:
997               - host:
998                   node: mysql_dbms
999               - log_endpoint:
1000                   nod: logstash
1001                   capabilit: log_endpoint
1002                   relationshipppp:
1003                     type: tosca.relationships.ConnectsTo
1004
1005         '''
1006         expectedmessage = _('"requirements" of template "mysql_database" '
1007                             'contains unknown field "nod". Refer to the '
1008                             'definition to verify valid values.')
1009         err = self.assertRaises(
1010             exception.UnknownFieldError,
1011             lambda: self._single_node_template_content_test(tpl_snippet))
1012         self.assertEqual(expectedmessage, err.__str__())
1013
1014         tpl_snippet = '''
1015         node_templates:
1016           mysql_database:
1017             type: tosca.nodes.Database
1018             requirements:
1019               - host:
1020                   node: mysql_dbms
1021               - log_endpoint:
1022                   node: logstash
1023                   capabilit: log_endpoint
1024                   relationshipppp:
1025                     type: tosca.relationships.ConnectsTo
1026
1027         '''
1028         expectedmessage = _('"requirements" of template "mysql_database" '
1029                             'contains unknown field "capabilit". Refer to the '
1030                             'definition to verify valid values.')
1031         err = self.assertRaises(
1032             exception.UnknownFieldError,
1033             lambda: self._single_node_template_content_test(tpl_snippet))
1034         self.assertEqual(expectedmessage, err.__str__())
1035
1036     def test_node_template_requirements_invalid_occurrences(self):
1037         tpl_snippet = '''
1038         node_templates:
1039           server:
1040             type: tosca.nodes.Compute
1041             requirements:
1042               - log_endpoint:
1043                   capability: log_endpoint
1044                   occurrences: [0, -1]
1045         '''
1046         expectedmessage = _('Value of property "[0, -1]" is invalid.')
1047         err = self.assertRaises(
1048             exception.InvalidPropertyValueError,
1049             lambda: self._single_node_template_content_test(tpl_snippet))
1050         self.assertEqual(expectedmessage, err.__str__())
1051
1052         tpl_snippet = '''
1053         node_templates:
1054           server:
1055             type: tosca.nodes.Compute
1056             requirements:
1057               - log_endpoint:
1058                   capability: log_endpoint
1059                   occurrences: [a, w]
1060         '''
1061         expectedmessage = _('"a" is not an integer.')
1062         err = self.assertRaises(
1063             ValueError,
1064             lambda: self._single_node_template_content_test(tpl_snippet))
1065         self.assertEqual(expectedmessage, err.__str__())
1066
1067         tpl_snippet = '''
1068         node_templates:
1069           server:
1070             type: tosca.nodes.Compute
1071             requirements:
1072               - log_endpoint:
1073                   capability: log_endpoint
1074                   occurrences: -1
1075         '''
1076         expectedmessage = _('"-1" is not a list.')
1077         err = self.assertRaises(
1078             ValueError,
1079             lambda: self._single_node_template_content_test(tpl_snippet))
1080         self.assertEqual(expectedmessage, err.__str__())
1081
1082         tpl_snippet = '''
1083         node_templates:
1084           server:
1085             type: tosca.nodes.Compute
1086             requirements:
1087               - log_endpoint:
1088                   capability: log_endpoint
1089                   occurrences: [5, 1]
1090         '''
1091         expectedmessage = _('Value of property "[5, 1]" is invalid.')
1092         err = self.assertRaises(
1093             exception.InvalidPropertyValueError,
1094             lambda: self._single_node_template_content_test(tpl_snippet))
1095         self.assertEqual(expectedmessage, err.__str__())
1096
1097         tpl_snippet = '''
1098         node_templates:
1099           server:
1100             type: tosca.nodes.Compute
1101             requirements:
1102               - log_endpoint:
1103                   capability: log_endpoint
1104                   occurrences: [0, 0]
1105         '''
1106         expectedmessage = _('Value of property "[0, 0]" is invalid.')
1107         err = self.assertRaises(
1108             exception.InvalidPropertyValueError,
1109             lambda: self._single_node_template_content_test(tpl_snippet))
1110         self.assertEqual(expectedmessage, err.__str__())
1111
1112     def test_node_template_requirements_valid_occurrences(self):
1113         tpl_snippet = '''
1114         node_templates:
1115           server:
1116             type: tosca.nodes.Compute
1117             requirements:
1118               - log_endpoint:
1119                   capability: log_endpoint
1120                   occurrences: [2, 2]
1121         '''
1122         self._single_node_template_content_test(tpl_snippet)
1123
1124     def test_node_template_capabilities(self):
1125         tpl_snippet = '''
1126         node_templates:
1127           mysql_database:
1128             type: tosca.nodes.Database
1129             properties:
1130               db_name: { get_input: db_name }
1131               db_user: { get_input: db_user }
1132               db_password: { get_input: db_pwd }
1133             capabilities:
1134               http_endpoint:
1135                 properties:
1136                   port: { get_input: db_port }
1137             requirements:
1138               - host: mysql_dbms
1139             interfaces:
1140               Standard:
1141                  configure: mysql_database_configure.sh
1142         '''
1143         expectedmessage = _('"capabilities" of template "mysql_database" '
1144                             'contains unknown field "http_endpoint". Refer to '
1145                             'the definition to verify valid values.')
1146         err = self.assertRaises(
1147             exception.UnknownFieldError,
1148             lambda: self._single_node_template_content_test(tpl_snippet))
1149         self.assertEqual(expectedmessage, err.__str__())
1150
1151     def test_node_template_properties(self):
1152         tpl_snippet = '''
1153         node_templates:
1154           server:
1155             type: tosca.nodes.Compute
1156             properties:
1157               os_image: F18_x86_64
1158             capabilities:
1159               host:
1160                 properties:
1161                   disk_size: 10 GB
1162                   num_cpus: { get_input: cpus }
1163                   mem_size: 4096 MB
1164               os:
1165                 properties:
1166                   architecture: x86_64
1167                   type: Linux
1168                   distribution: Fedora
1169                   version: 18.0
1170         '''
1171         expectedmessage = _('"properties" of template "server" contains '
1172                             'unknown field "os_image". Refer to the '
1173                             'definition to verify valid values.')
1174         err = self.assertRaises(
1175             exception.UnknownFieldError,
1176             lambda: self._single_node_template_content_test(tpl_snippet))
1177         self.assertEqual(expectedmessage, err.__str__())
1178
1179     def test_node_template_interfaces(self):
1180         tpl_snippet = '''
1181         node_templates:
1182           wordpress:
1183             type: tosca.nodes.WebApplication.WordPress
1184             requirements:
1185               - host: webserver
1186               - database_endpoint: mysql_database
1187             interfaces:
1188               Standards:
1189                  create: wordpress_install.sh
1190                  configure:
1191                    implementation: wordpress_configure.sh
1192                    inputs:
1193                      wp_db_name: { get_property: [ mysql_database, db_name ] }
1194                      wp_db_user: { get_property: [ mysql_database, db_user ] }
1195                      wp_db_password: { get_property: [ mysql_database, \
1196                      db_password ] }
1197                      wp_db_port: { get_property: [ SELF, \
1198                      database_endpoint, port ] }
1199         '''
1200         expectedmessage = _('"interfaces" of template "wordpress" contains '
1201                             'unknown field "Standards". Refer to the '
1202                             'definition to verify valid values.')
1203         err = self.assertRaises(
1204             exception.UnknownFieldError,
1205             lambda: self._single_node_template_content_test(tpl_snippet))
1206         self.assertEqual(expectedmessage, err.__str__())
1207
1208         tpl_snippet = '''
1209         node_templates:
1210           wordpress:
1211             type: tosca.nodes.WebApplication.WordPress
1212             requirements:
1213               - host: webserver
1214               - database_endpoint: mysql_database
1215             interfaces:
1216               Standard:
1217                  create: wordpress_install.sh
1218                  config:
1219                    implementation: wordpress_configure.sh
1220                    inputs:
1221                      wp_db_name: { get_property: [ mysql_database, db_name ] }
1222                      wp_db_user: { get_property: [ mysql_database, db_user ] }
1223                      wp_db_password: { get_property: [ mysql_database, \
1224                      db_password ] }
1225                      wp_db_port: { get_property: [ SELF, \
1226                      database_endpoint, port ] }
1227         '''
1228         expectedmessage = _('"interfaces" of template "wordpress" contains '
1229                             'unknown field "config". Refer to the definition '
1230                             'to verify valid values.')
1231         err = self.assertRaises(
1232             exception.UnknownFieldError,
1233             lambda: self._single_node_template_content_test(tpl_snippet))
1234         self.assertEqual(expectedmessage, err.__str__())
1235
1236         tpl_snippet = '''
1237         node_templates:
1238           wordpress:
1239             type: tosca.nodes.WebApplication.WordPress
1240             requirements:
1241               - host: webserver
1242               - database_endpoint: mysql_database
1243             interfaces:
1244               Standard:
1245                  create: wordpress_install.sh
1246                  configure:
1247                    implementation: wordpress_configure.sh
1248                    input:
1249                      wp_db_name: { get_property: [ mysql_database, db_name ] }
1250                      wp_db_user: { get_property: [ mysql_database, db_user ] }
1251                      wp_db_password: { get_property: [ mysql_database, \
1252                      db_password ] }
1253                      wp_db_port: { get_ref_property: [ database_endpoint, \
1254                      database_endpoint, port ] }
1255         '''
1256         expectedmessage = _('"interfaces" of template "wordpress" contains '
1257                             'unknown field "input". Refer to the definition '
1258                             'to verify valid values.')
1259         err = self.assertRaises(
1260             exception.UnknownFieldError,
1261             lambda: self._single_node_template_content_test(tpl_snippet))
1262         self.assertEqual(expectedmessage, err.__str__())
1263
1264     def test_relationship_template_properties(self):
1265         tpl_snippet = '''
1266         relationship_templates:
1267             storage_attachto:
1268                 type: AttachesTo
1269                 properties:
1270                   device: test_device
1271         '''
1272         expectedmessage = _('"properties" of template "storage_attachto" is '
1273                             'missing required field "[\'location\']".')
1274         rel_template = (toscaparser.utils.yamlparser.
1275                         simple_parse(tpl_snippet))['relationship_templates']
1276         name = list(rel_template.keys())[0]
1277         rel_template = RelationshipTemplate(rel_template[name], name)
1278         err = self.assertRaises(exception.MissingRequiredFieldError,
1279                                 rel_template.validate)
1280         self.assertEqual(expectedmessage, six.text_type(err))
1281
1282     def test_invalid_template_version(self):
1283         tosca_tpl = os.path.join(
1284             os.path.dirname(os.path.abspath(__file__)),
1285             "data/test_invalid_template_version.yaml")
1286         self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl)
1287         valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS)
1288         exception.ExceptionCollector.assertExceptionMessage(
1289             exception.InvalidTemplateVersion,
1290             (_('The template version "tosca_xyz" is invalid. Valid versions '
1291                'are "%s".') % valid_versions))
1292
1293     def test_node_template_capabilities_properties(self):
1294         # validating capability property values
1295         tpl_snippet = '''
1296         node_templates:
1297           server:
1298             type: tosca.nodes.WebServer
1299             capabilities:
1300               data_endpoint:
1301                 properties:
1302                   initiator: test
1303         '''
1304         expectedmessage = _('The value "test" of property "initiator" is '
1305                             'not valid. Expected a value from "[source, '
1306                             'target, peer]".')
1307
1308         err = self.assertRaises(
1309             exception.ValidationError,
1310             lambda: self._single_node_template_content_test(tpl_snippet))
1311         self.assertEqual(expectedmessage, err.__str__())
1312
1313         tpl_snippet = '''
1314         node_templates:
1315           server:
1316             type: tosca.nodes.Compute
1317             capabilities:
1318               host:
1319                 properties:
1320                   disk_size: 10 GB
1321                   num_cpus: { get_input: cpus }
1322                   mem_size: 4096 MB
1323               os:
1324                 properties:
1325                   architecture: x86_64
1326                   type: Linux
1327                   distribution: Fedora
1328                   version: 18.0
1329               scalable:
1330                 properties:
1331                   min_instances: 1
1332                   max_instances: 3
1333                   default_instances: 5
1334         '''
1335         expectedmessage = _('"properties" of template "server": '
1336                             '"default_instances" value is not between '
1337                             '"min_instances" and "max_instances".')
1338         err = self.assertRaises(
1339             exception.ValidationError,
1340             lambda: self._single_node_template_content_test(tpl_snippet))
1341         self.assertEqual(expectedmessage, err.__str__())
1342
1343     def test_node_template_objectstorage_without_required_property(self):
1344         tpl_snippet = '''
1345         node_templates:
1346           server:
1347             type: tosca.nodes.ObjectStorage
1348             properties:
1349               maxsize: 1 GB
1350         '''
1351         expectedmessage = _('"properties" of template "server" is missing '
1352                             'required field "[\'name\']".')
1353         err = self.assertRaises(
1354             exception.MissingRequiredFieldError,
1355             lambda: self._single_node_template_content_test(tpl_snippet))
1356         self.assertEqual(expectedmessage, err.__str__())
1357
1358     def test_node_template_objectstorage_with_invalid_scalar_unit(self):
1359         tpl_snippet = '''
1360         node_templates:
1361           server:
1362             type: tosca.nodes.ObjectStorage
1363             properties:
1364               name: test
1365               maxsize: -1
1366         '''
1367         expectedmessage = _('"-1" is not a valid scalar-unit.')
1368         err = self.assertRaises(
1369             ValueError,
1370             lambda: self._single_node_template_content_test(tpl_snippet))
1371         self.assertEqual(expectedmessage, err.__str__())
1372
1373     def test_node_template_objectstorage_with_invalid_scalar_type(self):
1374         tpl_snippet = '''
1375         node_templates:
1376           server:
1377             type: tosca.nodes.ObjectStorage
1378             properties:
1379               name: test
1380               maxsize: 1 XB
1381         '''
1382         expectedmessage = _('"1 XB" is not a valid scalar-unit.')
1383         err = self.assertRaises(
1384             ValueError,
1385             lambda: self._single_node_template_content_test(tpl_snippet))
1386         self.assertEqual(expectedmessage, err.__str__())
1387
1388     def test_special_keywords(self):
1389         """Test special keywords
1390
1391            Test that special keywords, e.g. metadata, which are not part
1392            of specification do not throw any validation error.
1393         """
1394         tpl_snippet_metadata_map = '''
1395         node_templates:
1396           server:
1397             type: tosca.nodes.Compute
1398             metadata:
1399               name: server A
1400               role: master
1401         '''
1402         self._single_node_template_content_test(tpl_snippet_metadata_map)
1403
1404         tpl_snippet_metadata_inline = '''
1405         node_templates:
1406           server:
1407             type: tosca.nodes.Compute
1408             metadata: none
1409         '''
1410         self._single_node_template_content_test(tpl_snippet_metadata_inline)
1411
1412     def test_policy_valid_keynames(self):
1413         tpl_snippet = '''
1414         policies:
1415           - servers_placement:
1416               type: tosca.policies.Placement
1417               description: Apply placement policy to servers
1418               metadata: { user1: 1001, user2: 1002 }
1419               targets: [ serv1, serv2 ]
1420         '''
1421         policies = (toscaparser.utils.yamlparser.
1422                     simple_parse(tpl_snippet))['policies'][0]
1423         name = list(policies.keys())[0]
1424         Policy(name, policies[name], None, None)
1425
1426     def test_policy_invalid_keyname(self):
1427         tpl_snippet = '''
1428         policies:
1429           - servers_placement:
1430               type: tosca.policies.Placement
1431               testkey: testvalue
1432         '''
1433         policies = (toscaparser.utils.yamlparser.
1434                     simple_parse(tpl_snippet))['policies'][0]
1435         name = list(policies.keys())[0]
1436
1437         expectedmessage = _('Policy "servers_placement" contains '
1438                             'unknown field "testkey". Refer to the '
1439                             'definition to verify valid values.')
1440         err = self.assertRaises(
1441             exception.UnknownFieldError,
1442             lambda: Policy(name, policies[name], None, None))
1443         self.assertEqual(expectedmessage, err.__str__())
1444
1445     def test_policy_trigger_valid_keyname(self):
1446         tpl_snippet = '''
1447         triggers:
1448          - resize_compute:
1449              description: trigger
1450              event_type: tosca.events.resource.utilization
1451              schedule:
1452                start_time: "2015-05-07T07:00:00Z"
1453                end_time: "2015-06-07T07:00:00Z"
1454              target_filter:
1455                node: master-container
1456                requirement: host
1457                capability: Container
1458              condition:
1459                constraint: utilization greater_than 50%
1460                period: 60
1461                evaluations: 1
1462                method : average
1463              action:
1464                resize: # Operation name
1465                 inputs:
1466                  strategy: LEAST_USED
1467                  implementation: Senlin.webhook()
1468         '''
1469         triggers = (toscaparser.utils.yamlparser.
1470                     simple_parse(tpl_snippet))['triggers'][0]
1471         name = list(triggers.keys())[0]
1472         Triggers(name, triggers[name])
1473
1474     def test_policy_trigger_invalid_keyname(self):
1475         tpl_snippet = '''
1476         triggers:
1477          - resize_compute:
1478              description: trigger
1479              event_type: tosca.events.resource.utilization
1480              schedule:
1481                start_time: "2015-05-07T07:00:00Z"
1482                end_time: "2015-06-07T07:00:00Z"
1483              target_filter1:
1484                node: master-container
1485                requirement: host
1486                capability: Container
1487              condition:
1488                constraint: utilization greater_than 50%
1489                period1: 60
1490                evaluations: 1
1491                method: average
1492              action:
1493                resize: # Operation name
1494                 inputs:
1495                  strategy: LEAST_USED
1496                  implementation: Senlin.webhook()
1497         '''
1498         triggers = (toscaparser.utils.yamlparser.
1499                     simple_parse(tpl_snippet))['triggers'][0]
1500         name = list(triggers.keys())[0]
1501         expectedmessage = _(
1502             'Triggers "resize_compute" contains unknown field '
1503             '"target_filter1". Refer to the definition '
1504             'to verify valid values.')
1505         err = self.assertRaises(
1506             exception.UnknownFieldError,
1507             lambda: Triggers(name, triggers[name]))
1508         self.assertEqual(expectedmessage, err.__str__())
1509
1510     def test_policy_missing_required_keyname(self):
1511         tpl_snippet = '''
1512         policies:
1513           - servers_placement:
1514               description: test description
1515         '''
1516         policies = (toscaparser.utils.yamlparser.
1517                     simple_parse(tpl_snippet))['policies'][0]
1518         name = list(policies.keys())[0]
1519
1520         expectedmessage = _('Template "servers_placement" is missing '
1521                             'required field "type".')
1522         err = self.assertRaises(
1523             exception.MissingRequiredFieldError,
1524             lambda: Policy(name, policies[name], None, None))
1525         self.assertEqual(expectedmessage, err.__str__())
1526
1527     def test_credential_datatype(self):
1528         tosca_tpl = os.path.join(
1529             os.path.dirname(os.path.abspath(__file__)),
1530             "data/test_credential_datatype.yaml")
1531         self.assertIsNotNone(ToscaTemplate(tosca_tpl))
1532
1533     def test_invalid_default_value(self):
1534         tpl_path = os.path.join(
1535             os.path.dirname(os.path.abspath(__file__)),
1536             "data/test_invalid_input_defaults.yaml")
1537         self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
1538         exception.ExceptionCollector.assertExceptionMessage(
1539             ValueError, _('"two" is not an integer.'))
1540
1541     def test_invalid_capability(self):
1542         tpl_snippet = '''
1543         node_templates:
1544           server:
1545             type: tosca.nodes.Compute
1546             capabilities:
1547                 oss:
1548                     properties:
1549                         architecture: x86_64
1550         '''
1551         tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
1552         err = self.assertRaises(exception.UnknownFieldError,
1553                                 TopologyTemplate, tpl, None)
1554         expectedmessage = _('"capabilities" of template "server" contains '
1555                             'unknown field "oss". Refer to the definition '
1556                             'to verify valid values.')
1557         self.assertEqual(expectedmessage, err.__str__())