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.\'')
575 exception.ExceptionCollector.assertExceptionMessage(
578 err9_msg = _('"relationship" used in template "webserver" is missing '
579 'required field "type".')
580 exception.ExceptionCollector.assertExceptionMessage(
581 exception.MissingRequiredFieldError, err9_msg)
583 err10_msg = _('Type "tosca.nodes.XYZ" is not a valid type.')
584 exception.ExceptionCollector.assertExceptionMessage(
585 exception.InvalidTypeError, err10_msg)
587 def test_invalid_section_names(self):
588 tosca_tpl = os.path.join(
589 os.path.dirname(os.path.abspath(__file__)),
590 "data/test_invalid_section_names.yaml")
591 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
593 err1_msg = _('Template contains unknown field '
594 '"tosca_definitions_versions". Refer to the definition '
595 'to verify valid values.')
596 exception.ExceptionCollector.assertExceptionMessage(
597 exception.UnknownFieldError, err1_msg)
599 err2_msg = _('Template contains unknown field "descriptions". '
600 'Refer to the definition to verify valid values.')
601 exception.ExceptionCollector.assertExceptionMessage(
602 exception.UnknownFieldError, err2_msg)
604 err3_msg = _('Template contains unknown field "import". Refer to '
605 'the definition to verify valid values.')
606 exception.ExceptionCollector.assertExceptionMessage(
607 exception.UnknownFieldError, err3_msg)
609 err4_msg = _('Template contains unknown field "topology_templates". '
610 'Refer to the definition to verify valid values.')
611 exception.ExceptionCollector.assertExceptionMessage(
612 exception.UnknownFieldError, err4_msg)
614 def test_csar_with_alternate_extenstion(self):
615 tosca_tpl = os.path.join(
616 os.path.dirname(os.path.abspath(__file__)),
617 "data/CSAR/csar_elk.csar")
618 tosca = ToscaTemplate(tosca_tpl, parsed_params={"my_cpus": 2})
619 self.assertTrue(tosca.topology_template.custom_defs)
621 def test_available_rel_tpls(self):
622 tosca_tpl = os.path.join(
623 os.path.dirname(os.path.abspath(__file__)),
624 "data/test_available_rel_tpls.yaml")
625 tosca = ToscaTemplate(tosca_tpl)
626 for node in tosca.nodetemplates:
627 for relationship, target in node.relationships.items():
630 except TypeError as error:
633 def test_no_input(self):
634 self.assertRaises(exception.ValidationError, ToscaTemplate, None,
636 err_msg = (('No path or yaml_dict_tpl was provided. '
637 'There is nothing to parse.'))
638 exception.ExceptionCollector.assertExceptionMessage(ValueError,
641 def test_path_and_yaml_dict_tpl_input(self):
642 test_tpl = os.path.join(
643 os.path.dirname(os.path.abspath(__file__)),
644 "data/tosca_helloworld.yaml")
646 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
648 tosca = ToscaTemplate(test_tpl, yaml_dict_tpl=yaml_dict_tpl)
650 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
652 def test_yaml_dict_tpl_input(self):
653 test_tpl = os.path.join(
654 os.path.dirname(os.path.abspath(__file__)),
655 "data/tosca_helloworld.yaml")
657 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
659 tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
661 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
663 def test_yaml_dict_tpl_with_params_and_url_import(self):
664 test_tpl = os.path.join(
665 os.path.dirname(os.path.abspath(__file__)),
666 "data/tosca_single_instance_wordpress_with_url_import.yaml")
668 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
670 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
671 'db_root_pwd': 'mypasswd'}
673 tosca = ToscaTemplate(parsed_params=params,
674 yaml_dict_tpl=yaml_dict_tpl)
676 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
678 def test_yaml_dict_tpl_with_rel_import(self):
679 test_tpl = os.path.join(
680 os.path.dirname(os.path.abspath(__file__)),
681 "data/tosca_single_instance_wordpress.yaml")
683 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
684 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
685 'db_root_pwd': '12345678'}
686 self.assertRaises(exception.ValidationError, ToscaTemplate, None,
687 params, False, yaml_dict_tpl)
688 err_msg = (_('Relative file name "custom_types/wordpress.yaml" '
689 'cannot be used in a pre-parsed input template.'))
690 exception.ExceptionCollector.assertExceptionMessage(ImportError,
693 def test_yaml_dict_tpl_with_fullpath_import(self):
694 test_tpl = os.path.join(
695 os.path.dirname(os.path.abspath(__file__)),
696 "data/tosca_single_instance_wordpress.yaml")
698 yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
700 yaml_dict_tpl['imports'] = [os.path.join(os.path.dirname(
701 os.path.abspath(__file__)), "data/custom_types/wordpress.yaml")]
703 params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
704 'db_root_pwd': 'mypasswd'}
706 tosca = ToscaTemplate(parsed_params=params,
707 yaml_dict_tpl=yaml_dict_tpl)
709 self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
711 def test_policies_for_node_templates(self):
712 tosca_tpl = os.path.join(
713 os.path.dirname(os.path.abspath(__file__)),
714 "data/policies/tosca_policy_template.yaml")
715 tosca = ToscaTemplate(tosca_tpl)
717 for policy in tosca.topology_template.policies:
719 policy.is_derived_from("tosca.policies.Root"))
720 if policy.name == 'my_compute_placement_policy':
721 self.assertEqual('tosca.policies.Placement', policy.type)
722 self.assertEqual(['my_server_1', 'my_server_2'],
724 self.assertEqual('node_templates', policy.get_targets_type())
725 for node in policy.targets_list:
726 if node.name == 'my_server_1':
727 '''Test property value'''
728 props = node.get_properties()
729 if props and 'mem_size' in props.keys():
730 self.assertEqual(props['mem_size'].value,
733 def test_policies_for_groups(self):
734 tosca_tpl = os.path.join(
735 os.path.dirname(os.path.abspath(__file__)),
736 "data/policies/tosca_policy_template.yaml")
737 tosca = ToscaTemplate(tosca_tpl)
739 for policy in tosca.topology_template.policies:
741 policy.is_derived_from("tosca.policies.Root"))
742 if policy.name == 'my_groups_placement':
743 self.assertEqual('mycompany.mytypes.myScalingPolicy',
745 self.assertEqual(['webserver_group'], policy.targets)
746 self.assertEqual('groups', policy.get_targets_type())
747 group = policy.get_targets_list()[0]
748 for node in group.get_member_nodes():
749 if node.name == 'my_server_2':
750 '''Test property value'''
751 props = node.get_properties()
752 if props and 'mem_size' in props.keys():
753 self.assertEqual(props['mem_size'].value,
756 def test_node_filter(self):
757 tosca_tpl = os.path.join(
758 os.path.dirname(os.path.abspath(__file__)),
759 "data/node_filter/test_node_filter.yaml")
760 ToscaTemplate(tosca_tpl)
762 def test_attributes_inheritance(self):
763 tosca_tpl = os.path.join(
764 os.path.dirname(os.path.abspath(__file__)),
765 "data/test_attributes_inheritance.yaml")
766 ToscaTemplate(tosca_tpl)
768 def test_repositories_definition(self):
769 tosca_tpl = os.path.join(
770 os.path.dirname(os.path.abspath(__file__)),
771 "data/repositories/test_repositories_definition.yaml")
772 ToscaTemplate(tosca_tpl)
774 def test_custom_caps_def(self):
775 tosca_tpl = os.path.join(
776 os.path.dirname(os.path.abspath(__file__)),
777 "data/test_custom_caps_def.yaml")
778 ToscaTemplate(tosca_tpl)
780 def test_custom_rel_with_script(self):
781 tosca_tpl = os.path.join(
782 os.path.dirname(os.path.abspath(__file__)),
783 "data/test_tosca_custom_rel_with_script.yaml")
784 tosca = ToscaTemplate(tosca_tpl)
785 rel = tosca.relationship_templates[0]
786 self.assertEqual(rel.type, "tosca.relationships.HostedOn")
787 self.assertTrue(rel.is_derived_from("tosca.relationships.Root"))
788 self.assertEqual(len(rel.interfaces), 1)
789 self.assertEqual(rel.interfaces[0].type, "Configure")
791 def test_various_portspec_errors(self):
792 tosca_tpl = os.path.join(
793 os.path.dirname(os.path.abspath(__file__)),
794 "data/datatypes/test_datatype_portspec_add_req.yaml")
795 self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
798 # TODO(TBD) find way to reuse error messages from constraints.py
799 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
800 'range "(min:%(vmin)s, max:%(vmax)s)".') %
801 dict(pname=PortSpec.SOURCE,
805 exception.ExceptionCollector.assertExceptionMessage(
806 exception.ValidationError, msg)
808 # Test value below range min.
809 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
810 'range "(min:%(vmin)s, max:%(vmax)s)".') %
811 dict(pname=PortSpec.SOURCE,
815 exception.ExceptionCollector.assertExceptionMessage(
816 exception.RangeValueError, msg)
818 # Test value above range max.
819 msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of '
820 'range "(min:%(vmin)s, max:%(vmax)s)".') %
821 dict(pname=PortSpec.SOURCE,
825 exception.ExceptionCollector.assertExceptionMessage(
826 exception.RangeValueError, msg)
828 def test_containers(self):
829 tosca_tpl = os.path.join(
830 os.path.dirname(os.path.abspath(__file__)),
831 "data/containers/test_container_docker_mysql.yaml")
832 ToscaTemplate(tosca_tpl, parsed_params={"mysql_root_pwd": "12345678"})
834 def test_endpoint_on_compute(self):
835 tosca_tpl = os.path.join(
836 os.path.dirname(os.path.abspath(__file__)),
837 "data/test_endpoint_on_compute.yaml")
838 ToscaTemplate(tosca_tpl)
840 def test_nested_dsl_def(self):
841 tosca_tpl = os.path.join(
842 os.path.dirname(os.path.abspath(__file__)),
843 "data/dsl_definitions/test_nested_dsl_def.yaml")
844 self.assertIsNotNone(ToscaTemplate(tosca_tpl))
846 def test_multiple_policies(self):
847 tosca_tpl = os.path.join(
848 os.path.dirname(os.path.abspath(__file__)),
849 "data/policies/test_tosca_nfv_multiple_policies.yaml")
850 tosca = ToscaTemplate(tosca_tpl)
852 ['ALRM1', 'SP1', 'SP2'],
853 sorted([policy.name for policy in tosca.policies]))