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