1 # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 # not use this file except in compliance with the License. You may obtain
3 # a copy of the License at
5 # http://www.apache.org/licenses/LICENSE-2.0
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 # License for the specific language governing permissions and limitations
16 from toscaparser.common import exception
17 from toscaparser.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
32 class ToscaTemplateValidationTest(TestCase):
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 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
39 'db_root_pwd': '12345678'}
40 self.assertIsNotNone(ToscaTemplate(tpl_path, params))
42 def test_custom_interface_allowed(self):
43 tpl_path = os.path.join(
44 os.path.dirname(os.path.abspath(__file__)),
45 "data/interfaces/test_custom_interface_in_template.yaml")
46 self.assertIsNotNone(ToscaTemplate(tpl_path))
48 def test_custom_interface_invalid_operation(self):
49 tpl_path = os.path.join(
50 os.path.dirname(os.path.abspath(__file__)),
51 "data/interfaces/test_custom_interface_invalid_operation.yaml")
52 self.assertRaises(exception.ValidationError,
53 ToscaTemplate, tpl_path)
54 exception.ExceptionCollector.assertExceptionMessage(
55 exception.UnknownFieldError,
56 _('"interfaces" of template "customInterfaceTest" '
57 'contains unknown field "CustomOp4". '
58 'Refer to the definition to verify valid values.'))
60 def test_first_level_sections(self):
61 tpl_path = os.path.join(
62 os.path.dirname(os.path.abspath(__file__)),
63 "data/test_tosca_top_level_error1.yaml")
64 self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
65 exception.ExceptionCollector.assertExceptionMessage(
66 exception.MissingRequiredFieldError,
67 _('Template is missing required field '
68 '"tosca_definitions_version".'))
70 tpl_path = os.path.join(
71 os.path.dirname(os.path.abspath(__file__)),
72 "data/test_tosca_top_level_error2.yaml")
73 self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
74 exception.ExceptionCollector.assertExceptionMessage(
75 exception.UnknownFieldError,
76 _('Template contains unknown field "node_template". Refer to the '
77 'definition to verify valid values.'))
79 def test_template_with_imports_validation(self):
80 tpl_path = os.path.join(
81 os.path.dirname(os.path.abspath(__file__)),
82 "data/tosca_imports_validation.yaml")
83 self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
84 exception.ExceptionCollector.assertExceptionMessage(
85 exception.UnknownFieldError,
86 _('Template custom_types/imported_sample.yaml contains unknown '
87 'field "descriptions". Refer to the definition'
88 ' to verify valid values.'))
89 exception.ExceptionCollector.assertExceptionMessage(
90 exception.UnknownFieldError,
91 _('Template custom_types/imported_sample.yaml contains unknown '
92 'field "node_typess". Refer to the definition to '
93 'verify valid values.'))
94 exception.ExceptionCollector.assertExceptionMessage(
95 exception.UnknownFieldError,
96 _('Template custom_types/imported_sample.yaml contains unknown '
97 'field "tosca1_definitions_version". Refer to the definition'
98 ' to verify valid values.'))
99 exception.ExceptionCollector.assertExceptionMessage(
100 exception.InvalidTemplateVersion,
101 _('The template version "tosca_simple_yaml_1_10 in '
102 'custom_types/imported_sample.yaml" is invalid. '
103 'Valid versions are "tosca_simple_yaml_1_0, '
104 'tosca_simple_profile_for_nfv_1_0_0".'))
105 exception.ExceptionCollector.assertExceptionMessage(
106 exception.UnknownFieldError,
107 _('Template custom_types/imported_sample.yaml contains unknown '
108 'field "policy_types1". Refer to the definition to '
109 'verify valid values.'))
110 exception.ExceptionCollector.assertExceptionMessage(
111 exception.UnknownFieldError,
112 _('Nodetype"tosca.nodes.SoftwareComponent.Logstash" contains '
113 'unknown field "capabilities1". Refer to the definition '
114 'to verify valid values.'))
115 exception.ExceptionCollector.assertExceptionMessage(
116 exception.UnknownFieldError,
117 _('Policy "mycompany.mytypes.myScalingPolicy" contains unknown '
118 'field "derived1_from". Refer to the definition to '
119 'verify valid values.'))
120 exception.ExceptionCollector.assertExceptionMessage(
121 exception.UnknownFieldError,
122 _('Relationshiptype "test.relation.connects" contains unknown '
123 'field "derived_from4". Refer to the definition to '
124 'verify valid values.'))
126 def test_getoperation_IncorrectValue(self):
131 type: tosca.nodes.Compute
135 implementation: scripts/frontend/create.sh
137 implementation: scripts/frontend/configure.sh
139 data_dir: {get_operation_output: [front_end,Standard1,
142 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
143 err = self.assertRaises(ValueError,
144 TopologyTemplate, tpl, None)
145 expectedmessage = _('Enter a valid interface name')
146 self.assertEqual(expectedmessage, err.__str__())
151 type: tosca.nodes.Compute
155 implementation: scripts/frontend/create.sh
157 implementation: scripts/frontend/configure.sh
159 data_dir: {get_operation_output: [front_end1,Standard,
162 tpl2 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet2))
163 err2 = self.assertRaises(KeyError,
164 TopologyTemplate, tpl2, None)
165 expectedmessage2 = _('\'Node template "front_end1" was not found.\'')
166 self.assertEqual(expectedmessage2, err2.__str__())
171 type: tosca.nodes.Compute
175 implementation: scripts/frontend/create.sh
177 implementation: scripts/frontend/configure.sh
179 data_dir: {get_operation_output: [front_end,Standard,
180 get_target,data_dir]}
182 tpl3 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet3))
183 err3 = self.assertRaises(ValueError,
184 TopologyTemplate, tpl3, None)
185 expectedmessage3 = _('Enter an operation of Standard interface')
186 self.assertEqual(expectedmessage3, err3.__str__())
191 type: tosca.nodes.Compute
195 implementation: scripts/frontend/create.sh
197 implementation: scripts/frontend/configure.sh
199 data_dir: {get_operation_output: [front_end,Configure,
202 tpl4 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet4))
203 err4 = self.assertRaises(ValueError,
204 TopologyTemplate, tpl4, None)
205 expectedmessage4 = _('Enter an operation of Configure interface')
206 self.assertEqual(expectedmessage4, err4.__str__())
211 type: tosca.nodes.Compute
215 implementation: scripts/frontend/create.sh
217 implementation: scripts/frontend/configure.sh
219 data_dir: {get_operation_output: [front_end,Standard,
222 tpl5 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet5))
223 err5 = self.assertRaises(ValueError,
224 TopologyTemplate, tpl5, None)
225 expectedmessage5 = _('Illegal arguments for function'
226 ' "get_operation_output".'
227 ' Expected arguments: "template_name",'
229 '"operation_name","output_variable_name"')
230 self.assertEqual(expectedmessage5, err5.__str__())
232 def test_unsupported_type(self):
236 type: tosca.test.invalidtype
238 size: { get_input: storage_size }
239 snapshot_id: { get_input: storage_snapshot_id }
241 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
242 err = self.assertRaises(exception.UnsupportedTypeError,
243 TopologyTemplate, tpl, None)
244 expectedmessage = _('Type "tosca.test.invalidtype" is valid'
245 ' TOSCA type but not supported at this time.')
246 self.assertEqual(expectedmessage, err.__str__())
248 def test_inputs(self):
253 description: Number of CPUs for the server.
255 - valid_values: [ 1, 2, 4 ]
263 description: Number of CPUs for the server.
265 - valid_values: [ 1, 2, 4 ]
273 description: List of items
278 inputs1 = (toscaparser.utils.yamlparser.
279 simple_parse(tpl_snippet1)['inputs'])
280 name1, attrs1 = list(inputs1.items())[0]
281 inputs2 = (toscaparser.utils.yamlparser.
282 simple_parse(tpl_snippet2)['inputs'])
283 name2, attrs2 = list(inputs2.items())[0]
286 except Exception as err:
287 self.assertEqual(_('Input "cpus" contains unknown field '
288 '"constraint". Refer to the definition to '
289 'verify valid values.'),
291 input2 = Input(name2, attrs2)
292 self.assertTrue(input2.required)
293 toscaparser.utils.yamlparser.simple_parse(tpl_snippet3)['inputs']
295 def _imports_content_test(self, tpl_snippet, path, custom_type_def):
296 imports = (toscaparser.utils.yamlparser.
297 simple_parse(tpl_snippet)['imports'])
298 loader = ImportsLoader(imports, path, custom_type_def)
299 return loader.get_custom_defs()
301 def test_imports_without_templates(self):
304 # omitted here for brevity
306 path = 'toscaparser/tests/data/tosca_elk.yaml'
307 errormsg = _('"imports" keyname is defined without including '
309 err = self.assertRaises(exception.ValidationError,
310 self._imports_content_test,
314 self.assertEqual(errormsg, err.__str__())
316 def test_imports_with_name_without_templates(self):
321 path = 'toscaparser/tests/data/tosca_elk.yaml'
322 errormsg = _('A template file name is not provided with import '
323 'definition "some_definitions".')
324 err = self.assertRaises(exception.ValidationError,
325 self._imports_content_test,
326 tpl_snippet, path, None)
327 self.assertEqual(errormsg, err.__str__())
329 def test_imports_without_import_name(self):
332 - custom_types/paypalpizzastore_nodejs_app.yaml
333 - https://raw.githubusercontent.com/openstack/\
334 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
336 path = 'toscaparser/tests/data/tosca_elk.yaml'
337 custom_defs = self._imports_content_test(tpl_snippet,
340 self.assertTrue(custom_defs)
342 def test_imports_wth_import_name(self):
345 - some_definitions: custom_types/paypalpizzastore_nodejs_app.yaml
347 file: 'https://raw.githubusercontent.com/openstack/tosca-parser\
348 /master/toscaparser/tests/data/custom_types/wordpress.yaml'
349 namespace_prefix: single_instance_wordpress
351 path = 'toscaparser/tests/data/tosca_elk.yaml'
352 custom_defs = self._imports_content_test(tpl_snippet,
355 self.assertTrue(custom_defs.get("single_instance_wordpress.tosca."
356 "nodes.WebApplication.WordPress"))
358 def test_imports_wth_namespace_prefix(self):
362 file: custom_types/nested_rsyslog.yaml
363 namespace_prefix: testprefix
365 path = 'toscaparser/tests/data/tosca_elk.yaml'
366 custom_defs = self._imports_content_test(tpl_snippet,
369 self.assertTrue(custom_defs.get("testprefix.Rsyslog"))
371 def test_imports_with_no_main_template(self):
374 - some_definitions: https://raw.githubusercontent.com/openstack/\
375 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
377 file: my_defns/my_typesdefs_n.yaml
379 errormsg = _('Input tosca template is not provided.')
380 err = self.assertRaises(exception.ValidationError,
381 self._imports_content_test,
382 tpl_snippet, None, None)
383 self.assertEqual(errormsg, err.__str__())
385 def test_imports_duplicate_name(self):
388 - some_definitions: https://raw.githubusercontent.com/openstack/\
389 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
391 file: my_defns/my_typesdefs_n.yaml
393 errormsg = _('Duplicate import name "some_definitions" was found.')
394 path = 'toscaparser/tests/data/tosca_elk.yaml'
395 err = self.assertRaises(exception.ValidationError,
396 self._imports_content_test,
397 tpl_snippet, path, None)
398 self.assertEqual(errormsg, err.__str__())
400 def test_imports_missing_req_field_in_def(self):
404 file1: my_defns/my_typesdefs_n.yaml
405 repository: my_company_repo
406 namespace_uri: http://mycompany.com/ns/tosca/2.0
407 namespace_prefix: mycompany
409 errormsg = _('Import of template "more_definitions" is missing '
410 'required field "file".')
411 path = 'toscaparser/tests/data/tosca_elk.yaml'
412 err = self.assertRaises(exception.MissingRequiredFieldError,
413 self._imports_content_test,
414 tpl_snippet, path, None)
415 self.assertEqual(errormsg, err.__str__())
417 def test_imports_file_with_uri(self):
421 file: https://raw.githubusercontent.com/openstack/\
422 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
424 path = 'https://raw.githubusercontent.com/openstack/\
425 tosca-parser/master/toscaparser/tests/data/\
426 tosca_single_instance_wordpress_with_url_import.yaml'
427 custom_defs = self._imports_content_test(tpl_snippet,
430 self.assertTrue(custom_defs.get("tosca.nodes."
431 "WebApplication.WordPress"))
433 def test_imports_file_namespace_fields(self):
437 file: https://raw.githubusercontent.com/openstack/\
438 heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
439 namespace_prefix: mycompany
440 namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0
442 path = 'toscaparser/tests/data/tosca_elk.yaml'
443 custom_defs = self._imports_content_test(tpl_snippet,
446 self.assertTrue(custom_defs.get("mycompany.tosca.nodes."
447 "WebApplication.WordPress"))
449 def test_import_error_file_uri(self):
453 file: mycompany.com/ns/tosca/2.0/toscaparser/tests/data\
455 namespace_prefix: mycompany
456 namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0
458 path = 'toscaparser/tests/data/tosca_elk.yaml'
459 self.assertRaises(ImportError,
460 self._imports_content_test,
461 tpl_snippet, path, None)
463 def test_import_single_line_error(self):
466 - some_definitions: abc.com/tests/data/tosca_elk.yaml
468 errormsg = _('Import "abc.com/tests/data/tosca_elk.yaml" is not '
470 path = 'toscaparser/tests/data/tosca_elk.yaml'
471 err = self.assertRaises(ImportError,
472 self._imports_content_test,
473 tpl_snippet, path, None)
474 self.assertEqual(errormsg, err.__str__())
476 def test_outputs(self):
480 description: IP address of server instance.
481 values: { get_property: [server, private_address] }
483 outputs = (toscaparser.utils.yamlparser.
484 simple_parse(tpl_snippet)['outputs'])
485 name, attrs = list(outputs.items())[0]
486 output = Output(name, attrs)
489 except Exception as err:
491 isinstance(err, exception.MissingRequiredFieldError))
492 self.assertEqual(_('Output "server_address" is missing required '
493 'field "value".'), err.__str__())
498 descriptions: IP address of server instance.
499 value: { get_property: [server, private_address] }
501 outputs = (toscaparser.utils.yamlparser.
502 simple_parse(tpl_snippet)['outputs'])
503 name, attrs = list(outputs.items())[0]
504 output = Output(name, attrs)
507 except Exception as err:
508 self.assertIsInstance(err, exception.UnknownFieldError)
509 self.assertEqual(_('Output "server_address" contains unknown '
510 'field "descriptions". Refer to the definition '
511 'to verify valid values.'),
514 def _repo_content(self, path):
515 repositories = path['repositories']
517 for name, val in repositories.items():
518 reposits = Repository(name, val)
519 reposit.append(reposits)
522 def test_repositories(self):
525 repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
527 description: My project's code Repository in github usercontent.
528 url: https://github.com/nandinivemula/intern
533 description: My Project's code Repository in github.
534 url: https://github.com/nandinivemula/intern
539 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
540 repoobject = self._repo_content(tpl)
541 actualrepo_names = []
542 for repo in repoobject:
544 actualrepo_names.append(repos)
545 reposname = list(tpl.values())
546 reposnames = reposname[0]
547 expected_reponames = list(reposnames.keys())
548 self.assertEqual(expected_reponames, actualrepo_names)
550 def test_repositories_with_missing_required_field(self):
553 repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
555 description: My project's code Repository in github usercontent.
560 description: My Project's code Repository in github.
561 url: https://github.com/nandinivemula/intern
566 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
567 err = self.assertRaises(exception.MissingRequiredFieldError,
568 self._repo_content, tpl)
569 expectedmessage = _('Repository "repo_code1" is missing '
570 'required field "url".')
571 self.assertEqual(expectedmessage, err.__str__())
573 def test_repositories_with_unknown_field(self):
576 repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
578 description: My project's code Repository in github usercontent.
579 url: https://github.com/nandinivemula/intern
584 descripton: My Project's code Repository in github.
585 url: https://github.com/nandinivemula/intern
590 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
591 err = self.assertRaises(exception.UnknownFieldError,
592 self._repo_content, tpl)
593 expectedmessage = _('repositories "repo_code2" contains unknown field'
594 ' "descripton". Refer to the definition to verify'
596 self.assertEqual(expectedmessage, err.__str__())
598 def test_repositories_with_invalid_url(self):
601 repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
603 description: My project's code Repository in github usercontent.
609 description: My Project's code Repository in github.
610 url: https://github.com/nandinivemula/intern
615 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
616 err = self.assertRaises(exception.URLException,
617 self._repo_content, tpl)
618 expectedmessage = _('repsositories "repo_code1" Invalid Url')
619 self.assertEqual(expectedmessage, err.__str__())
621 def test_groups(self):
625 type: tosca.nodes.Compute
628 capability: log_endpoint
631 type: tosca.nodes.DBMS
638 type: tosca.groups.Root
639 members: [ server, mysql_dbms ]
641 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
642 TopologyTemplate(tpl, None)
644 def test_groups_with_missing_required_field(self):
648 type: tosca.nodes.Compute
651 capability: log_endpoint
654 type: tosca.nodes.DBMS
661 members: ['server', 'mysql_dbms']
663 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
664 err = self.assertRaises(exception.MissingRequiredFieldError,
665 TopologyTemplate, tpl, None)
666 expectedmessage = _('Template "webserver_group" is missing '
667 'required field "type".')
668 self.assertEqual(expectedmessage, err.__str__())
670 def test_groups_with_unknown_target(self):
674 type: tosca.nodes.Compute
677 capability: log_endpoint
680 type: tosca.nodes.DBMS
687 type: tosca.groups.Root
688 members: [ serv, mysql_dbms ]
690 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
691 expectedmessage = _('"Target member "serv" is not found in '
693 err = self.assertRaises(exception.InvalidGroupTargetException,
694 TopologyTemplate, tpl, None)
695 self.assertEqual(expectedmessage, err.__str__())
697 def test_groups_with_repeated_targets(self):
701 type: tosca.nodes.Compute
704 capability: log_endpoint
707 type: tosca.nodes.DBMS
714 type: tosca.groups.Root
715 members: [ server, server, mysql_dbms ]
717 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
718 expectedmessage = _('"Member nodes '
719 '"[\'server\', \'server\', \'mysql_dbms\']" '
720 'should be >= 1 and not repeated"')
721 err = self.assertRaises(exception.InvalidGroupTargetException,
722 TopologyTemplate, tpl, None)
723 self.assertEqual(expectedmessage, err.__str__())
725 def test_groups_with_only_one_target(self):
729 type: tosca.nodes.Compute
732 capability: log_endpoint
735 type: tosca.nodes.DBMS
742 type: tosca.groups.Root
745 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
746 expectedmessage = _('"Member nodes "[]" should be >= 1 '
748 err = self.assertRaises(exception.InvalidGroupTargetException,
749 TopologyTemplate, tpl, None)
750 self.assertEqual(expectedmessage, err.__str__())
752 def _custom_types(self):
754 def_file = os.path.join(
755 os.path.dirname(os.path.abspath(__file__)),
756 "data/custom_types/wordpress.yaml")
757 custom_type = toscaparser.utils.yamlparser.load_yaml(def_file)
758 node_types = custom_type['node_types']
759 for name in node_types:
760 defintion = node_types[name]
761 custom_types[name] = defintion
764 def _single_node_template_content_test(self, tpl_snippet):
765 nodetemplates = (toscaparser.utils.yamlparser.
766 simple_ordered_parse(tpl_snippet))['node_templates']
767 name = list(nodetemplates.keys())[0]
768 nodetemplate = NodeTemplate(name, nodetemplates,
769 self._custom_types())
770 nodetemplate.validate()
771 nodetemplate.requirements
772 nodetemplate.get_capabilities_objects()
773 nodetemplate.get_properties_objects()
774 nodetemplate.interfaces
776 def test_node_templates(self):
793 expectedmessage = _('Template "server" is missing required field '
795 err = self.assertRaises(
796 exception.MissingRequiredFieldError,
797 lambda: self._single_node_template_content_test(tpl_snippet))
798 self.assertEqual(expectedmessage, err.__str__())
800 def test_node_template_with_wrong_properties_keyname(self):
801 """Node template keyname 'properties' given as 'propertiessss'."""
805 type: tosca.nodes.DBMS
810 expectedmessage = _('Node template "mysql_dbms" contains unknown '
811 'field "propertiessss". Refer to the definition '
812 'to verify valid values.')
813 err = self.assertRaises(
814 exception.UnknownFieldError,
815 lambda: self._single_node_template_content_test(tpl_snippet))
816 self.assertEqual(expectedmessage, err.__str__())
818 def test_node_template_with_wrong_requirements_keyname(self):
819 """Node template keyname 'requirements' given as 'requirement'."""
823 type: tosca.nodes.DBMS
830 expectedmessage = _('Node template "mysql_dbms" contains unknown '
831 'field "requirement". Refer to the definition to '
832 'verify valid values.')
833 err = self.assertRaises(
834 exception.UnknownFieldError,
835 lambda: self._single_node_template_content_test(tpl_snippet))
836 self.assertEqual(expectedmessage, err.__str__())
838 def test_node_template_with_wrong_interfaces_keyname(self):
839 """Node template keyname 'interfaces' given as 'interfac'."""
843 type: tosca.nodes.DBMS
851 configure: mysql_database_configure.sh
853 expectedmessage = _('Node template "mysql_dbms" contains unknown '
854 'field "interfac". Refer to the definition to '
855 'verify valid values.')
856 err = self.assertRaises(
857 exception.UnknownFieldError,
858 lambda: self._single_node_template_content_test(tpl_snippet))
859 self.assertEqual(expectedmessage, err.__str__())
861 def test_node_template_with_wrong_capabilities_keyname(self):
862 """Node template keyname 'capabilities' given as 'capabilitiis'."""
866 type: tosca.nodes.Database
868 db_name: { get_input: db_name }
869 db_user: { get_input: db_user }
870 db_password: { get_input: db_pwd }
874 port: { get_input: db_port }
876 expectedmessage = _('Node template "mysql_database" contains unknown '
877 'field "capabilitiis". Refer to the definition to '
878 'verify valid values.')
879 err = self.assertRaises(
880 exception.UnknownFieldError,
881 lambda: self._single_node_template_content_test(tpl_snippet))
882 self.assertEqual(expectedmessage, err.__str__())
884 def test_node_template_with_wrong_artifacts_keyname(self):
885 """Node template keyname 'artifacts' given as 'artifactsss'."""
889 type: tosca.nodes.Database
892 implementation: files/my_db_content.txt
893 type: tosca.artifacts.File
895 expectedmessage = _('Node template "mysql_database" contains unknown '
896 'field "artifactsss". Refer to the definition to '
897 'verify valid values.')
898 err = self.assertRaises(
899 exception.UnknownFieldError,
900 lambda: self._single_node_template_content_test(tpl_snippet))
901 self.assertEqual(expectedmessage, err.__str__())
903 def test_node_template_with_multiple_wrong_keynames(self):
904 """Node templates given with multiple wrong keynames."""
908 type: tosca.nodes.DBMS
916 configure: mysql_database_configure.sh
918 expectedmessage = _('Node template "mysql_dbms" contains unknown '
919 'field "propertieees". Refer to the definition to '
920 'verify valid values.')
921 err = self.assertRaises(
922 exception.UnknownFieldError,
923 lambda: self._single_node_template_content_test(tpl_snippet))
924 self.assertEqual(expectedmessage, err.__str__())
929 type: tosca.nodes.Database
931 name: { get_input: db_name }
932 user: { get_input: db_user }
933 password: { get_input: db_pwd }
937 port: { get_input: db_port }
943 configure: mysql_database_configure.sh
946 expectedmessage = _('Node template "mysql_database" contains unknown '
947 'field "capabilitiiiies". Refer to the definition '
948 'to verify valid values.')
949 err = self.assertRaises(
950 exception.UnknownFieldError,
951 lambda: self._single_node_template_content_test(tpl_snippet))
952 self.assertEqual(expectedmessage, err.__str__())
954 def test_node_template_type(self):
958 type: tosca.nodes.Databases
960 db_name: { get_input: db_name }
961 db_user: { get_input: db_user }
962 db_password: { get_input: db_pwd }
966 port: { get_input: db_port }
971 configure: mysql_database_configure.sh
973 expectedmessage = _('Type "tosca.nodes.Databases" is not '
975 err = self.assertRaises(
976 exception.InvalidTypeError,
977 lambda: self._single_node_template_content_test(tpl_snippet))
978 self.assertEqual(expectedmessage, err.__str__())
980 def test_node_template_requirements(self):
984 type: tosca.nodes.WebServer
989 create: webserver_install.sh
992 expectedmessage = _('"requirements" of template "webserver" must be '
994 err = self.assertRaises(
995 exception.TypeMismatchError,
996 lambda: self._single_node_template_content_test(tpl_snippet))
997 self.assertEqual(expectedmessage, err.__str__())
1002 type: tosca.nodes.Database
1004 db_name: { get_input: db_name }
1005 db_user: { get_input: db_user }
1006 db_password: { get_input: db_pwd }
1010 port: { get_input: db_port }
1013 - database_endpoint: mysql_database
1016 configure: mysql_database_configure.sh
1018 expectedmessage = _('"requirements" of template "mysql_database" '
1019 'contains unknown field "database_endpoint". '
1020 'Refer to the definition to verify valid values.')
1021 err = self.assertRaises(
1022 exception.UnknownFieldError,
1023 lambda: self._single_node_template_content_test(tpl_snippet))
1024 self.assertEqual(expectedmessage, err.__str__())
1026 def test_node_template_requirements_with_wrong_node_keyname(self):
1027 """Node template requirements keyname 'node' given as 'nodes'."""
1031 type: tosca.nodes.Database
1037 expectedmessage = _('"requirements" of template "mysql_database" '
1038 'contains unknown field "nodes". Refer to the '
1039 'definition to verify valid values.')
1040 err = self.assertRaises(
1041 exception.UnknownFieldError,
1042 lambda: self._single_node_template_content_test(tpl_snippet))
1043 self.assertEqual(expectedmessage, err.__str__())
1045 def test_node_template_requirements_with_wrong_capability_keyname(self):
1046 """Incorrect node template requirements keyname
1048 Node template requirements keyname 'capability' given as
1054 type: tosca.nodes.Database
1060 capabilityy: log_endpoint
1062 type: tosca.relationships.ConnectsTo
1065 expectedmessage = _('"requirements" of template "mysql_database" '
1066 'contains unknown field "capabilityy". Refer to '
1067 'the definition to verify valid values.')
1068 err = self.assertRaises(
1069 exception.UnknownFieldError,
1070 lambda: self._single_node_template_content_test(tpl_snippet))
1071 self.assertEqual(expectedmessage, err.__str__())
1073 def test_node_template_requirements_with_wrong_relationship_keyname(self):
1074 """Incorrect node template requirements keyname
1076 Node template requirements keyname 'relationship' given as
1082 type: tosca.nodes.Database
1088 capability: log_endpoint
1090 type: tosca.relationships.ConnectsTo
1093 expectedmessage = _('"requirements" of template "mysql_database" '
1094 'contains unknown field "relationshipppp". Refer '
1095 'to the definition to verify valid values.')
1096 err = self.assertRaises(
1097 exception.UnknownFieldError,
1098 lambda: self._single_node_template_content_test(tpl_snippet))
1099 self.assertEqual(expectedmessage, err.__str__())
1101 def test_node_template_requirements_with_wrong_occurrences_keyname(self):
1102 """Incorrect node template requirements keyname
1104 Node template requirements keyname 'occurrences' given as
1110 type: tosca.nodes.Database
1116 capability: log_endpoint
1118 type: tosca.relationships.ConnectsTo
1119 occurences: [0, UNBOUNDED]
1121 expectedmessage = _('"requirements" of template "mysql_database" '
1122 'contains unknown field "occurences". Refer to '
1123 'the definition to verify valid values.')
1124 err = self.assertRaises(
1125 exception.UnknownFieldError,
1126 lambda: self._single_node_template_content_test(tpl_snippet))
1127 self.assertEqual(expectedmessage, err.__str__())
1129 def test_node_template_requirements_with_multiple_wrong_keynames(self):
1130 """Node templates given with multiple wrong requirements keynames."""
1134 type: tosca.nodes.Database
1140 capabilit: log_endpoint
1142 type: tosca.relationships.ConnectsTo
1145 expectedmessage = _('"requirements" of template "mysql_database" '
1146 'contains unknown field "nod". Refer to the '
1147 'definition to verify valid values.')
1148 err = self.assertRaises(
1149 exception.UnknownFieldError,
1150 lambda: self._single_node_template_content_test(tpl_snippet))
1151 self.assertEqual(expectedmessage, err.__str__())
1156 type: tosca.nodes.Database
1162 capabilit: log_endpoint
1164 type: tosca.relationships.ConnectsTo
1167 expectedmessage = _('"requirements" of template "mysql_database" '
1168 'contains unknown field "capabilit". Refer to the '
1169 'definition to verify valid values.')
1170 err = self.assertRaises(
1171 exception.UnknownFieldError,
1172 lambda: self._single_node_template_content_test(tpl_snippet))
1173 self.assertEqual(expectedmessage, err.__str__())
1175 def test_node_template_requirements_invalid_occurrences(self):
1179 type: tosca.nodes.Compute
1182 capability: log_endpoint
1183 occurrences: [0, -1]
1185 expectedmessage = _('Value of property "[0, -1]" is invalid.')
1186 err = self.assertRaises(
1187 exception.InvalidPropertyValueError,
1188 lambda: self._single_node_template_content_test(tpl_snippet))
1189 self.assertEqual(expectedmessage, err.__str__())
1194 type: tosca.nodes.Compute
1197 capability: log_endpoint
1200 expectedmessage = _('"a" is not an integer.')
1201 err = self.assertRaises(
1203 lambda: self._single_node_template_content_test(tpl_snippet))
1204 self.assertEqual(expectedmessage, err.__str__())
1209 type: tosca.nodes.Compute
1212 capability: log_endpoint
1215 expectedmessage = _('"-1" is not a list.')
1216 err = self.assertRaises(
1218 lambda: self._single_node_template_content_test(tpl_snippet))
1219 self.assertEqual(expectedmessage, err.__str__())
1224 type: tosca.nodes.Compute
1227 capability: log_endpoint
1230 expectedmessage = _('Value of property "[5, 1]" is invalid.')
1231 err = self.assertRaises(
1232 exception.InvalidPropertyValueError,
1233 lambda: self._single_node_template_content_test(tpl_snippet))
1234 self.assertEqual(expectedmessage, err.__str__())
1239 type: tosca.nodes.Compute
1242 capability: log_endpoint
1245 expectedmessage = _('Value of property "[0, 0]" is invalid.')
1246 err = self.assertRaises(
1247 exception.InvalidPropertyValueError,
1248 lambda: self._single_node_template_content_test(tpl_snippet))
1249 self.assertEqual(expectedmessage, err.__str__())
1251 def test_node_template_requirements_valid_occurrences(self):
1255 type: tosca.nodes.Compute
1258 capability: log_endpoint
1261 self._single_node_template_content_test(tpl_snippet)
1263 def test_node_template_capabilities(self):
1267 type: tosca.nodes.Database
1269 db_name: { get_input: db_name }
1270 db_user: { get_input: db_user }
1271 db_password: { get_input: db_pwd }
1275 port: { get_input: db_port }
1280 configure: mysql_database_configure.sh
1282 expectedmessage = _('"capabilities" of template "mysql_database" '
1283 'contains unknown field "http_endpoint". Refer to '
1284 'the definition to verify valid values.')
1285 err = self.assertRaises(
1286 exception.UnknownFieldError,
1287 lambda: self._single_node_template_content_test(tpl_snippet))
1288 self.assertEqual(expectedmessage, err.__str__())
1290 def test_node_template_properties(self):
1294 type: tosca.nodes.Compute
1296 os_image: F18_x86_64
1301 num_cpus: { get_input: cpus }
1305 architecture: x86_64
1307 distribution: Fedora
1310 expectedmessage = _('"properties" of template "server" contains '
1311 'unknown field "os_image". Refer to the '
1312 'definition to verify valid values.')
1313 err = self.assertRaises(
1314 exception.UnknownFieldError,
1315 lambda: self._single_node_template_content_test(tpl_snippet))
1316 self.assertEqual(expectedmessage, err.__str__())
1318 def test_node_template_interfaces(self):
1322 type: tosca.nodes.WebApplication.WordPress
1325 - database_endpoint: mysql_database
1328 create: wordpress_install.sh
1330 implementation: wordpress_configure.sh
1332 wp_db_name: { get_property: [ mysql_database, db_name ] }
1333 wp_db_user: { get_property: [ mysql_database, db_user ] }
1334 wp_db_password: { get_property: [ mysql_database, \
1336 wp_db_port: { get_property: [ SELF, \
1337 database_endpoint, port ] }
1339 expectedmessage = _('"interfaces" of template "wordpress" contains '
1340 'unknown field "Standards". Refer to the '
1341 'definition to verify valid values.')
1342 err = self.assertRaises(
1343 exception.UnknownFieldError,
1344 lambda: self._single_node_template_content_test(tpl_snippet))
1345 self.assertEqual(expectedmessage, err.__str__())
1350 type: tosca.nodes.WebApplication.WordPress
1353 - database_endpoint: mysql_database
1356 create: wordpress_install.sh
1358 implementation: wordpress_configure.sh
1360 wp_db_name: { get_property: [ mysql_database, db_name ] }
1361 wp_db_user: { get_property: [ mysql_database, db_user ] }
1362 wp_db_password: { get_property: [ mysql_database, \
1364 wp_db_port: { get_property: [ SELF, \
1365 database_endpoint, port ] }
1367 expectedmessage = _('"interfaces" of template "wordpress" contains '
1368 'unknown field "config". Refer to the definition '
1369 'to verify valid values.')
1370 err = self.assertRaises(
1371 exception.UnknownFieldError,
1372 lambda: self._single_node_template_content_test(tpl_snippet))
1373 self.assertEqual(expectedmessage, err.__str__())
1378 type: tosca.nodes.WebApplication.WordPress
1381 - database_endpoint: mysql_database
1384 create: wordpress_install.sh
1386 implementation: wordpress_configure.sh
1388 wp_db_name: { get_property: [ mysql_database, db_name ] }
1389 wp_db_user: { get_property: [ mysql_database, db_user ] }
1390 wp_db_password: { get_property: [ mysql_database, \
1392 wp_db_port: { get_ref_property: [ database_endpoint, \
1393 database_endpoint, port ] }
1395 expectedmessage = _('"interfaces" of template "wordpress" contains '
1396 'unknown field "input". Refer to the definition '
1397 'to verify valid values.')
1398 err = self.assertRaises(
1399 exception.UnknownFieldError,
1400 lambda: self._single_node_template_content_test(tpl_snippet))
1401 self.assertEqual(expectedmessage, err.__str__())
1403 def test_relationship_template_properties(self):
1405 relationship_templates:
1411 expectedmessage = _('"properties" of template "storage_attachto" is '
1412 'missing required field "[\'location\']".')
1413 rel_template = (toscaparser.utils.yamlparser.
1414 simple_parse(tpl_snippet))['relationship_templates']
1415 name = list(rel_template.keys())[0]
1416 rel_template = RelationshipTemplate(rel_template[name], name)
1417 err = self.assertRaises(exception.MissingRequiredFieldError,
1418 rel_template.validate)
1419 self.assertEqual(expectedmessage, six.text_type(err))
1421 def test_invalid_template_version(self):
1422 tosca_tpl = os.path.join(
1423 os.path.dirname(os.path.abspath(__file__)),
1424 "data/test_invalid_template_version.yaml")
1425 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl)
1426 valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS)
1427 exception.ExceptionCollector.assertExceptionMessage(
1428 exception.InvalidTemplateVersion,
1429 (_('The template version "tosca_xyz" is invalid. Valid versions '
1430 'are "%s".') % valid_versions))
1432 def test_node_template_capabilities_properties(self):
1433 # validating capability property values
1437 type: tosca.nodes.WebServer
1443 expectedmessage = _('The value "test" of property "initiator" is '
1444 'not valid. Expected a value from "[source, '
1447 err = self.assertRaises(
1448 exception.ValidationError,
1449 lambda: self._single_node_template_content_test(tpl_snippet))
1450 self.assertEqual(expectedmessage, err.__str__())
1455 type: tosca.nodes.Compute
1460 num_cpus: { get_input: cpus }
1464 architecture: x86_64
1466 distribution: Fedora
1472 default_instances: 5
1474 expectedmessage = _('"properties" of template "server": '
1475 '"default_instances" value is not between '
1476 '"min_instances" and "max_instances".')
1477 err = self.assertRaises(
1478 exception.ValidationError,
1479 lambda: self._single_node_template_content_test(tpl_snippet))
1480 self.assertEqual(expectedmessage, err.__str__())
1482 def test_node_template_objectstorage_without_required_property(self):
1486 type: tosca.nodes.ObjectStorage
1490 expectedmessage = _('"properties" of template "server" is missing '
1491 'required field "[\'name\']".')
1492 err = self.assertRaises(
1493 exception.MissingRequiredFieldError,
1494 lambda: self._single_node_template_content_test(tpl_snippet))
1495 self.assertEqual(expectedmessage, err.__str__())
1497 def test_node_template_objectstorage_with_invalid_scalar_unit(self):
1501 type: tosca.nodes.ObjectStorage
1506 expectedmessage = _('"-1" is not a valid scalar-unit.')
1507 err = self.assertRaises(
1509 lambda: self._single_node_template_content_test(tpl_snippet))
1510 self.assertEqual(expectedmessage, err.__str__())
1512 def test_node_template_objectstorage_with_invalid_scalar_type(self):
1516 type: tosca.nodes.ObjectStorage
1521 expectedmessage = _('"1 XB" is not a valid scalar-unit.')
1522 err = self.assertRaises(
1524 lambda: self._single_node_template_content_test(tpl_snippet))
1525 self.assertEqual(expectedmessage, err.__str__())
1527 def test_special_keywords(self):
1528 """Test special keywords
1530 Test that special keywords, e.g. metadata, which are not part
1531 of specification do not throw any validation error.
1533 tpl_snippet_metadata_map = '''
1536 type: tosca.nodes.Compute
1541 self._single_node_template_content_test(tpl_snippet_metadata_map)
1543 tpl_snippet_metadata_inline = '''
1546 type: tosca.nodes.Compute
1549 self._single_node_template_content_test(tpl_snippet_metadata_inline)
1551 def test_policy_valid_keynames(self):
1554 - servers_placement:
1555 type: tosca.policies.Placement
1556 description: Apply placement policy to servers
1557 metadata: { user1: 1001, user2: 1002 }
1558 targets: [ serv1, serv2 ]
1560 policies = (toscaparser.utils.yamlparser.
1561 simple_parse(tpl_snippet))['policies'][0]
1562 name = list(policies.keys())[0]
1563 Policy(name, policies[name], None, None)
1565 def test_policy_invalid_keyname(self):
1568 - servers_placement:
1569 type: tosca.policies.Placement
1572 policies = (toscaparser.utils.yamlparser.
1573 simple_parse(tpl_snippet))['policies'][0]
1574 name = list(policies.keys())[0]
1576 expectedmessage = _('Policy "servers_placement" contains '
1577 'unknown field "testkey". Refer to the '
1578 'definition to verify valid values.')
1579 err = self.assertRaises(
1580 exception.UnknownFieldError,
1581 lambda: Policy(name, policies[name], None, None))
1582 self.assertEqual(expectedmessage, err.__str__())
1584 def test_policy_trigger_valid_keyname(self):
1588 description: trigger
1589 event_type: tosca.events.resource.utilization
1591 start_time: "2015-05-07T07:00:00Z"
1592 end_time: "2015-06-07T07:00:00Z"
1594 node: master-container
1596 capability: Container
1598 constraint: { greater_than: 50 }
1603 resize: # Operation name
1605 strategy: LEAST_USED
1606 implementation: Senlin.webhook()
1608 triggers = (toscaparser.utils.yamlparser.
1609 simple_parse(tpl_snippet))['triggers'][0]
1610 name = list(triggers.keys())[0]
1611 Triggers(name, triggers[name])
1613 def test_policy_trigger_invalid_keyname(self):
1617 description: trigger
1618 event_type: tosca.events.resource.utilization
1620 start_time: "2015-05-07T07:00:00Z"
1621 end_time: "2015-06-07T07:00:00Z"
1623 node: master-container
1625 capability: Container
1627 constraint: utilization greater_than 50%
1632 resize: # Operation name
1634 strategy: LEAST_USED
1635 implementation: Senlin.webhook()
1637 triggers = (toscaparser.utils.yamlparser.
1638 simple_parse(tpl_snippet))['triggers'][0]
1639 name = list(triggers.keys())[0]
1640 expectedmessage = _(
1641 'Triggers "resize_compute" contains unknown field '
1642 '"target_filter1". Refer to the definition '
1643 'to verify valid values.')
1644 err = self.assertRaises(
1645 exception.UnknownFieldError,
1646 lambda: Triggers(name, triggers[name]))
1647 self.assertEqual(expectedmessage, err.__str__())
1649 def test_policy_missing_required_keyname(self):
1652 - servers_placement:
1653 description: test description
1655 policies = (toscaparser.utils.yamlparser.
1656 simple_parse(tpl_snippet))['policies'][0]
1657 name = list(policies.keys())[0]
1659 expectedmessage = _('Template "servers_placement" is missing '
1660 'required field "type".')
1661 err = self.assertRaises(
1662 exception.MissingRequiredFieldError,
1663 lambda: Policy(name, policies[name], None, None))
1664 self.assertEqual(expectedmessage, err.__str__())
1666 def test_credential_datatype(self):
1667 tosca_tpl = os.path.join(
1668 os.path.dirname(os.path.abspath(__file__)),
1669 "data/test_credential_datatype.yaml")
1670 self.assertIsNotNone(ToscaTemplate(tosca_tpl))
1672 def test_invalid_default_value(self):
1673 tpl_path = os.path.join(
1674 os.path.dirname(os.path.abspath(__file__)),
1675 "data/test_invalid_input_defaults.yaml")
1676 self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
1677 exception.ExceptionCollector.assertExceptionMessage(
1678 ValueError, _('"two" is not an integer.'))
1680 def test_invalid_capability(self):
1684 type: tosca.nodes.Compute
1688 architecture: x86_64
1690 tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
1691 err = self.assertRaises(exception.UnknownFieldError,
1692 TopologyTemplate, tpl, None)
1693 expectedmessage = _('"capabilities" of template "server" contains '
1694 'unknown field "oss". Refer to the definition '
1695 'to verify valid values.')
1696 self.assertEqual(expectedmessage, err.__str__())
1698 def test_qualified_name(self):
1699 tpl_snippet_full_name = '''
1702 type: tosca.nodes.Compute
1705 toscaparser.utils.yamlparser.simple_parse(
1706 tpl_snippet_full_name))
1707 TopologyTemplate(tpl, None)
1709 tpl_snippet_short_name = '''
1715 toscaparser.utils.yamlparser.simple_parse(
1716 tpl_snippet_short_name))
1717 TopologyTemplate(tpl, None)
1719 tpl_snippet_qualified_name = '''
1725 toscaparser.utils.yamlparser.simple_parse(
1726 tpl_snippet_qualified_name))
1727 TopologyTemplate(tpl, None)
1729 def test_requirements_as_list(self):
1730 """Node template with requirements provided with or without list
1732 Node template requirements are required to be provided as list.
1735 expectedmessage = _('"requirements" of template "my_webserver"'
1736 ' must be of type "list".')
1738 # requirements provided as dictionary
1742 type: tosca.nodes.WebServer
1746 type: tosca.nodes.Compute
1748 err1 = self.assertRaises(
1749 exception.TypeMismatchError,
1750 lambda: self._single_node_template_content_test(tpl_snippet1))
1751 self.assertEqual(expectedmessage, err1.__str__())
1753 # requirements provided as string
1757 type: tosca.nodes.WebServer
1758 requirements: server
1760 type: tosca.nodes.Compute
1762 err2 = self.assertRaises(
1763 exception.TypeMismatchError,
1764 lambda: self._single_node_template_content_test(tpl_snippet2))
1765 self.assertEqual(expectedmessage, err2.__str__())
1767 # requirements provided as list
1771 type: tosca.nodes.WebServer
1775 type: tosca.nodes.Compute
1778 self._single_node_template_content_test(tpl_snippet3))
1780 def test_properties_override_with_flavor_and_image(self):
1781 tpl_path = os.path.join(
1782 os.path.dirname(os.path.abspath(__file__)),
1783 "data/test_normative_type_properties_override.yaml")
1784 self.assertIsNotNone(ToscaTemplate(tpl_path))