Merge "EntityTemplate has no property of parent_type"
[parser.git] / tosca2heat / tosca-parser / toscaparser / tests / test_toscatpl.py
1 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
2 #    not use this file except in compliance with the License. You may obtain
3 #    a copy of the License at
4 #
5 #         http://www.apache.org/licenses/LICENSE-2.0
6 #
7 #    Unless required by applicable law or agreed to in writing, software
8 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 #    License for the specific language governing permissions and limitations
11 #    under the License.
12
13 import os
14 import six
15
16 from toscaparser.common import exception
17 import toscaparser.elements.interfaces as ifaces
18 from toscaparser.elements.nodetype import NodeType
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
26
27
28 class ToscaTemplateTest(TestCase):
29
30     '''TOSCA template.'''
31     tosca_tpl = os.path.join(
32         os.path.dirname(os.path.abspath(__file__)),
33         "data/tosca_single_instance_wordpress.yaml")
34     tosca = ToscaTemplate(tosca_tpl)
35
36     tosca_elk_tpl = os.path.join(
37         os.path.dirname(os.path.abspath(__file__)),
38         "data/tosca_elk.yaml")
39
40     def test_version(self):
41         self.assertEqual(self.tosca.version, "tosca_simple_yaml_1_0")
42
43     def test_description(self):
44         expected_description = "TOSCA simple profile with wordpress, " \
45                                "web server and mysql on the same server."
46         self.assertEqual(self.tosca.description, expected_description)
47
48     def test_inputs(self):
49         self.assertEqual(
50             ['cpus', 'db_name', 'db_port',
51              'db_pwd', 'db_root_pwd', 'db_user'],
52             sorted([input.name for input in self.tosca.inputs]))
53
54         input_name = "db_port"
55         expected_description = "Port for the MySQL database."
56         for input in self.tosca.inputs:
57             if input.name == input_name:
58                 self.assertEqual(input.description, expected_description)
59
60     def test_node_tpls(self):
61         '''Test nodetemplate names.'''
62         self.assertEqual(
63             ['mysql_database', 'mysql_dbms', 'server',
64              'webserver', 'wordpress'],
65             sorted([tpl.name for tpl in self.tosca.nodetemplates]))
66
67         tpl_name = "mysql_database"
68         expected_type = "tosca.nodes.Database"
69         expected_properties = ['name', 'password', 'user']
70         expected_capabilities = ['database_endpoint', 'feature']
71         expected_requirements = [{'host': 'mysql_dbms'}]
72         ''' TODO: needs enhancement in tosca_elk.yaml..
73         expected_relationshp = ['tosca.relationships.HostedOn']
74         expected_host = ['mysql_dbms']
75         '''
76         expected_interface = [ifaces.LIFECYCLE_SHORTNAME]
77
78         for tpl in self.tosca.nodetemplates:
79             if tpl_name == tpl.name:
80                 '''Test node type.'''
81                 self.assertEqual(tpl.type, expected_type)
82
83                 '''Test properties.'''
84                 self.assertEqual(
85                     expected_properties,
86                     sorted(tpl.get_properties().keys()))
87
88                 '''Test capabilities.'''
89                 self.assertEqual(
90                     expected_capabilities,
91                     sorted(tpl.get_capabilities().keys()))
92
93                 '''Test requirements.'''
94                 self.assertEqual(
95                     expected_requirements, tpl.requirements)
96
97                 '''Test relationship.'''
98                 ''' needs enhancements in tosca_elk.yaml
99                 self.assertEqual(
100                     expected_relationshp,
101                     [x.type for x in tpl.relationships.keys()])
102                 self.assertEqual(
103                     expected_host,
104                     [y.name for y in tpl.relationships.values()])
105                 '''
106                 '''Test interfaces.'''
107                 self.assertEqual(
108                     expected_interface,
109                     [x.type for x in tpl.interfaces])
110
111             if tpl.name == 'server':
112                 '''Test property value'''
113                 props = tpl.get_properties()
114                 if props and 'mem_size' in props.keys():
115                     self.assertEqual(props['mem_size'].value, '4096 MB')
116                 '''Test capability'''
117                 caps = tpl.get_capabilities()
118                 self.assertIn('os', caps.keys())
119                 os_props_objs = None
120                 os_props = None
121                 os_type_prop = None
122                 if caps and 'os' in caps.keys():
123                     capability = caps['os']
124                     os_props_objs = capability.get_properties_objects()
125                     os_props = capability.get_properties()
126                     os_type_prop = capability.get_property_value('type')
127                     break
128                 self.assertEqual(
129                     ['Linux'],
130                     [p.value for p in os_props_objs if p.name == 'type'])
131                 self.assertEqual(
132                     'Linux',
133                     os_props['type'].value if 'type' in os_props else '')
134                 self.assertEqual('Linux', os_props['type'].value)
135                 self.assertEqual('Linux', os_type_prop)
136
137     def test_node_inheritance_type(self):
138         wordpress_node = [
139             node for node in self.tosca.nodetemplates
140             if node.name == 'wordpress'][0]
141         self.assertTrue(
142             wordpress_node.is_derived_from("tosca.nodes.WebApplication"))
143         self.assertTrue(
144             wordpress_node.is_derived_from("tosca.nodes.Root"))
145         self.assertFalse(
146             wordpress_node.is_derived_from("tosca.policies.Root"))
147         self.assertFalse(
148             wordpress_node.is_derived_from("tosca.groups.Root"))
149
150     def test_outputs(self):
151         self.assertEqual(
152             ['website_url'],
153             sorted([output.name for output in self.tosca.outputs]))
154
155     def test_interfaces(self):
156         wordpress_node = [
157             node for node in self.tosca.nodetemplates
158             if node.name == 'wordpress'][0]
159         interfaces = wordpress_node.interfaces
160         self.assertEqual(2, len(interfaces))
161         for interface in interfaces:
162             if interface.name == 'create':
163                 self.assertEqual(ifaces.LIFECYCLE_SHORTNAME,
164                                  interface.type)
165                 self.assertEqual('wordpress/wordpress_install.sh',
166                                  interface.implementation)
167                 self.assertIsNone(interface.inputs)
168             elif interface.name == 'configure':
169                 self.assertEqual(ifaces.LIFECYCLE_SHORTNAME,
170                                  interface.type)
171                 self.assertEqual('wordpress/wordpress_configure.sh',
172                                  interface.implementation)
173                 self.assertEqual(3, len(interface.inputs))
174                 TestCase.skip(self, 'bug #1440247')
175                 wp_db_port = interface.inputs['wp_db_port']
176                 self.assertTrue(isinstance(wp_db_port, GetProperty))
177                 self.assertEqual('get_property', wp_db_port.name)
178                 self.assertEqual(['SELF',
179                                   'database_endpoint',
180                                   'port'],
181                                  wp_db_port.args)
182                 result = wp_db_port.result()
183                 self.assertTrue(isinstance(result, GetInput))
184             else:
185                 raise AssertionError(
186                     'Unexpected interface: {0}'.format(interface.name))
187
188     def test_normative_type_by_short_name(self):
189         # test template with a short name Compute
190         template = os.path.join(
191             os.path.dirname(os.path.abspath(__file__)),
192             "data/test_tosca_normative_type_by_shortname.yaml")
193
194         tosca_tpl = ToscaTemplate(template)
195         expected_type = "tosca.nodes.Compute"
196         for tpl in tosca_tpl.nodetemplates:
197             self.assertEqual(tpl.type, expected_type)
198         for tpl in tosca_tpl.nodetemplates:
199             compute_type = NodeType(tpl.type)
200             self.assertEqual(
201                 sorted(['tosca.capabilities.Container',
202                         'tosca.capabilities.Node',
203                         'tosca.capabilities.OperatingSystem',
204                         'tosca.capabilities.network.Bindable',
205                         'tosca.capabilities.Scalable']),
206                 sorted([c.type
207                         for c in compute_type.get_capabilities_objects()]))
208
209     def test_template_with_no_inputs(self):
210         tosca_tpl = self._load_template('test_no_inputs_in_template.yaml')
211         self.assertEqual(0, len(tosca_tpl.inputs))
212
213     def test_template_with_no_outputs(self):
214         tosca_tpl = self._load_template('test_no_outputs_in_template.yaml')
215         self.assertEqual(0, len(tosca_tpl.outputs))
216
217     def test_relationship_interface(self):
218         template = ToscaTemplate(self.tosca_elk_tpl)
219         for node_tpl in template.nodetemplates:
220             if node_tpl.name == 'logstash':
221                 config_interface = 'Configure'
222                 artifact = 'logstash/configure_elasticsearch.py'
223                 relation = node_tpl.relationships
224                 for key in relation.keys():
225                     rel_tpl = relation.get(key).get_relationship_template()
226                     if rel_tpl:
227                         self.assertEqual(
228                             rel_tpl[0].type, "tosca.relationships.ConnectsTo")
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,
234                                              interface.type)
235                             self.assertEqual('pre_configure_source',
236                                              interface.name)
237                             self.assertEqual(artifact,
238                                              interface.implementation)
239
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)
249                 self.assertEqual(
250                     expected_relationships,
251                     sorted([k.type for k in node_tpl.relationships.keys()]))
252                 self.assertEqual(
253                     expected_hosts,
254                     sorted([v.type for v in node_tpl.relationships.values()]))
255
256     def test_template_macro(self):
257         template = ToscaTemplate(self.tosca_elk_tpl)
258         for node_tpl in template.nodetemplates:
259             if node_tpl.name == 'mongo_server':
260                 self.assertEqual(
261                     ['disk_size', 'mem_size', 'num_cpus'],
262                     sorted(node_tpl.get_capability('host').
263                            get_properties().keys()))
264
265     def test_template_requirements(self):
266         """Test different formats of requirements
267
268         The requirements can be defined in few different ways,
269         1. Requirement expressed as a capability with an implicit relationship.
270         2. Requirement expressed with explicit relationship.
271         3. Requirement expressed with a relationship template.
272         4. Requirement expressed via TOSCA types to provision a node
273            with explicit relationship.
274         5. Requirement expressed via TOSCA types with a filter.
275         """
276         tosca_tpl = os.path.join(
277             os.path.dirname(os.path.abspath(__file__)),
278             "data/test_requirements.yaml")
279         tosca = ToscaTemplate(tosca_tpl)
280         for node_tpl in tosca.nodetemplates:
281             if node_tpl.name == 'my_app':
282                 expected_relationship = [
283                     ('tosca.relationships.ConnectsTo', 'mysql_database'),
284                     ('tosca.relationships.HostedOn', 'my_webserver')]
285                 actual_relationship = sorted([
286                     (relation.type, node.name) for
287                     relation, node in node_tpl.relationships.items()])
288                 self.assertEqual(expected_relationship, actual_relationship)
289             if node_tpl.name == 'mysql_database':
290                     self.assertEqual(
291                         [('tosca.relationships.HostedOn', 'my_dbms')],
292                         [(relation.type, node.name) for
293                          relation,
294                          node in node_tpl.relationships.items()])
295             if node_tpl.name == 'my_server':
296                     self.assertEqual(
297                         [('tosca.relationships.AttachesTo', 'my_storage')],
298                         [(relation.type, node.name) for
299                          relation,
300                          node in node_tpl.relationships.items()])
301
302     def test_template_requirements_not_implemented(self):
303         # TODO(spzala): replace this test with new one once TOSCA types look up
304         # support is implemented.
305         """Requirements that yet need to be implemented
306
307         The following requirement formats are not yet implemented,
308         due to look up dependency:
309         1. Requirement expressed via TOSCA types to provision a node
310            with explicit relationship.
311         2. Requirement expressed via TOSCA types with a filter.
312         """
313         tpl_snippet_1 = '''
314         node_templates:
315           mysql_database:
316             type: tosca.nodes.Database
317             description: Requires a particular node type and relationship.
318                         To be full-filled via lookup into node repository.
319             requirements:
320               - req1:
321                   node: tosca.nodes.DBMS
322                   relationship: tosca.relationships.HostedOn
323         '''
324
325         tpl_snippet_2 = '''
326         node_templates:
327           my_webserver:
328             type: tosca.nodes.WebServer
329             description: Requires a particular node type with a filter.
330                          To be full-filled via lookup into node repository.
331             requirements:
332               - req1:
333                   node: tosca.nodes.Compute
334                   target_filter:
335                     properties:
336                       num_cpus: { in_range: [ 1, 4 ] }
337                       mem_size: { greater_or_equal: 2 }
338                     capabilities:
339                       - tosca.capabilities.OS:
340                           properties:
341                             architecture: x86_64
342                             type: linux
343         '''
344
345         tpl_snippet_3 = '''
346         node_templates:
347           my_webserver2:
348             type: tosca.nodes.WebServer
349             description: Requires a node type with a particular capability.
350                          To be full-filled via lookup into node repository.
351             requirements:
352               - req1:
353                   node: tosca.nodes.Compute
354                   relationship: tosca.relationships.HostedOn
355                   capability: tosca.capabilities.Container
356         '''
357         self._requirements_not_implemented(tpl_snippet_1, 'mysql_database')
358         self._requirements_not_implemented(tpl_snippet_2, 'my_webserver')
359         self._requirements_not_implemented(tpl_snippet_3, 'my_webserver2')
360
361     def _requirements_not_implemented(self, tpl_snippet, tpl_name):
362         nodetemplates = (toscaparser.utils.yamlparser.
363                          simple_parse(tpl_snippet))['node_templates']
364         self.assertRaises(
365             NotImplementedError,
366             lambda: NodeTemplate(tpl_name, nodetemplates).relationships)
367
368     # Test the following:
369     # 1. Custom node type derived from 'WebApplication' named 'TestApp'
370     #    with a custom Capability Type 'TestCapability'
371     # 2. Same as #1, but referencing a custom 'TestCapability' Capability Type
372     #    that is not defined
373     def test_custom_capability_type_definition(self):
374         tpl_snippet = '''
375         node_templates:
376           test_app:
377             type: tosca.nodes.WebApplication.TestApp
378             capabilities:
379               test_cap:
380                 properties:
381                   test: 1
382         '''
383         # custom node type definition with custom capability type definition
384         custom_def = '''
385         tosca.nodes.WebApplication.TestApp:
386           derived_from: tosca.nodes.WebApplication
387           capabilities:
388             test_cap:
389                type: tosca.capabilities.TestCapability
390         tosca.capabilities.TestCapability:
391           derived_from: tosca.capabilities.Root
392           properties:
393             test:
394               type: integer
395               required: false
396         '''
397         expected_capabilities = ['app_endpoint', 'feature', 'test_cap']
398         nodetemplates = (toscaparser.utils.yamlparser.
399                          simple_parse(tpl_snippet))['node_templates']
400         custom_def = (toscaparser.utils.yamlparser.
401                       simple_parse(custom_def))
402         name = list(nodetemplates.keys())[0]
403         tpl = NodeTemplate(name, nodetemplates, custom_def)
404         self.assertEqual(
405             expected_capabilities,
406             sorted(tpl.get_capabilities().keys()))
407
408         # custom definition without valid capability type definition
409         custom_def = '''
410         tosca.nodes.WebApplication.TestApp:
411           derived_from: tosca.nodes.WebApplication
412           capabilities:
413             test_cap:
414                type: tosca.capabilities.TestCapability
415         '''
416         custom_def = (toscaparser.utils.yamlparser.
417                       simple_parse(custom_def))
418         tpl = NodeTemplate(name, nodetemplates, custom_def)
419         err = self.assertRaises(
420             exception.InvalidTypeError,
421             lambda: NodeTemplate(name, nodetemplates,
422                                  custom_def).get_capabilities_objects())
423         self.assertEqual('Type "tosca.capabilities.TestCapability" is not '
424                          'a valid type.', six.text_type(err))
425
426     def test_local_template_with_local_relpath_import(self):
427         tosca_tpl = os.path.join(
428             os.path.dirname(os.path.abspath(__file__)),
429             "data/tosca_single_instance_wordpress.yaml")
430         tosca = ToscaTemplate(tosca_tpl)
431         self.assertTrue(tosca.topology_template.custom_defs)
432
433     def test_local_template_with_url_import(self):
434         tosca_tpl = os.path.join(
435             os.path.dirname(os.path.abspath(__file__)),
436             "data/tosca_single_instance_wordpress_with_url_import.yaml")
437         tosca = ToscaTemplate(tosca_tpl)
438         self.assertTrue(tosca.topology_template.custom_defs)
439
440     def test_url_template_with_local_relpath_import(self):
441         tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
442                      'tosca-parser/master/toscaparser/tests/data/'
443                      'tosca_single_instance_wordpress.yaml')
444         tosca = ToscaTemplate(tosca_tpl, None, False)
445         self.assertTrue(tosca.topology_template.custom_defs)
446
447     def test_url_template_with_local_abspath_import(self):
448         tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
449                      'tosca-parser/master/toscaparser/tests/data/'
450                      'tosca_single_instance_wordpress_with_local_abspath_'
451                      'import.yaml')
452         self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
453                           None, False)
454         err_msg = (_('Absolute file name "/tmp/tosca-parser/toscaparser/tests'
455                      '/data/custom_types/wordpress.yaml" cannot be used in a '
456                      'URL-based input template "%(tpl)s".')
457                    % {'tpl': tosca_tpl})
458         exception.ExceptionCollector.assertExceptionMessage(ImportError,
459                                                             err_msg)
460
461     def test_url_template_with_url_import(self):
462         tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
463                      'tosca-parser/master/toscaparser/tests/data/'
464                      'tosca_single_instance_wordpress_with_url_import.yaml')
465         tosca = ToscaTemplate(tosca_tpl, None, False)
466         self.assertTrue(tosca.topology_template.custom_defs)
467
468     def test_csar_parsing_wordpress(self):
469         csar_archive = os.path.join(
470             os.path.dirname(os.path.abspath(__file__)),
471             'data/CSAR/csar_wordpress.zip')
472         self.assertTrue(ToscaTemplate(csar_archive))
473
474     def test_csar_parsing_elk_url_based(self):
475         csar_archive = ('https://github.com/openstack/tosca-parser/raw/master/'
476                         'toscaparser/tests/data/CSAR/csar_elk.zip')
477         self.assertTrue(ToscaTemplate(csar_archive, None, False))
478
479     def test_nested_imports_in_templates(self):
480         tosca_tpl = os.path.join(
481             os.path.dirname(os.path.abspath(__file__)),
482             "data/test_instance_nested_imports.yaml")
483         tosca = ToscaTemplate(tosca_tpl)
484         expected_custom_types = ['tosca.nodes.WebApplication.WordPress',
485                                  'test_namespace_prefix.Rsyslog',
486                                  'Test2ndRsyslogType',
487                                  'test_2nd_namespace_prefix.Rsyslog',
488                                  'tosca.nodes.SoftwareComponent.Logstash',
489                                  'tosca.nodes.SoftwareComponent.Rsyslog.'
490                                  'TestRsyslogType']
491         self.assertItemsEqual(tosca.topology_template.custom_defs.keys(),
492                               expected_custom_types)
493
494     def test_invalid_template_file(self):
495         template_file = 'invalid template file'
496         expected_msg = (_('"%s" is not a valid file.') % template_file)
497         self.assertRaises(
498             exception.ValidationError,
499             ToscaTemplate, template_file, None, False)
500         exception.ExceptionCollector.assertExceptionMessage(ValueError,
501                                                             expected_msg)
502
503     def test_multiple_validation_errors(self):
504         tosca_tpl = os.path.join(
505             os.path.dirname(os.path.abspath(__file__)),
506             "data/test_multiple_validation_errors.yaml")
507         self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
508                           None)
509         valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS)
510         err1_msg = (_('The template version "tosca_simple_yaml_1" is invalid. '
511                       'Valid versions are "%s".') % valid_versions)
512         exception.ExceptionCollector.assertExceptionMessage(
513             exception.InvalidTemplateVersion, err1_msg)
514
515         err2_msg = _('Import "custom_types/not_there.yaml" is not valid.')
516         exception.ExceptionCollector.assertExceptionMessage(
517             ImportError, err2_msg)
518
519         err3_msg = _('Type "tosca.nodes.WebApplication.WordPress" is not a '
520                      'valid type.')
521         exception.ExceptionCollector.assertExceptionMessage(
522             exception.InvalidTypeError, err3_msg)
523
524         err4_msg = _('Node template "wordpress" contains unknown field '
525                      '"requirement". Refer to the definition to verify valid '
526                      'values.')
527         exception.ExceptionCollector.assertExceptionMessage(
528             exception.UnknownFieldError, err4_msg)
529
530         err5_msg = _('\'Property "passwords" was not found in node template '
531                      '"mysql_database".\'')
532         exception.ExceptionCollector.assertExceptionMessage(
533             KeyError, err5_msg)
534
535         err6_msg = _('Template "mysql_dbms" is missing required field "type".')
536         exception.ExceptionCollector.assertExceptionMessage(
537             exception.MissingRequiredFieldError, err6_msg)
538
539         err7_msg = _('Node template "mysql_dbms" contains unknown field '
540                      '"type1". Refer to the definition to verify valid '
541                      'values.')
542         exception.ExceptionCollector.assertExceptionMessage(
543             exception.UnknownFieldError, err7_msg)
544
545         err8_msg = _('\'Node template "server1" was not found.\'')
546         exception.ExceptionCollector.assertExceptionMessage(
547             KeyError, err8_msg)
548
549         err9_msg = _('"relationship" used in template "webserver" is missing '
550                      'required field "type".')
551         exception.ExceptionCollector.assertExceptionMessage(
552             exception.MissingRequiredFieldError, err9_msg)
553
554     def test_invalid_section_names(self):
555         tosca_tpl = os.path.join(
556             os.path.dirname(os.path.abspath(__file__)),
557             "data/test_invalid_section_names.yaml")
558         self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
559                           None)
560         err1_msg = _('Template contains unknown field '
561                      '"tosca_definitions_versions". Refer to the definition '
562                      'to verify valid values.')
563         exception.ExceptionCollector.assertExceptionMessage(
564             exception.UnknownFieldError, err1_msg)
565
566         err2_msg = _('Template contains unknown field "descriptions". '
567                      'Refer to the definition to verify valid values.')
568         exception.ExceptionCollector.assertExceptionMessage(
569             exception.UnknownFieldError, err2_msg)
570
571         err3_msg = _('Template contains unknown field "import". Refer to '
572                      'the definition to verify valid values.')
573         exception.ExceptionCollector.assertExceptionMessage(
574             exception.UnknownFieldError, err3_msg)
575
576         err4_msg = _('Template contains unknown field "topology_templates". '
577                      'Refer to the definition to verify valid values.')
578         exception.ExceptionCollector.assertExceptionMessage(
579             exception.UnknownFieldError, err4_msg)
580
581     def test_csar_with_alternate_extenstion(self):
582         tosca_tpl = os.path.join(
583             os.path.dirname(os.path.abspath(__file__)),
584             "data/CSAR/csar_elk.csar")
585         tosca = ToscaTemplate(tosca_tpl)
586         self.assertTrue(tosca.topology_template.custom_defs)
587
588     def test_available_rel_tpls(self):
589         tosca_tpl = os.path.join(
590             os.path.dirname(os.path.abspath(__file__)),
591             "data/test_available_rel_tpls.yaml")
592         tosca = ToscaTemplate(tosca_tpl)
593         for node in tosca.nodetemplates:
594             for relationship, target in node.relationships.items():
595                 try:
596                     target.relationships
597                 except TypeError as error:
598                     self.fail(error)
599
600     def test_no_input(self):
601         self.assertRaises(exception.ValidationError, ToscaTemplate, None,
602                           None, False, None)
603         err_msg = (('No path or yaml_dict_tpl was provided. '
604                     'There is nothing to parse.'))
605         exception.ExceptionCollector.assertExceptionMessage(ValueError,
606                                                             err_msg)
607
608     def test_path_and_yaml_dict_tpl_input(self):
609         test_tpl = os.path.join(
610             os.path.dirname(os.path.abspath(__file__)),
611             "data/tosca_helloworld.yaml")
612
613         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
614
615         tosca = ToscaTemplate(test_tpl, yaml_dict_tpl=yaml_dict_tpl)
616
617         self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
618
619     def test_yaml_dict_tpl_input(self):
620         test_tpl = os.path.join(
621             os.path.dirname(os.path.abspath(__file__)),
622             "data/tosca_helloworld.yaml")
623
624         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
625
626         tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
627
628         self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
629
630     def test_yaml_dict_tpl_with_params_and_url_import(self):
631         test_tpl = os.path.join(
632             os.path.dirname(os.path.abspath(__file__)),
633             "data/tosca_single_instance_wordpress_with_url_import.yaml")
634
635         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
636
637         params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
638                   'db_root_pwd': 'mypasswd'}
639
640         tosca = ToscaTemplate(parsed_params=params,
641                               yaml_dict_tpl=yaml_dict_tpl)
642
643         self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
644
645     def test_yaml_dict_tpl_with_rel_import(self):
646         test_tpl = os.path.join(
647             os.path.dirname(os.path.abspath(__file__)),
648             "data/tosca_single_instance_wordpress.yaml")
649
650         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
651
652         self.assertRaises(exception.ValidationError, ToscaTemplate, None,
653                           None, False, yaml_dict_tpl)
654         err_msg = (_('Relative file name "custom_types/wordpress.yaml" '
655                      'cannot be used in a pre-parsed input template.'))
656         exception.ExceptionCollector.assertExceptionMessage(ImportError,
657                                                             err_msg)
658
659     def test_yaml_dict_tpl_with_fullpath_import(self):
660         test_tpl = os.path.join(
661             os.path.dirname(os.path.abspath(__file__)),
662             "data/tosca_single_instance_wordpress.yaml")
663
664         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
665
666         yaml_dict_tpl['imports'] = [os.path.join(os.path.dirname(
667             os.path.abspath(__file__)), "data/custom_types/wordpress.yaml")]
668
669         params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
670                   'db_root_pwd': 'mypasswd'}
671
672         tosca = ToscaTemplate(parsed_params=params,
673                               yaml_dict_tpl=yaml_dict_tpl)
674
675         self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
676
677     def test_policies_for_node_templates(self):
678         tosca_tpl = os.path.join(
679             os.path.dirname(os.path.abspath(__file__)),
680             "data/policies/tosca_policy_template.yaml")
681         tosca = ToscaTemplate(tosca_tpl)
682
683         for policy in tosca.topology_template.policies:
684             if policy.name == 'my_compute_placement_policy':
685                 self.assertEqual('tosca.policies.Placement', policy.type)
686                 self.assertEqual(['my_server_1', 'my_server_2'],
687                                  policy.targets)
688                 self.assertEqual('node_templates', policy.get_targets_type())
689                 for node in policy.targets_list:
690                     if node.name == 'my_server_1':
691                         '''Test property value'''
692                         props = node.get_properties()
693                         if props and 'mem_size' in props.keys():
694                             self.assertEqual(props['mem_size'].value,
695                                              '4096 MB')
696
697     def test_policies_for_groups(self):
698         tosca_tpl = os.path.join(
699             os.path.dirname(os.path.abspath(__file__)),
700             "data/policies/tosca_policy_template.yaml")
701         tosca = ToscaTemplate(tosca_tpl)
702
703         for policy in tosca.topology_template.policies:
704             if policy.name == 'my_groups_placement':
705                 self.assertEqual('mycompany.mytypes.myScalingPolicy',
706                                  policy.type)
707                 self.assertEqual(['webserver_group'], policy.targets)
708                 self.assertEqual('groups', policy.get_targets_type())
709                 group = policy.get_targets_list()[0]
710                 for node in group.get_member_nodes():
711                     if node.name == 'my_server_2':
712                         '''Test property value'''
713                         props = node.get_properties()
714                         if props and 'mem_size' in props.keys():
715                             self.assertEqual(props['mem_size'].value,
716                                              '4096 MB')
717
718     def test_node_filter(self):
719         tosca_tpl = os.path.join(
720             os.path.dirname(os.path.abspath(__file__)),
721             "data/test_node_filter.yaml")
722         ToscaTemplate(tosca_tpl)
723
724     def test_attributes_inheritance(self):
725         tosca_tpl = os.path.join(
726             os.path.dirname(os.path.abspath(__file__)),
727             "data/test_attributes_inheritance.yaml")
728         ToscaTemplate(tosca_tpl)
729
730     def test_repositories_definition(self):
731         tosca_tpl = os.path.join(
732             os.path.dirname(os.path.abspath(__file__)),
733             "data/test_repositories_definition.yaml")
734         ToscaTemplate(tosca_tpl)
735
736     def test_custom_caps_def(self):
737         tosca_tpl = os.path.join(
738             os.path.dirname(os.path.abspath(__file__)),
739             "data/test_custom_caps_def.yaml")
740         ToscaTemplate(tosca_tpl)
741
742     def test_custom_rel_with_script(self):
743         tosca_tpl = os.path.join(
744             os.path.dirname(os.path.abspath(__file__)),
745             "data/test_tosca_custom_rel_with_script.yaml")
746         tosca = ToscaTemplate(tosca_tpl)
747         rel = tosca.relationship_templates[0]
748         self.assertEqual(rel.type, "tosca.relationships.HostedOn")
749         self.assertTrue(rel.is_derived_from("tosca.relationships.Root"))
750         self.assertEqual(len(rel.interfaces), 1)
751         self.assertEqual(rel.interfaces[0].type, "Configure")