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_relationship_interface(self):
220 template = ToscaTemplate(self.tosca_elk_tpl)
221 for node_tpl in template.nodetemplates:
222 if node_tpl.name == 'logstash':
223 config_interface = 'Configure'
224 artifact = 'logstash/configure_elasticsearch.py'
225 relation = node_tpl.relationships
226 for key in relation.keys():
227 rel_tpl = relation.get(key).get_relationship_template()
229 self.assertTrue(rel_tpl[0].is_derived_from(
230 "tosca.relationships.Root"))
231 interfaces = rel_tpl[0].interfaces
232 for interface in interfaces:
233 self.assertEqual(config_interface,
235 self.assertEqual('pre_configure_source',
237 self.assertEqual(artifact,
238 interface.implementation)
240 def test_relationship(self):
241 template = ToscaTemplate(self.tosca_elk_tpl)
242 for node_tpl in template.nodetemplates:
243 if node_tpl.name == 'paypal_pizzastore':
244 expected_relationships = ['tosca.relationships.ConnectsTo',
245 'tosca.relationships.HostedOn']
246 expected_hosts = ['tosca.nodes.Database',
247 'tosca.nodes.WebServer']
248 self.assertEqual(len(node_tpl.relationships), 2)
250 expected_relationships,
251 sorted([k.type for k in node_tpl.relationships.keys()]))
254 sorted([v.type for v in node_tpl.relationships.values()]))
256 def test_repositories(self):
257 template = ToscaTemplate(self.tosca_repo_tpl)
259 ['repo_code0', 'repo_code1', 'repo_code2'],
260 sorted([input.name for input in template.repositories]))
262 input_name = "repo_code2"
263 expected_url = "https://github.com/nandinivemula/intern/master"
264 for input in template.repositories:
265 if input.name == input_name:
266 self.assertEqual(input.url, expected_url)
268 def test_template_macro(self):
269 template = ToscaTemplate(self.tosca_elk_tpl)
270 for node_tpl in template.nodetemplates:
271 if node_tpl.name == 'mongo_server':
273 ['disk_size', 'mem_size', 'num_cpus'],
274 sorted(node_tpl.get_capability('host').
275 get_properties().keys()))
277 def test_template_requirements(self):
278 """Test different formats of requirements
280 The requirements can be defined in few different ways,
281 1. Requirement expressed as a capability with an implicit relationship.
282 2. Requirement expressed with explicit relationship.
283 3. Requirement expressed with a relationship template.
284 4. Requirement expressed via TOSCA types to provision a node
285 with explicit relationship.
286 5. Requirement expressed via TOSCA types with a filter.
288 tosca_tpl = os.path.join(
289 os.path.dirname(os.path.abspath(__file__)),
290 "data/requirements/test_requirements.yaml")
291 tosca = ToscaTemplate(tosca_tpl)
292 for node_tpl in tosca.nodetemplates:
293 if node_tpl.name == 'my_app':
294 expected_relationship = [
295 ('tosca.relationships.ConnectsTo', 'mysql_database'),
296 ('tosca.relationships.HostedOn', 'my_webserver')]
297 actual_relationship = sorted([
298 (relation.type, node.name) for
299 relation, node in node_tpl.relationships.items()])
300 self.assertEqual(expected_relationship, actual_relationship)
301 if node_tpl.name == 'mysql_database':
303 [('tosca.relationships.HostedOn', 'my_dbms')],
304 [(relation.type, node.name) for
306 node in node_tpl.relationships.items()])
307 if node_tpl.name == 'my_server':
309 [('tosca.relationships.AttachesTo', 'my_storage')],
310 [(relation.type, node.name) for
312 node in node_tpl.relationships.items()])
314 def test_template_requirements_not_implemented(self):
315 # TODO(spzala): replace this test with new one once TOSCA types look up
316 # support is implemented.
317 """Requirements that yet need to be implemented
319 The following requirement formats are not yet implemented,
320 due to look up dependency:
321 1. Requirement expressed via TOSCA types to provision a node
322 with explicit relationship.
323 2. Requirement expressed via TOSCA types with a filter.
328 type: tosca.nodes.Database
329 description: Requires a particular node type and relationship.
330 To be full-filled via lookup into node repository.
333 node: tosca.nodes.DBMS
334 relationship: tosca.relationships.HostedOn
340 type: tosca.nodes.WebServer
341 description: Requires a particular node type with a filter.
342 To be full-filled via lookup into node repository.
345 node: tosca.nodes.Compute
348 num_cpus: { in_range: [ 1, 4 ] }
349 mem_size: { greater_or_equal: 2 }
351 - tosca.capabilities.OS:
360 type: tosca.nodes.WebServer
361 description: Requires a node type with a particular capability.
362 To be full-filled via lookup into node repository.
365 node: tosca.nodes.Compute
366 relationship: tosca.relationships.HostedOn
367 capability: tosca.capabilities.Container
369 self._requirements_not_implemented(tpl_snippet_1, 'mysql_database')
370 self._requirements_not_implemented(tpl_snippet_2, 'my_webserver')
371 self._requirements_not_implemented(tpl_snippet_3, 'my_webserver2')
373 def _requirements_not_implemented(self, tpl_snippet, tpl_name):
374 nodetemplates = (toscaparser.utils.yamlparser.
375 simple_parse(tpl_snippet))['node_templates']
378 lambda: NodeTemplate(tpl_name, nodetemplates).relationships)
380 # Test the following:
381 # 1. Custom node type derived from 'WebApplication' named 'TestApp'
382 # with a custom Capability Type 'TestCapability'
383 # 2. Same as #1, but referencing a custom 'TestCapability' Capability Type
384 # that is not defined
385 def test_custom_capability_type_definition(self):
389 type: tosca.nodes.WebApplication.TestApp
395 # custom node type definition with custom capability type definition
397 tosca.nodes.WebApplication.TestApp:
398 derived_from: tosca.nodes.WebApplication
401 type: tosca.capabilities.TestCapability
402 tosca.capabilities.TestCapability:
403 derived_from: tosca.capabilities.Root
409 expected_capabilities = ['app_endpoint', 'feature', 'test_cap']
410 nodetemplates = (toscaparser.utils.yamlparser.
411 simple_parse(tpl_snippet))['node_templates']
412 custom_def = (toscaparser.utils.yamlparser.
413 simple_parse(custom_def))
414 name = list(nodetemplates.keys())[0]
415 tpl = NodeTemplate(name, nodetemplates, custom_def)
417 expected_capabilities,
418 sorted(tpl.get_capabilities().keys()))
420 # custom definition without valid capability type definition
422 tosca.nodes.WebApplication.TestApp:
423 derived_from: tosca.nodes.WebApplication
426 type: tosca.capabilities.TestCapability
428 custom_def = (toscaparser.utils.yamlparser.
429 simple_parse(custom_def))
430 tpl = NodeTemplate(name, nodetemplates, custom_def)
431 err = self.assertRaises(
432 exception.InvalidTypeError,
433 lambda: NodeTemplate(name, nodetemplates,
434 custom_def).get_capabilities_objects())
435 self.assertEqual('Type "tosca.capabilities.TestCapability" is not '
436 'a valid type.', six.text_type(err))
438 def test_local_template_with_local_relpath_import(self):
439 tosca_tpl = os.path.join(
440 os.path.dirname(os.path.abspath(__file__)),
441 "data/tosca_single_instance_wordpress.yaml")
442 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
443 'db_root_pwd': '12345678'}
444 tosca = ToscaTemplate(tosca_tpl, parsed_params=params)
445 self.assertTrue(tosca.topology_template.custom_defs)
447 def test_local_template_with_url_import(self):
448 tosca_tpl = os.path.join(
449 os.path.dirname(os.path.abspath(__file__)),
450 "data/tosca_single_instance_wordpress_with_url_import.yaml")
451 tosca = ToscaTemplate(tosca_tpl,
452 parsed_params={'db_root_pwd': '123456'})
453 self.assertTrue(tosca.topology_template.custom_defs)
455 def test_url_template_with_local_relpath_import(self):
456 tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
457 'tosca-parser/master/toscaparser/tests/data/'
458 'tosca_single_instance_wordpress.yaml')
459 tosca = ToscaTemplate(tosca_tpl, a_file=False,
460 parsed_params={"db_name": "mysql",
462 "db_root_pwd": "1234",
466 self.assertTrue(tosca.topology_template.custom_defs)
468 def test_url_template_with_local_abspath_import(self):
469 tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
470 'tosca-parser/master/toscaparser/tests/data/'
471 'tosca_single_instance_wordpress_with_local_abspath_'
473 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
475 err_msg = (_('Absolute file name "/tmp/tosca-parser/toscaparser/tests'
476 '/data/custom_types/wordpress.yaml" cannot be used in a '
477 'URL-based input template "%(tpl)s".')
478 % {'tpl': tosca_tpl})
479 exception.ExceptionCollector.assertExceptionMessage(ImportError,
482 def test_url_template_with_url_import(self):
483 tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
484 'tosca-parser/master/toscaparser/tests/data/'
485 'tosca_single_instance_wordpress_with_url_import.yaml')
486 tosca = ToscaTemplate(tosca_tpl, a_file=False,
487 parsed_params={"db_root_pwd": "1234"})
488 self.assertTrue(tosca.topology_template.custom_defs)
490 def test_csar_parsing_wordpress(self):
491 csar_archive = os.path.join(
492 os.path.dirname(os.path.abspath(__file__)),
493 'data/CSAR/csar_wordpress.zip')
494 self.assertTrue(ToscaTemplate(csar_archive,
495 parsed_params={"db_name": "mysql",
497 "db_root_pwd": "1234",
502 def test_csar_parsing_elk_url_based(self):
503 csar_archive = ('https://github.com/openstack/tosca-parser/raw/master/'
504 'toscaparser/tests/data/CSAR/csar_elk.zip')
505 self.assertTrue(ToscaTemplate(csar_archive, a_file=False,
506 parsed_params={"my_cpus": 4}))
508 def test_nested_imports_in_templates(self):
509 tosca_tpl = os.path.join(
510 os.path.dirname(os.path.abspath(__file__)),
511 "data/test_instance_nested_imports.yaml")
512 tosca = ToscaTemplate(tosca_tpl)
513 expected_custom_types = ['tosca.nodes.WebApplication.WordPress',
514 'test_namespace_prefix.Rsyslog',
515 'Test2ndRsyslogType',
516 'test_2nd_namespace_prefix.Rsyslog',
517 'tosca.nodes.SoftwareComponent.Logstash',
518 'tosca.nodes.SoftwareComponent.Rsyslog.'
520 self.assertItemsEqual(tosca.topology_template.custom_defs.keys(),
521 expected_custom_types)
523 def test_invalid_template_file(self):
524 template_file = 'invalid template file'
525 expected_msg = (_('"%s" is not a valid file.') % template_file)
527 exception.ValidationError,
528 ToscaTemplate, template_file, None, False)
529 exception.ExceptionCollector.assertExceptionMessage(ValueError,
532 def test_multiple_validation_errors(self):
533 tosca_tpl = os.path.join(
534 os.path.dirname(os.path.abspath(__file__)),
535 "data/test_multiple_validation_errors.yaml")
536 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
538 valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS)
539 err1_msg = (_('The template version "tosca_simple_yaml_1" is invalid. '
540 'Valid versions are "%s".') % valid_versions)
541 exception.ExceptionCollector.assertExceptionMessage(
542 exception.InvalidTemplateVersion, err1_msg)
544 err2_msg = _('Import "custom_types/not_there.yaml" is not valid.')
545 exception.ExceptionCollector.assertExceptionMessage(
546 ImportError, err2_msg)
548 err3_msg = _('Type "tosca.nodes.WebApplication.WordPress" is not a '
550 exception.ExceptionCollector.assertExceptionMessage(
551 exception.InvalidTypeError, err3_msg)
553 err4_msg = _('Node template "wordpress" contains unknown field '
554 '"requirement". Refer to the definition to verify valid '
556 exception.ExceptionCollector.assertExceptionMessage(
557 exception.UnknownFieldError, err4_msg)
559 err5_msg = _('\'Property "passwords" was not found in node template '
560 '"mysql_database".\'')
561 exception.ExceptionCollector.assertExceptionMessage(
564 err6_msg = _('Template "mysql_dbms" is missing required field "type".')
565 exception.ExceptionCollector.assertExceptionMessage(
566 exception.MissingRequiredFieldError, err6_msg)
568 err7_msg = _('Node template "mysql_dbms" contains unknown field '
569 '"type1". Refer to the definition to verify valid '
571 exception.ExceptionCollector.assertExceptionMessage(
572 exception.UnknownFieldError, err7_msg)
574 err8_msg = _('\'Node template "server1" was not found in '
576 exception.ExceptionCollector.assertExceptionMessage(
579 err9_msg = _('"relationship" used in template "webserver" is missing '
580 'required field "type".')
581 exception.ExceptionCollector.assertExceptionMessage(
582 exception.MissingRequiredFieldError, err9_msg)
584 err10_msg = _('Type "tosca.nodes.XYZ" is not a valid type.')
585 exception.ExceptionCollector.assertExceptionMessage(
586 exception.InvalidTypeError, err10_msg)
588 def test_invalid_section_names(self):
589 tosca_tpl = os.path.join(
590 os.path.dirname(os.path.abspath(__file__)),
591 "data/test_invalid_section_names.yaml")
592 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
594 err1_msg = _('Template contains unknown field '
595 '"tosca_definitions_versions". Refer to the definition '
596 'to verify valid values.')
597 exception.ExceptionCollector.assertExceptionMessage(
598 exception.UnknownFieldError, err1_msg)
600 err2_msg = _('Template contains unknown field "descriptions". '
601 'Refer to the definition to verify valid values.')
602 exception.ExceptionCollector.assertExceptionMessage(
603 exception.UnknownFieldError, err2_msg)
605 err3_msg = _('Template contains unknown field "import". Refer to '
606 'the definition to verify valid values.')
607 exception.ExceptionCollector.assertExceptionMessage(
608 exception.UnknownFieldError, err3_msg)
610 err4_msg = _('Template contains unknown field "topology_templates". '
611 'Refer to the definition to verify valid values.')
612 exception.ExceptionCollector.assertExceptionMessage(
613 exception.UnknownFieldError, err4_msg)
615 def test_csar_with_alternate_extenstion(self):
616 tosca_tpl = os.path.join(
617 os.path.dirname(os.path.abspath(__file__)),
618 "data/CSAR/csar_elk.csar")
619 tosca = ToscaTemplate(tosca_tpl, parsed_params={"my_cpus": 2})
620 self.assertTrue(tosca.topology_template.custom_defs)
622 def test_available_rel_tpls(self):
623 tosca_tpl = os.path.join(
624 os.path.dirname(os.path.abspath(__file__)),
625 "data/test_available_rel_tpls.yaml")
626 tosca = ToscaTemplate(tosca_tpl)
627 for node in tosca.nodetemplates:
628 for relationship, target in node.relationships.items():
631 except TypeError as error:
634 def test_no_input(self):
635 self.assertRaises(exception.ValidationError, ToscaTemplate, None,
637 err_msg = (('No path or yaml_dict_tpl was provided. '
638 'There is nothing to parse.'))
639 exception.ExceptionCollector.assertExceptionMessage(ValueError,
642 def test_path_and_yaml_dict_tpl_input(self):
643 test_tpl = os.path.join(
644 os.path.dirname(os.path.abspath(__file__)),
645 "data/tosca_helloworld.yaml")
647 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
649 tosca = ToscaTemplate(test_tpl, yaml_dict_tpl=yaml_dict_tpl)
651 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
653 def test_yaml_dict_tpl_input(self):
654 test_tpl = os.path.join(
655 os.path.dirname(os.path.abspath(__file__)),
656 "data/tosca_helloworld.yaml")
658 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
660 tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
662 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
664 def test_yaml_dict_tpl_with_params_and_url_import(self):
665 test_tpl = os.path.join(
666 os.path.dirname(os.path.abspath(__file__)),
667 "data/tosca_single_instance_wordpress_with_url_import.yaml")
669 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
671 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
672 'db_root_pwd': 'mypasswd'}
674 tosca = ToscaTemplate(parsed_params=params,
675 yaml_dict_tpl=yaml_dict_tpl)
677 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
679 def test_yaml_dict_tpl_with_rel_import(self):
680 test_tpl = os.path.join(
681 os.path.dirname(os.path.abspath(__file__)),
682 "data/tosca_single_instance_wordpress.yaml")
684 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
685 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
686 'db_root_pwd': '12345678'}
687 self.assertRaises(exception.ValidationError, ToscaTemplate, None,
688 params, False, yaml_dict_tpl)
689 err_msg = (_('Relative file name "custom_types/wordpress.yaml" '
690 'cannot be used in a pre-parsed input template.'))
691 exception.ExceptionCollector.assertExceptionMessage(ImportError,
694 def test_yaml_dict_tpl_with_fullpath_import(self):
695 test_tpl = os.path.join(
696 os.path.dirname(os.path.abspath(__file__)),
697 "data/tosca_single_instance_wordpress.yaml")
699 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
701 yaml_dict_tpl['imports'] = [os.path.join(os.path.dirname(
702 os.path.abspath(__file__)), "data/custom_types/wordpress.yaml")]
704 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
705 'db_root_pwd': 'mypasswd'}
707 tosca = ToscaTemplate(parsed_params=params,
708 yaml_dict_tpl=yaml_dict_tpl)
710 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
712 def test_policies_for_node_templates(self):
713 tosca_tpl = os.path.join(
714 os.path.dirname(os.path.abspath(__file__)),
715 "data/policies/tosca_policy_template.yaml")
716 tosca = ToscaTemplate(tosca_tpl)
718 for policy in tosca.topology_template.policies:
720 policy.is_derived_from("tosca.policies.Root"))
721 if policy.name == 'my_compute_placement_policy':
722 self.assertEqual('tosca.policies.Placement', policy.type)
723 self.assertEqual(['my_server_1', 'my_server_2'],
725 self.assertEqual('node_templates', policy.get_targets_type())
726 for node in policy.targets_list:
727 if node.name == 'my_server_1':
728 '''Test property value'''
729 props = node.get_properties()
730 if props and 'mem_size' in props.keys():
731 self.assertEqual(props['mem_size'].value,
734 def test_policies_for_groups(self):
735 tosca_tpl = os.path.join(
736 os.path.dirname(os.path.abspath(__file__)),
737 "data/policies/tosca_policy_template.yaml")
738 tosca = ToscaTemplate(tosca_tpl)
740 for policy in tosca.topology_template.policies:
742 policy.is_derived_from("tosca.policies.Root"))
743 if policy.name == 'my_groups_placement':
744 self.assertEqual('mycompany.mytypes.myScalingPolicy',
746 self.assertEqual(['webserver_group'], policy.targets)
747 self.assertEqual('groups', policy.get_targets_type())
748 group = policy.get_targets_list()[0]
749 for node in group.get_member_nodes():
750 if node.name == 'my_server_2':
751 '''Test property value'''
752 props = node.get_properties()
753 if props and 'mem_size' in props.keys():
754 self.assertEqual(props['mem_size'].value,
757 def test_node_filter(self):
758 tosca_tpl = os.path.join(
759 os.path.dirname(os.path.abspath(__file__)),
760 "data/node_filter/test_node_filter.yaml")
761 ToscaTemplate(tosca_tpl)
763 def test_attributes_inheritance(self):
764 tosca_tpl = os.path.join(
765 os.path.dirname(os.path.abspath(__file__)),
766 "data/test_attributes_inheritance.yaml")
767 ToscaTemplate(tosca_tpl)
769 def test_repositories_definition(self):
770 tosca_tpl = os.path.join(
771 os.path.dirname(os.path.abspath(__file__)),
772 "data/repositories/test_repositories_definition.yaml")
773 ToscaTemplate(tosca_tpl)
775 def test_custom_caps_def(self):
776 tosca_tpl = os.path.join(
777 os.path.dirname(os.path.abspath(__file__)),
778 "data/test_custom_caps_def.yaml")
779 ToscaTemplate(tosca_tpl)
781 def test_custom_rel_with_script(self):
782 tosca_tpl = os.path.join(
783 os.path.dirname(os.path.abspath(__file__)),
784 "data/test_tosca_custom_rel_with_script.yaml")
785 tosca = ToscaTemplate(tosca_tpl)
786 rel = tosca.relationship_templates[0]
787 self.assertEqual(rel.type, "tosca.relationships.HostedOn")
788 self.assertTrue(rel.is_derived_from("tosca.relationships.Root"))
789 self.assertEqual(len(rel.interfaces), 1)
790 self.assertEqual(rel.interfaces[0].type, "Configure")
792 def test_various_portspec_errors(self):
793 tosca_tpl = os.path.join(
794 os.path.dirname(os.path.abspath(__file__)),
795 "data/datatypes/test_datatype_portspec_add_req.yaml")
796 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
799 # TODO(TBD) find way to reuse error messages from constraints.py
800 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
801 'range "(min:%(vmin)s, max:%(vmax)s)".') %
802 dict(pname=PortSpec.SOURCE,
806 exception.ExceptionCollector.assertExceptionMessage(
807 exception.ValidationError, msg)
809 # Test value below range min.
810 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
811 'range "(min:%(vmin)s, max:%(vmax)s)".') %
812 dict(pname=PortSpec.SOURCE,
816 exception.ExceptionCollector.assertExceptionMessage(
817 exception.RangeValueError, msg)
819 # Test value above range max.
820 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
821 'range "(min:%(vmin)s, max:%(vmax)s)".') %
822 dict(pname=PortSpec.SOURCE,
826 exception.ExceptionCollector.assertExceptionMessage(
827 exception.RangeValueError, msg)
829 def test_containers(self):
830 tosca_tpl = os.path.join(
831 os.path.dirname(os.path.abspath(__file__)),
832 "data/containers/test_container_docker_mysql.yaml")
833 ToscaTemplate(tosca_tpl, parsed_params={"mysql_root_pwd": "12345678"})
835 def test_endpoint_on_compute(self):
836 tosca_tpl = os.path.join(
837 os.path.dirname(os.path.abspath(__file__)),
838 "data/test_endpoint_on_compute.yaml")
839 ToscaTemplate(tosca_tpl)
841 def test_nested_dsl_def(self):
842 tosca_tpl = os.path.join(
843 os.path.dirname(os.path.abspath(__file__)),
844 "data/dsl_definitions/test_nested_dsl_def.yaml")
845 self.assertIsNotNone(ToscaTemplate(tosca_tpl))
847 def test_multiple_policies(self):
848 tosca_tpl = os.path.join(
849 os.path.dirname(os.path.abspath(__file__)),
850 "data/policies/test_tosca_nfv_multiple_policies.yaml")
851 tosca = ToscaTemplate(tosca_tpl)
853 ['ALRM1', 'SP1', 'SP2'],
854 sorted([policy.name for policy in tosca.policies]))