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
15 from toscaparser.common import exception
16 import toscaparser.elements.interfaces as ifaces
17 from toscaparser.elements.nodetype import NodeType
18 from toscaparser.elements.portspectype import PortSpec
19 from toscaparser.functions import GetInput
20 from toscaparser.functions import GetProperty
21 from toscaparser.nodetemplate import NodeTemplate
22 from toscaparser.tests.base import TestCase
23 from toscaparser.tosca_template import ToscaTemplate
24 from toscaparser.utils.gettextutils import _
25 import toscaparser.utils.yamlparser
28 class ToscaTemplateTest(TestCase):
30 tosca_tpl = os.path.join(
31 os.path.dirname(os.path.abspath(__file__)),
32 "data/tosca_single_instance_wordpress.yaml")
33 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
34 'db_root_pwd': '12345678'}
35 tosca = ToscaTemplate(tosca_tpl, parsed_params=params)
36 tosca_elk_tpl = os.path.join(
37 os.path.dirname(os.path.abspath(__file__)),
38 "data/tosca_elk.yaml")
39 tosca_repo_tpl = os.path.join(
40 os.path.dirname(os.path.abspath(__file__)),
41 "data/repositories/tosca_repositories_test_definition.yaml")
43 def test_version(self):
44 self.assertEqual(self.tosca.version, "tosca_simple_yaml_1_0")
46 def test_description(self):
47 expected_description = "TOSCA simple profile with wordpress, " \
48 "web server and mysql on the same server."
49 self.assertEqual(self.tosca.description, expected_description)
51 def test_inputs(self):
53 ['cpus', 'db_name', 'db_port',
54 'db_pwd', 'db_root_pwd', 'db_user'],
55 sorted([input.name for input in self.tosca.inputs]))
57 input_name = "db_port"
58 expected_description = "Port for the MySQL database."
59 for input in self.tosca.inputs:
60 if input.name == input_name:
61 self.assertEqual(input.description, expected_description)
63 def test_node_tpls(self):
64 '''Test nodetemplate names.'''
66 ['mysql_database', 'mysql_dbms', 'server',
67 'webserver', 'wordpress'],
68 sorted([tpl.name for tpl in self.tosca.nodetemplates]))
70 tpl_name = "mysql_database"
71 expected_type = "tosca.nodes.Database"
72 expected_properties = ['name', 'password', 'user']
73 expected_capabilities = ['database_endpoint', 'feature']
74 expected_requirements = [{'host': 'mysql_dbms'}]
75 ''' TODO: needs enhancement in tosca_elk.yaml..
76 expected_relationshp = ['tosca.relationships.HostedOn']
77 expected_host = ['mysql_dbms']
79 expected_interface = [ifaces.LIFECYCLE_SHORTNAME]
81 for tpl in self.tosca.nodetemplates:
82 if tpl_name == tpl.name:
84 self.assertEqual(tpl.type, expected_type)
86 '''Test properties.'''
89 sorted(tpl.get_properties().keys()))
91 '''Test capabilities.'''
93 expected_capabilities,
94 sorted(tpl.get_capabilities().keys()))
96 '''Test requirements.'''
98 expected_requirements, tpl.requirements)
100 '''Test relationship.'''
101 ''' needs enhancements in tosca_elk.yaml
103 expected_relationshp,
104 [x.type for x in tpl.relationships.keys()])
107 [y.name for y in tpl.relationships.values()])
109 '''Test interfaces.'''
112 [x.type for x in tpl.interfaces])
114 if tpl.name == 'server':
115 '''Test property value'''
116 props = tpl.get_properties()
117 if props and 'mem_size' in props.keys():
118 self.assertEqual(props['mem_size'].value, '4096 MB')
119 '''Test capability'''
120 caps = tpl.get_capabilities()
121 self.assertIn('os', caps.keys())
125 if caps and 'os' in caps.keys():
126 capability = caps['os']
127 os_props_objs = capability.get_properties_objects()
128 os_props = capability.get_properties()
129 os_type_prop = capability.get_property_value('type')
133 [p.value for p in os_props_objs if p.name == 'type'])
136 os_props['type'].value if 'type' in os_props else '')
137 self.assertEqual('Linux', os_props['type'].value)
138 self.assertEqual('Linux', os_type_prop)
140 def test_node_inheritance_type(self):
142 node for node in self.tosca.nodetemplates
143 if node.name == 'wordpress'][0]
145 wordpress_node.is_derived_from("tosca.nodes.WebApplication"))
147 wordpress_node.is_derived_from("tosca.nodes.Root"))
149 wordpress_node.is_derived_from("tosca.policies.Root"))
151 def test_outputs(self):
154 sorted([output.name for output in self.tosca.outputs]))
156 def test_interfaces(self):
158 node for node in self.tosca.nodetemplates
159 if node.name == 'wordpress'][0]
160 interfaces = wordpress_node.interfaces
161 self.assertEqual(2, len(interfaces))
162 for interface in interfaces:
163 if interface.name == 'create':
164 self.assertEqual(ifaces.LIFECYCLE_SHORTNAME,
166 self.assertEqual('wordpress/wordpress_install.sh',
167 interface.implementation)
168 self.assertIsNone(interface.inputs)
169 elif interface.name == 'configure':
170 self.assertEqual(ifaces.LIFECYCLE_SHORTNAME,
172 self.assertEqual('wordpress/wordpress_configure.sh',
173 interface.implementation)
174 self.assertEqual(3, len(interface.inputs))
175 TestCase.skip(self, 'bug #1440247')
176 wp_db_port = interface.inputs['wp_db_port']
177 self.assertIsInstance(wp_db_port, GetProperty)
178 self.assertEqual('get_property', wp_db_port.name)
179 self.assertEqual(['SELF',
183 result = wp_db_port.result()
184 self.assertIsInstance(result, GetInput)
186 raise AssertionError(
187 'Unexpected interface: {0}'.format(interface.name))
189 def test_normative_type_by_short_name(self):
190 # test template with a short name Compute
191 template = os.path.join(
192 os.path.dirname(os.path.abspath(__file__)),
193 "data/test_tosca_normative_type_by_shortname.yaml")
195 tosca_tpl = ToscaTemplate(template)
196 expected_type = "tosca.nodes.Compute"
197 for tpl in tosca_tpl.nodetemplates:
198 self.assertEqual(tpl.type, expected_type)
199 for tpl in tosca_tpl.nodetemplates:
200 compute_type = NodeType(tpl.type)
202 sorted(['tosca.capabilities.Container',
203 'tosca.capabilities.Endpoint.Admin',
204 'tosca.capabilities.Node',
205 'tosca.capabilities.OperatingSystem',
206 'tosca.capabilities.network.Bindable',
207 'tosca.capabilities.Scalable']),
209 for c in compute_type.get_capabilities_objects()]))
211 def test_template_with_no_inputs(self):
212 tosca_tpl = self._load_template('test_no_inputs_in_template.yaml')
213 self.assertEqual(0, len(tosca_tpl.inputs))
215 def test_template_with_no_outputs(self):
216 tosca_tpl = self._load_template('test_no_outputs_in_template.yaml')
217 self.assertEqual(0, len(tosca_tpl.outputs))
219 def test_template_file_with_suffix_yml(self):
220 tosca_tpl = self._load_template('custom_types/wordpress.yml')
221 self.assertIsNotNone(tosca_tpl)
223 def test_relationship_interface(self):
224 template = ToscaTemplate(self.tosca_elk_tpl)
225 for node_tpl in template.nodetemplates:
226 if node_tpl.name == 'logstash':
227 config_interface = 'Configure'
228 artifact = 'logstash/configure_elasticsearch.py'
229 relation = node_tpl.relationships
230 for key in relation.keys():
231 rel_tpl = relation.get(key).get_relationship_template()
233 self.assertTrue(rel_tpl[0].is_derived_from(
234 "tosca.relationships.Root"))
235 interfaces = rel_tpl[0].interfaces
236 for interface in interfaces:
237 self.assertEqual(config_interface,
239 self.assertEqual('pre_configure_source',
241 self.assertEqual(artifact,
242 interface.implementation)
244 def test_relationship(self):
245 template = ToscaTemplate(self.tosca_elk_tpl)
246 for node_tpl in template.nodetemplates:
247 if node_tpl.name == 'paypal_pizzastore':
248 expected_relationships = ['tosca.relationships.ConnectsTo',
249 'tosca.relationships.HostedOn']
250 expected_hosts = ['tosca.nodes.Database',
251 'tosca.nodes.WebServer']
252 self.assertEqual(len(node_tpl.relationships), 2)
254 expected_relationships,
255 sorted([k.type for k in node_tpl.relationships.keys()]))
258 sorted([v.type for v in node_tpl.relationships.values()]))
260 def test_repositories(self):
261 template = ToscaTemplate(self.tosca_repo_tpl)
263 ['repo_code0', 'repo_code1', 'repo_code2'],
264 sorted([input.name for input in template.repositories]))
266 input_name = "repo_code2"
267 expected_url = "https://github.com/nandinivemula/intern/master"
268 for input in template.repositories:
269 if input.name == input_name:
270 self.assertEqual(input.url, expected_url)
272 def test_template_macro(self):
273 template = ToscaTemplate(self.tosca_elk_tpl)
274 for node_tpl in template.nodetemplates:
275 if node_tpl.name == 'mongo_server':
277 ['disk_size', 'mem_size', 'num_cpus'],
278 sorted(node_tpl.get_capability('host').
279 get_properties().keys()))
281 def test_template_requirements(self):
282 """Test different formats of requirements
284 The requirements can be defined in few different ways,
285 1. Requirement expressed as a capability with an implicit relationship.
286 2. Requirement expressed with explicit relationship.
287 3. Requirement expressed with a relationship template.
288 4. Requirement expressed via TOSCA types to provision a node
289 with explicit relationship.
290 5. Requirement expressed via TOSCA types with a filter.
292 tosca_tpl = os.path.join(
293 os.path.dirname(os.path.abspath(__file__)),
294 "data/requirements/test_requirements.yaml")
295 tosca = ToscaTemplate(tosca_tpl)
296 for node_tpl in tosca.nodetemplates:
297 if node_tpl.name == 'my_app':
298 expected_relationship = [
299 ('tosca.relationships.ConnectsTo', 'mysql_database'),
300 ('tosca.relationships.HostedOn', 'my_webserver')]
301 actual_relationship = sorted([
302 (relation.type, node.name) for
303 relation, node in node_tpl.relationships.items()])
304 self.assertEqual(expected_relationship, actual_relationship)
305 if node_tpl.name == 'mysql_database':
307 [('tosca.relationships.HostedOn', 'my_dbms')],
308 [(relation.type, node.name) for
310 node in node_tpl.relationships.items()])
311 if node_tpl.name == 'my_server':
313 [('tosca.relationships.AttachesTo', 'my_storage')],
314 [(relation.type, node.name) for
316 node in node_tpl.relationships.items()])
318 def test_template_requirements_not_implemented(self):
319 # TODO(spzala): replace this test with new one once TOSCA types look up
320 # support is implemented.
321 """Requirements that yet need to be implemented
323 The following requirement formats are not yet implemented,
324 due to look up dependency:
325 1. Requirement expressed via TOSCA types to provision a node
326 with explicit relationship.
327 2. Requirement expressed via TOSCA types with a filter.
332 type: tosca.nodes.Database
333 description: Requires a particular node type and relationship.
334 To be full-filled via lookup into node repository.
337 node: tosca.nodes.DBMS
338 relationship: tosca.relationships.HostedOn
344 type: tosca.nodes.WebServer
345 description: Requires a particular node type with a filter.
346 To be full-filled via lookup into node repository.
349 node: tosca.nodes.Compute
352 num_cpus: { in_range: [ 1, 4 ] }
353 mem_size: { greater_or_equal: 2 }
355 - tosca.capabilities.OS:
364 type: tosca.nodes.WebServer
365 description: Requires a node type with a particular capability.
366 To be full-filled via lookup into node repository.
369 node: tosca.nodes.Compute
370 relationship: tosca.relationships.HostedOn
371 capability: tosca.capabilities.Container
373 self._requirements_not_implemented(tpl_snippet_1, 'mysql_database')
374 self._requirements_not_implemented(tpl_snippet_2, 'my_webserver')
375 self._requirements_not_implemented(tpl_snippet_3, 'my_webserver2')
377 def _requirements_not_implemented(self, tpl_snippet, tpl_name):
378 nodetemplates = (toscaparser.utils.yamlparser.
379 simple_parse(tpl_snippet))['node_templates']
382 lambda: NodeTemplate(tpl_name, nodetemplates).relationships)
384 # Test the following:
385 # 1. Custom node type derived from 'WebApplication' named 'TestApp'
386 # with a custom Capability Type 'TestCapability'
387 # 2. Same as #1, but referencing a custom 'TestCapability' Capability Type
388 # that is not defined
389 def test_custom_capability_type_definition(self):
393 type: tosca.nodes.WebApplication.TestApp
399 # custom node type definition with custom capability type definition
401 tosca.nodes.WebApplication.TestApp:
402 derived_from: tosca.nodes.WebApplication
405 type: tosca.capabilities.TestCapability
406 tosca.capabilities.TestCapability:
407 derived_from: tosca.capabilities.Root
413 expected_capabilities = ['app_endpoint', 'feature', 'test_cap']
414 nodetemplates = (toscaparser.utils.yamlparser.
415 simple_parse(tpl_snippet))['node_templates']
416 custom_def = (toscaparser.utils.yamlparser.
417 simple_parse(custom_def))
418 name = list(nodetemplates.keys())[0]
419 tpl = NodeTemplate(name, nodetemplates, custom_def)
421 expected_capabilities,
422 sorted(tpl.get_capabilities().keys()))
424 # custom definition without valid capability type definition
426 tosca.nodes.WebApplication.TestApp:
427 derived_from: tosca.nodes.WebApplication
430 type: tosca.capabilities.TestCapability
432 custom_def = (toscaparser.utils.yamlparser.
433 simple_parse(custom_def))
434 tpl = NodeTemplate(name, nodetemplates, custom_def)
435 err = self.assertRaises(
436 exception.InvalidTypeError,
437 lambda: NodeTemplate(name, nodetemplates,
438 custom_def).get_capabilities_objects())
439 self.assertEqual('Type "tosca.capabilities.TestCapability" is not '
440 'a valid type.', six.text_type(err))
442 def test_local_template_with_local_relpath_import(self):
443 tosca_tpl = os.path.join(
444 os.path.dirname(os.path.abspath(__file__)),
445 "data/tosca_single_instance_wordpress.yaml")
446 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
447 'db_root_pwd': '12345678'}
448 tosca = ToscaTemplate(tosca_tpl, parsed_params=params)
449 self.assertTrue(tosca.topology_template.custom_defs)
451 def test_local_template_with_url_import(self):
452 tosca_tpl = os.path.join(
453 os.path.dirname(os.path.abspath(__file__)),
454 "data/tosca_single_instance_wordpress_with_url_import.yaml")
455 tosca = ToscaTemplate(tosca_tpl,
456 parsed_params={'db_root_pwd': '123456'})
457 self.assertTrue(tosca.topology_template.custom_defs)
459 def test_url_template_with_local_relpath_import(self):
460 tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
461 'tosca-parser/master/toscaparser/tests/data/'
462 'tosca_single_instance_wordpress.yaml')
463 tosca = ToscaTemplate(tosca_tpl, a_file=False,
464 parsed_params={"db_name": "mysql",
466 "db_root_pwd": "1234",
470 self.assertTrue(tosca.topology_template.custom_defs)
472 def test_url_template_with_local_abspath_import(self):
473 tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
474 'tosca-parser/master/toscaparser/tests/data/'
475 'tosca_single_instance_wordpress_with_local_abspath_'
477 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
479 err_msg = (_('Absolute file name "/tmp/tosca-parser/toscaparser/tests'
480 '/data/custom_types/wordpress.yaml" cannot be used in a '
481 'URL-based input template "%(tpl)s".')
482 % {'tpl': tosca_tpl})
483 exception.ExceptionCollector.assertExceptionMessage(ImportError,
486 def test_url_template_with_url_import(self):
487 tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
488 'tosca-parser/master/toscaparser/tests/data/'
489 'tosca_single_instance_wordpress_with_url_import.yaml')
490 tosca = ToscaTemplate(tosca_tpl, a_file=False,
491 parsed_params={"db_root_pwd": "1234"})
492 self.assertTrue(tosca.topology_template.custom_defs)
494 def test_csar_parsing_wordpress(self):
495 csar_archive = os.path.join(
496 os.path.dirname(os.path.abspath(__file__)),
497 'data/CSAR/csar_wordpress.zip')
498 self.assertTrue(ToscaTemplate(csar_archive,
499 parsed_params={"db_name": "mysql",
501 "db_root_pwd": "1234",
506 def test_csar_parsing_elk_url_based(self):
507 csar_archive = ('https://github.com/openstack/tosca-parser/raw/master/'
508 'toscaparser/tests/data/CSAR/csar_elk.zip')
509 self.assertTrue(ToscaTemplate(csar_archive, a_file=False,
510 parsed_params={"my_cpus": 4}))
512 def test_nested_imports_in_templates(self):
513 tosca_tpl = os.path.join(
514 os.path.dirname(os.path.abspath(__file__)),
515 "data/test_instance_nested_imports.yaml")
516 tosca = ToscaTemplate(tosca_tpl)
517 expected_custom_types = ['tosca.nodes.SoftwareComponent.Kibana',
518 'tosca.nodes.WebApplication.WordPress',
519 'test_namespace_prefix.Rsyslog',
520 'Test2ndRsyslogType',
521 'test_2nd_namespace_prefix.Rsyslog',
522 'tosca.nodes.SoftwareComponent.Logstash',
523 'tosca.nodes.SoftwareComponent.Rsyslog.'
525 self.assertItemsEqual(tosca.topology_template.custom_defs.keys(),
526 expected_custom_types)
528 def test_invalid_template_file(self):
529 template_file = 'invalid template file'
530 expected_msg = (_('"%s" is not a valid file.') % template_file)
532 exception.ValidationError,
533 ToscaTemplate, template_file, None, False)
534 exception.ExceptionCollector.assertExceptionMessage(ValueError,
537 def test_multiple_validation_errors(self):
538 tosca_tpl = os.path.join(
539 os.path.dirname(os.path.abspath(__file__)),
540 "data/test_multiple_validation_errors.yaml")
541 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
543 valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS)
544 err1_msg = (_('The template version "tosca_simple_yaml_1" is invalid. '
545 'Valid versions are "%s".') % valid_versions)
546 exception.ExceptionCollector.assertExceptionMessage(
547 exception.InvalidTemplateVersion, err1_msg)
549 err2_msg = _('Import "custom_types/not_there.yaml" is not valid.')
550 exception.ExceptionCollector.assertExceptionMessage(
551 ImportError, err2_msg)
553 err3_msg = _('Type "tosca.nodes.WebApplication.WordPress" is not a '
555 exception.ExceptionCollector.assertExceptionMessage(
556 exception.InvalidTypeError, err3_msg)
558 err4_msg = _('Node template "wordpress" contains unknown field '
559 '"requirement". Refer to the definition to verify valid '
561 exception.ExceptionCollector.assertExceptionMessage(
562 exception.UnknownFieldError, err4_msg)
564 err5_msg = _('\'Property "passwords" was not found in node template '
565 '"mysql_database".\'')
566 exception.ExceptionCollector.assertExceptionMessage(
569 err6_msg = _('Template "mysql_dbms" is missing required field "type".')
570 exception.ExceptionCollector.assertExceptionMessage(
571 exception.MissingRequiredFieldError, err6_msg)
573 err7_msg = _('Node template "mysql_dbms" contains unknown field '
574 '"type1". Refer to the definition to verify valid '
576 exception.ExceptionCollector.assertExceptionMessage(
577 exception.UnknownFieldError, err7_msg)
579 err8_msg = _('\'Node template "server1" was not found in '
581 exception.ExceptionCollector.assertExceptionMessage(
584 err9_msg = _('"relationship" used in template "webserver" is missing '
585 'required field "type".')
586 exception.ExceptionCollector.assertExceptionMessage(
587 exception.MissingRequiredFieldError, err9_msg)
589 err10_msg = _('Type "tosca.nodes.XYZ" is not a valid type.')
590 exception.ExceptionCollector.assertExceptionMessage(
591 exception.InvalidTypeError, err10_msg)
593 def test_invalid_section_names(self):
594 tosca_tpl = os.path.join(
595 os.path.dirname(os.path.abspath(__file__)),
596 "data/test_invalid_section_names.yaml")
597 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
599 err1_msg = _('Template contains unknown field '
600 '"tosca_definitions_versions". Refer to the definition '
601 'to verify valid values.')
602 exception.ExceptionCollector.assertExceptionMessage(
603 exception.UnknownFieldError, err1_msg)
605 err2_msg = _('Template contains unknown field "descriptions". '
606 'Refer to the definition to verify valid values.')
607 exception.ExceptionCollector.assertExceptionMessage(
608 exception.UnknownFieldError, err2_msg)
610 err3_msg = _('Template contains unknown field "import". Refer to '
611 'the definition to verify valid values.')
612 exception.ExceptionCollector.assertExceptionMessage(
613 exception.UnknownFieldError, err3_msg)
615 err4_msg = _('Template contains unknown field "topology_templates". '
616 'Refer to the definition to verify valid values.')
617 exception.ExceptionCollector.assertExceptionMessage(
618 exception.UnknownFieldError, err4_msg)
620 def test_csar_with_alternate_extenstion(self):
621 tosca_tpl = os.path.join(
622 os.path.dirname(os.path.abspath(__file__)),
623 "data/CSAR/csar_elk.csar")
624 tosca = ToscaTemplate(tosca_tpl, parsed_params={"my_cpus": 2})
625 self.assertTrue(tosca.topology_template.custom_defs)
627 def test_available_rel_tpls(self):
628 tosca_tpl = os.path.join(
629 os.path.dirname(os.path.abspath(__file__)),
630 "data/test_available_rel_tpls.yaml")
631 tosca = ToscaTemplate(tosca_tpl)
632 for node in tosca.nodetemplates:
633 for relationship, target in node.relationships.items():
636 except TypeError as error:
639 def test_no_input(self):
640 self.assertRaises(exception.ValidationError, ToscaTemplate, None,
642 err_msg = (('No path or yaml_dict_tpl was provided. '
643 'There is nothing to parse.'))
644 exception.ExceptionCollector.assertExceptionMessage(ValueError,
647 def test_path_and_yaml_dict_tpl_input(self):
648 test_tpl = os.path.join(
649 os.path.dirname(os.path.abspath(__file__)),
650 "data/tosca_helloworld.yaml")
652 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
654 tosca = ToscaTemplate(test_tpl, yaml_dict_tpl=yaml_dict_tpl)
656 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
658 def test_yaml_dict_tpl_input(self):
659 test_tpl = os.path.join(
660 os.path.dirname(os.path.abspath(__file__)),
661 "data/tosca_helloworld.yaml")
663 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
665 tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
667 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
669 def test_yaml_dict_tpl_with_version_1_1(self):
670 test_tpl = os.path.join(
671 os.path.dirname(os.path.abspath(__file__)),
672 "data/tosca_helloworld_with_version_1_1.yaml")
674 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
676 tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
678 self.assertEqual(tosca.version, "tosca_simple_yaml_1_1")
680 def test_yaml_dict_tpl_with_params_and_url_import(self):
681 test_tpl = os.path.join(
682 os.path.dirname(os.path.abspath(__file__)),
683 "data/tosca_single_instance_wordpress_with_url_import.yaml")
685 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
687 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
688 'db_root_pwd': 'mypasswd'}
690 tosca = ToscaTemplate(parsed_params=params,
691 yaml_dict_tpl=yaml_dict_tpl)
693 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
695 def test_yaml_dict_tpl_with_rel_import(self):
696 test_tpl = os.path.join(
697 os.path.dirname(os.path.abspath(__file__)),
698 "data/tosca_single_instance_wordpress.yaml")
700 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
701 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
702 'db_root_pwd': '12345678'}
703 self.assertRaises(exception.ValidationError, ToscaTemplate, None,
704 params, False, yaml_dict_tpl)
705 err_msg = (_('Relative file name "custom_types/wordpress.yaml" '
706 'cannot be used in a pre-parsed input template.'))
707 exception.ExceptionCollector.assertExceptionMessage(ImportError,
710 def test_yaml_dict_tpl_with_fullpath_import(self):
711 test_tpl = os.path.join(
712 os.path.dirname(os.path.abspath(__file__)),
713 "data/tosca_single_instance_wordpress.yaml")
715 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
717 yaml_dict_tpl['imports'] = [os.path.join(os.path.dirname(
718 os.path.abspath(__file__)), "data/custom_types/wordpress.yaml")]
720 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
721 'db_root_pwd': 'mypasswd'}
723 tosca = ToscaTemplate(parsed_params=params,
724 yaml_dict_tpl=yaml_dict_tpl)
726 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
728 def test_policies_for_node_templates(self):
729 tosca_tpl = os.path.join(
730 os.path.dirname(os.path.abspath(__file__)),
731 "data/policies/tosca_policy_template.yaml")
732 tosca = ToscaTemplate(tosca_tpl)
734 for policy in tosca.topology_template.policies:
736 policy.is_derived_from("tosca.policies.Root"))
737 if policy.name == 'my_compute_placement_policy':
738 self.assertEqual('tosca.policies.Placement', policy.type)
739 self.assertEqual(['my_server_1', 'my_server_2'],
741 self.assertEqual('node_templates', policy.get_targets_type())
742 for node in policy.targets_list:
743 if node.name == 'my_server_1':
744 '''Test property value'''
745 props = node.get_properties()
746 if props and 'mem_size' in props.keys():
747 self.assertEqual(props['mem_size'].value,
750 def test_policies_for_groups(self):
751 tosca_tpl = os.path.join(
752 os.path.dirname(os.path.abspath(__file__)),
753 "data/policies/tosca_policy_template.yaml")
754 tosca = ToscaTemplate(tosca_tpl)
756 for policy in tosca.topology_template.policies:
758 policy.is_derived_from("tosca.policies.Root"))
759 if policy.name == 'my_groups_placement':
760 self.assertEqual('mycompany.mytypes.myScalingPolicy',
762 self.assertEqual(['webserver_group'], policy.targets)
763 self.assertEqual('groups', policy.get_targets_type())
764 group = policy.get_targets_list()[0]
765 for node in group.get_member_nodes():
766 if node.name == 'my_server_2':
767 '''Test property value'''
768 props = node.get_properties()
769 if props and 'mem_size' in props.keys():
770 self.assertEqual(props['mem_size'].value,
773 def test_node_filter(self):
774 tosca_tpl = os.path.join(
775 os.path.dirname(os.path.abspath(__file__)),
776 "data/node_filter/test_node_filter.yaml")
777 ToscaTemplate(tosca_tpl)
779 def test_attributes_inheritance(self):
780 tosca_tpl = os.path.join(
781 os.path.dirname(os.path.abspath(__file__)),
782 "data/test_attributes_inheritance.yaml")
783 ToscaTemplate(tosca_tpl)
785 def test_repositories_definition(self):
786 tosca_tpl = os.path.join(
787 os.path.dirname(os.path.abspath(__file__)),
788 "data/repositories/test_repositories_definition.yaml")
789 ToscaTemplate(tosca_tpl)
791 def test_custom_caps_def(self):
792 tosca_tpl = os.path.join(
793 os.path.dirname(os.path.abspath(__file__)),
794 "data/test_custom_caps_def.yaml")
795 ToscaTemplate(tosca_tpl)
797 def test_custom_rel_with_script(self):
798 tosca_tpl = os.path.join(
799 os.path.dirname(os.path.abspath(__file__)),
800 "data/test_tosca_custom_rel_with_script.yaml")
801 tosca = ToscaTemplate(tosca_tpl)
802 rel = tosca.relationship_templates[0]
803 self.assertEqual(rel.type, "tosca.relationships.HostedOn")
804 self.assertTrue(rel.is_derived_from("tosca.relationships.Root"))
805 self.assertEqual(len(rel.interfaces), 1)
806 self.assertEqual(rel.interfaces[0].type, "Configure")
808 def test_various_portspec_errors(self):
809 tosca_tpl = os.path.join(
810 os.path.dirname(os.path.abspath(__file__)),
811 "data/datatypes/test_datatype_portspec_add_req.yaml")
812 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
815 # TODO(TBD) find way to reuse error messages from constraints.py
816 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
817 'range "(min:%(vmin)s, max:%(vmax)s)".') %
818 dict(pname=PortSpec.SOURCE,
822 exception.ExceptionCollector.assertExceptionMessage(
823 exception.ValidationError, msg)
825 # Test value below range min.
826 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
827 'range "(min:%(vmin)s, max:%(vmax)s)".') %
828 dict(pname=PortSpec.SOURCE,
832 exception.ExceptionCollector.assertExceptionMessage(
833 exception.RangeValueError, msg)
835 # Test value above range max.
836 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
837 'range "(min:%(vmin)s, max:%(vmax)s)".') %
838 dict(pname=PortSpec.SOURCE,
842 exception.ExceptionCollector.assertExceptionMessage(
843 exception.RangeValueError, msg)
845 def test_containers(self):
846 tosca_tpl = os.path.join(
847 os.path.dirname(os.path.abspath(__file__)),
848 "data/containers/test_container_docker_mysql.yaml")
849 ToscaTemplate(tosca_tpl, parsed_params={"mysql_root_pwd": "12345678"})
851 def test_endpoint_on_compute(self):
852 tosca_tpl = os.path.join(
853 os.path.dirname(os.path.abspath(__file__)),
854 "data/test_endpoint_on_compute.yaml")
855 ToscaTemplate(tosca_tpl)
857 def test_nested_dsl_def(self):
858 tosca_tpl = os.path.join(
859 os.path.dirname(os.path.abspath(__file__)),
860 "data/dsl_definitions/test_nested_dsl_def.yaml")
861 self.assertIsNotNone(ToscaTemplate(tosca_tpl))
863 def test_multiple_policies(self):
864 tosca_tpl = os.path.join(
865 os.path.dirname(os.path.abspath(__file__)),
866 "data/policies/test_tosca_nfv_multiple_policies.yaml")
867 tosca = ToscaTemplate(tosca_tpl)
869 ['ALRM1', 'SP1', 'SP2'],
870 sorted([policy.name for policy in tosca.policies]))