Merge "The grouptype's parent_type definition is error"
[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.assertTrue(rel_tpl[0].is_derived_from(
228                             "tosca.relationships.Root"))
229                         interfaces = rel_tpl[0].interfaces
230                         for interface in interfaces:
231                             self.assertEqual(config_interface,
232                                              interface.type)
233                             self.assertEqual('pre_configure_source',
234                                              interface.name)
235                             self.assertEqual(artifact,
236                                              interface.implementation)
237
238     def test_relationship(self):
239         template = ToscaTemplate(self.tosca_elk_tpl)
240         for node_tpl in template.nodetemplates:
241             if node_tpl.name == 'paypal_pizzastore':
242                 expected_relationships = ['tosca.relationships.ConnectsTo',
243                                           'tosca.relationships.HostedOn']
244                 expected_hosts = ['tosca.nodes.Database',
245                                   'tosca.nodes.WebServer']
246                 self.assertEqual(len(node_tpl.relationships), 2)
247                 self.assertEqual(
248                     expected_relationships,
249                     sorted([k.type for k in node_tpl.relationships.keys()]))
250                 self.assertEqual(
251                     expected_hosts,
252                     sorted([v.type for v in node_tpl.relationships.values()]))
253
254     def test_template_macro(self):
255         template = ToscaTemplate(self.tosca_elk_tpl)
256         for node_tpl in template.nodetemplates:
257             if node_tpl.name == 'mongo_server':
258                 self.assertEqual(
259                     ['disk_size', 'mem_size', 'num_cpus'],
260                     sorted(node_tpl.get_capability('host').
261                            get_properties().keys()))
262
263     def test_template_requirements(self):
264         """Test different formats of requirements
265
266         The requirements can be defined in few different ways,
267         1. Requirement expressed as a capability with an implicit relationship.
268         2. Requirement expressed with explicit relationship.
269         3. Requirement expressed with a relationship template.
270         4. Requirement expressed via TOSCA types to provision a node
271            with explicit relationship.
272         5. Requirement expressed via TOSCA types with a filter.
273         """
274         tosca_tpl = os.path.join(
275             os.path.dirname(os.path.abspath(__file__)),
276             "data/test_requirements.yaml")
277         tosca = ToscaTemplate(tosca_tpl)
278         for node_tpl in tosca.nodetemplates:
279             if node_tpl.name == 'my_app':
280                 expected_relationship = [
281                     ('tosca.relationships.ConnectsTo', 'mysql_database'),
282                     ('tosca.relationships.HostedOn', 'my_webserver')]
283                 actual_relationship = sorted([
284                     (relation.type, node.name) for
285                     relation, node in node_tpl.relationships.items()])
286                 self.assertEqual(expected_relationship, actual_relationship)
287             if node_tpl.name == 'mysql_database':
288                     self.assertEqual(
289                         [('tosca.relationships.HostedOn', 'my_dbms')],
290                         [(relation.type, node.name) for
291                          relation,
292                          node in node_tpl.relationships.items()])
293             if node_tpl.name == 'my_server':
294                     self.assertEqual(
295                         [('tosca.relationships.AttachesTo', 'my_storage')],
296                         [(relation.type, node.name) for
297                          relation,
298                          node in node_tpl.relationships.items()])
299
300     def test_template_requirements_not_implemented(self):
301         # TODO(spzala): replace this test with new one once TOSCA types look up
302         # support is implemented.
303         """Requirements that yet need to be implemented
304
305         The following requirement formats are not yet implemented,
306         due to look up dependency:
307         1. Requirement expressed via TOSCA types to provision a node
308            with explicit relationship.
309         2. Requirement expressed via TOSCA types with a filter.
310         """
311         tpl_snippet_1 = '''
312         node_templates:
313           mysql_database:
314             type: tosca.nodes.Database
315             description: Requires a particular node type and relationship.
316                         To be full-filled via lookup into node repository.
317             requirements:
318               - req1:
319                   node: tosca.nodes.DBMS
320                   relationship: tosca.relationships.HostedOn
321         '''
322
323         tpl_snippet_2 = '''
324         node_templates:
325           my_webserver:
326             type: tosca.nodes.WebServer
327             description: Requires a particular node type with a filter.
328                          To be full-filled via lookup into node repository.
329             requirements:
330               - req1:
331                   node: tosca.nodes.Compute
332                   target_filter:
333                     properties:
334                       num_cpus: { in_range: [ 1, 4 ] }
335                       mem_size: { greater_or_equal: 2 }
336                     capabilities:
337                       - tosca.capabilities.OS:
338                           properties:
339                             architecture: x86_64
340                             type: linux
341         '''
342
343         tpl_snippet_3 = '''
344         node_templates:
345           my_webserver2:
346             type: tosca.nodes.WebServer
347             description: Requires a node type with a particular capability.
348                          To be full-filled via lookup into node repository.
349             requirements:
350               - req1:
351                   node: tosca.nodes.Compute
352                   relationship: tosca.relationships.HostedOn
353                   capability: tosca.capabilities.Container
354         '''
355         self._requirements_not_implemented(tpl_snippet_1, 'mysql_database')
356         self._requirements_not_implemented(tpl_snippet_2, 'my_webserver')
357         self._requirements_not_implemented(tpl_snippet_3, 'my_webserver2')
358
359     def _requirements_not_implemented(self, tpl_snippet, tpl_name):
360         nodetemplates = (toscaparser.utils.yamlparser.
361                          simple_parse(tpl_snippet))['node_templates']
362         self.assertRaises(
363             NotImplementedError,
364             lambda: NodeTemplate(tpl_name, nodetemplates).relationships)
365
366     # Test the following:
367     # 1. Custom node type derived from 'WebApplication' named 'TestApp'
368     #    with a custom Capability Type 'TestCapability'
369     # 2. Same as #1, but referencing a custom 'TestCapability' Capability Type
370     #    that is not defined
371     def test_custom_capability_type_definition(self):
372         tpl_snippet = '''
373         node_templates:
374           test_app:
375             type: tosca.nodes.WebApplication.TestApp
376             capabilities:
377               test_cap:
378                 properties:
379                   test: 1
380         '''
381         # custom node type definition with custom capability type definition
382         custom_def = '''
383         tosca.nodes.WebApplication.TestApp:
384           derived_from: tosca.nodes.WebApplication
385           capabilities:
386             test_cap:
387                type: tosca.capabilities.TestCapability
388         tosca.capabilities.TestCapability:
389           derived_from: tosca.capabilities.Root
390           properties:
391             test:
392               type: integer
393               required: false
394         '''
395         expected_capabilities = ['app_endpoint', 'feature', 'test_cap']
396         nodetemplates = (toscaparser.utils.yamlparser.
397                          simple_parse(tpl_snippet))['node_templates']
398         custom_def = (toscaparser.utils.yamlparser.
399                       simple_parse(custom_def))
400         name = list(nodetemplates.keys())[0]
401         tpl = NodeTemplate(name, nodetemplates, custom_def)
402         self.assertEqual(
403             expected_capabilities,
404             sorted(tpl.get_capabilities().keys()))
405
406         # custom definition without valid capability type definition
407         custom_def = '''
408         tosca.nodes.WebApplication.TestApp:
409           derived_from: tosca.nodes.WebApplication
410           capabilities:
411             test_cap:
412                type: tosca.capabilities.TestCapability
413         '''
414         custom_def = (toscaparser.utils.yamlparser.
415                       simple_parse(custom_def))
416         tpl = NodeTemplate(name, nodetemplates, custom_def)
417         err = self.assertRaises(
418             exception.InvalidTypeError,
419             lambda: NodeTemplate(name, nodetemplates,
420                                  custom_def).get_capabilities_objects())
421         self.assertEqual('Type "tosca.capabilities.TestCapability" is not '
422                          'a valid type.', six.text_type(err))
423
424     def test_local_template_with_local_relpath_import(self):
425         tosca_tpl = os.path.join(
426             os.path.dirname(os.path.abspath(__file__)),
427             "data/tosca_single_instance_wordpress.yaml")
428         tosca = ToscaTemplate(tosca_tpl)
429         self.assertTrue(tosca.topology_template.custom_defs)
430
431     def test_local_template_with_url_import(self):
432         tosca_tpl = os.path.join(
433             os.path.dirname(os.path.abspath(__file__)),
434             "data/tosca_single_instance_wordpress_with_url_import.yaml")
435         tosca = ToscaTemplate(tosca_tpl)
436         self.assertTrue(tosca.topology_template.custom_defs)
437
438     def test_url_template_with_local_relpath_import(self):
439         tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
440                      'tosca-parser/master/toscaparser/tests/data/'
441                      'tosca_single_instance_wordpress.yaml')
442         tosca = ToscaTemplate(tosca_tpl, None, False)
443         self.assertTrue(tosca.topology_template.custom_defs)
444
445     def test_url_template_with_local_abspath_import(self):
446         tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
447                      'tosca-parser/master/toscaparser/tests/data/'
448                      'tosca_single_instance_wordpress_with_local_abspath_'
449                      'import.yaml')
450         self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
451                           None, False)
452         err_msg = (_('Absolute file name "/tmp/tosca-parser/toscaparser/tests'
453                      '/data/custom_types/wordpress.yaml" cannot be used in a '
454                      'URL-based input template "%(tpl)s".')
455                    % {'tpl': tosca_tpl})
456         exception.ExceptionCollector.assertExceptionMessage(ImportError,
457                                                             err_msg)
458
459     def test_url_template_with_url_import(self):
460         tosca_tpl = ('https://raw.githubusercontent.com/openstack/'
461                      'tosca-parser/master/toscaparser/tests/data/'
462                      'tosca_single_instance_wordpress_with_url_import.yaml')
463         tosca = ToscaTemplate(tosca_tpl, None, False)
464         self.assertTrue(tosca.topology_template.custom_defs)
465
466     def test_csar_parsing_wordpress(self):
467         csar_archive = os.path.join(
468             os.path.dirname(os.path.abspath(__file__)),
469             'data/CSAR/csar_wordpress.zip')
470         self.assertTrue(ToscaTemplate(csar_archive))
471
472     def test_csar_parsing_elk_url_based(self):
473         csar_archive = ('https://github.com/openstack/tosca-parser/raw/master/'
474                         'toscaparser/tests/data/CSAR/csar_elk.zip')
475         self.assertTrue(ToscaTemplate(csar_archive, None, False))
476
477     def test_nested_imports_in_templates(self):
478         tosca_tpl = os.path.join(
479             os.path.dirname(os.path.abspath(__file__)),
480             "data/test_instance_nested_imports.yaml")
481         tosca = ToscaTemplate(tosca_tpl)
482         expected_custom_types = ['tosca.nodes.WebApplication.WordPress',
483                                  'test_namespace_prefix.Rsyslog',
484                                  'Test2ndRsyslogType',
485                                  'test_2nd_namespace_prefix.Rsyslog',
486                                  'tosca.nodes.SoftwareComponent.Logstash',
487                                  'tosca.nodes.SoftwareComponent.Rsyslog.'
488                                  'TestRsyslogType']
489         self.assertItemsEqual(tosca.topology_template.custom_defs.keys(),
490                               expected_custom_types)
491
492     def test_invalid_template_file(self):
493         template_file = 'invalid template file'
494         expected_msg = (_('"%s" is not a valid file.') % template_file)
495         self.assertRaises(
496             exception.ValidationError,
497             ToscaTemplate, template_file, None, False)
498         exception.ExceptionCollector.assertExceptionMessage(ValueError,
499                                                             expected_msg)
500
501     def test_multiple_validation_errors(self):
502         tosca_tpl = os.path.join(
503             os.path.dirname(os.path.abspath(__file__)),
504             "data/test_multiple_validation_errors.yaml")
505         self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
506                           None)
507         valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS)
508         err1_msg = (_('The template version "tosca_simple_yaml_1" is invalid. '
509                       'Valid versions are "%s".') % valid_versions)
510         exception.ExceptionCollector.assertExceptionMessage(
511             exception.InvalidTemplateVersion, err1_msg)
512
513         err2_msg = _('Import "custom_types/not_there.yaml" is not valid.')
514         exception.ExceptionCollector.assertExceptionMessage(
515             ImportError, err2_msg)
516
517         err3_msg = _('Type "tosca.nodes.WebApplication.WordPress" is not a '
518                      'valid type.')
519         exception.ExceptionCollector.assertExceptionMessage(
520             exception.InvalidTypeError, err3_msg)
521
522         err4_msg = _('Node template "wordpress" contains unknown field '
523                      '"requirement". Refer to the definition to verify valid '
524                      'values.')
525         exception.ExceptionCollector.assertExceptionMessage(
526             exception.UnknownFieldError, err4_msg)
527
528         err5_msg = _('\'Property "passwords" was not found in node template '
529                      '"mysql_database".\'')
530         exception.ExceptionCollector.assertExceptionMessage(
531             KeyError, err5_msg)
532
533         err6_msg = _('Template "mysql_dbms" is missing required field "type".')
534         exception.ExceptionCollector.assertExceptionMessage(
535             exception.MissingRequiredFieldError, err6_msg)
536
537         err7_msg = _('Node template "mysql_dbms" contains unknown field '
538                      '"type1". Refer to the definition to verify valid '
539                      'values.')
540         exception.ExceptionCollector.assertExceptionMessage(
541             exception.UnknownFieldError, err7_msg)
542
543         err8_msg = _('\'Node template "server1" was not found.\'')
544         exception.ExceptionCollector.assertExceptionMessage(
545             KeyError, err8_msg)
546
547         err9_msg = _('"relationship" used in template "webserver" is missing '
548                      'required field "type".')
549         exception.ExceptionCollector.assertExceptionMessage(
550             exception.MissingRequiredFieldError, err9_msg)
551
552     def test_invalid_section_names(self):
553         tosca_tpl = os.path.join(
554             os.path.dirname(os.path.abspath(__file__)),
555             "data/test_invalid_section_names.yaml")
556         self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
557                           None)
558         err1_msg = _('Template contains unknown field '
559                      '"tosca_definitions_versions". Refer to the definition '
560                      'to verify valid values.')
561         exception.ExceptionCollector.assertExceptionMessage(
562             exception.UnknownFieldError, err1_msg)
563
564         err2_msg = _('Template contains unknown field "descriptions". '
565                      'Refer to the definition to verify valid values.')
566         exception.ExceptionCollector.assertExceptionMessage(
567             exception.UnknownFieldError, err2_msg)
568
569         err3_msg = _('Template contains unknown field "import". Refer to '
570                      'the definition to verify valid values.')
571         exception.ExceptionCollector.assertExceptionMessage(
572             exception.UnknownFieldError, err3_msg)
573
574         err4_msg = _('Template contains unknown field "topology_templates". '
575                      'Refer to the definition to verify valid values.')
576         exception.ExceptionCollector.assertExceptionMessage(
577             exception.UnknownFieldError, err4_msg)
578
579     def test_csar_with_alternate_extenstion(self):
580         tosca_tpl = os.path.join(
581             os.path.dirname(os.path.abspath(__file__)),
582             "data/CSAR/csar_elk.csar")
583         tosca = ToscaTemplate(tosca_tpl)
584         self.assertTrue(tosca.topology_template.custom_defs)
585
586     def test_available_rel_tpls(self):
587         tosca_tpl = os.path.join(
588             os.path.dirname(os.path.abspath(__file__)),
589             "data/test_available_rel_tpls.yaml")
590         tosca = ToscaTemplate(tosca_tpl)
591         for node in tosca.nodetemplates:
592             for relationship, target in node.relationships.items():
593                 try:
594                     target.relationships
595                 except TypeError as error:
596                     self.fail(error)
597
598     def test_no_input(self):
599         self.assertRaises(exception.ValidationError, ToscaTemplate, None,
600                           None, False, None)
601         err_msg = (('No path or yaml_dict_tpl was provided. '
602                     'There is nothing to parse.'))
603         exception.ExceptionCollector.assertExceptionMessage(ValueError,
604                                                             err_msg)
605
606     def test_path_and_yaml_dict_tpl_input(self):
607         test_tpl = os.path.join(
608             os.path.dirname(os.path.abspath(__file__)),
609             "data/tosca_helloworld.yaml")
610
611         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
612
613         tosca = ToscaTemplate(test_tpl, yaml_dict_tpl=yaml_dict_tpl)
614
615         self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
616
617     def test_yaml_dict_tpl_input(self):
618         test_tpl = os.path.join(
619             os.path.dirname(os.path.abspath(__file__)),
620             "data/tosca_helloworld.yaml")
621
622         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
623
624         tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
625
626         self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
627
628     def test_yaml_dict_tpl_with_params_and_url_import(self):
629         test_tpl = os.path.join(
630             os.path.dirname(os.path.abspath(__file__)),
631             "data/tosca_single_instance_wordpress_with_url_import.yaml")
632
633         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
634
635         params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
636                   'db_root_pwd': 'mypasswd'}
637
638         tosca = ToscaTemplate(parsed_params=params,
639                               yaml_dict_tpl=yaml_dict_tpl)
640
641         self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
642
643     def test_yaml_dict_tpl_with_rel_import(self):
644         test_tpl = os.path.join(
645             os.path.dirname(os.path.abspath(__file__)),
646             "data/tosca_single_instance_wordpress.yaml")
647
648         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
649
650         self.assertRaises(exception.ValidationError, ToscaTemplate, None,
651                           None, False, yaml_dict_tpl)
652         err_msg = (_('Relative file name "custom_types/wordpress.yaml" '
653                      'cannot be used in a pre-parsed input template.'))
654         exception.ExceptionCollector.assertExceptionMessage(ImportError,
655                                                             err_msg)
656
657     def test_yaml_dict_tpl_with_fullpath_import(self):
658         test_tpl = os.path.join(
659             os.path.dirname(os.path.abspath(__file__)),
660             "data/tosca_single_instance_wordpress.yaml")
661
662         yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
663
664         yaml_dict_tpl['imports'] = [os.path.join(os.path.dirname(
665             os.path.abspath(__file__)), "data/custom_types/wordpress.yaml")]
666
667         params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
668                   'db_root_pwd': 'mypasswd'}
669
670         tosca = ToscaTemplate(parsed_params=params,
671                               yaml_dict_tpl=yaml_dict_tpl)
672
673         self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
674
675     def test_policies_for_node_templates(self):
676         tosca_tpl = os.path.join(
677             os.path.dirname(os.path.abspath(__file__)),
678             "data/policies/tosca_policy_template.yaml")
679         tosca = ToscaTemplate(tosca_tpl)
680
681         for policy in tosca.topology_template.policies:
682             if policy.name == 'my_compute_placement_policy':
683                 self.assertEqual('tosca.policies.Placement', policy.type)
684                 self.assertEqual(['my_server_1', 'my_server_2'],
685                                  policy.targets)
686                 self.assertEqual('node_templates', policy.get_targets_type())
687                 for node in policy.targets_list:
688                     if node.name == 'my_server_1':
689                         '''Test property value'''
690                         props = node.get_properties()
691                         if props and 'mem_size' in props.keys():
692                             self.assertEqual(props['mem_size'].value,
693                                              '4096 MB')
694
695     def test_policies_for_groups(self):
696         tosca_tpl = os.path.join(
697             os.path.dirname(os.path.abspath(__file__)),
698             "data/policies/tosca_policy_template.yaml")
699         tosca = ToscaTemplate(tosca_tpl)
700
701         for policy in tosca.topology_template.policies:
702             if policy.name == 'my_groups_placement':
703                 self.assertEqual('mycompany.mytypes.myScalingPolicy',
704                                  policy.type)
705                 self.assertEqual(['webserver_group'], policy.targets)
706                 self.assertEqual('groups', policy.get_targets_type())
707                 group = policy.get_targets_list()[0]
708                 for node in group.get_member_nodes():
709                     if node.name == 'my_server_2':
710                         '''Test property value'''
711                         props = node.get_properties()
712                         if props and 'mem_size' in props.keys():
713                             self.assertEqual(props['mem_size'].value,
714                                              '4096 MB')
715
716     def test_node_filter(self):
717         tosca_tpl = os.path.join(
718             os.path.dirname(os.path.abspath(__file__)),
719             "data/test_node_filter.yaml")
720         ToscaTemplate(tosca_tpl)
721
722     def test_attributes_inheritance(self):
723         tosca_tpl = os.path.join(
724             os.path.dirname(os.path.abspath(__file__)),
725             "data/test_attributes_inheritance.yaml")
726         ToscaTemplate(tosca_tpl)
727
728     def test_repositories_definition(self):
729         tosca_tpl = os.path.join(
730             os.path.dirname(os.path.abspath(__file__)),
731             "data/test_repositories_definition.yaml")
732         ToscaTemplate(tosca_tpl)
733
734     def test_custom_caps_def(self):
735         tosca_tpl = os.path.join(
736             os.path.dirname(os.path.abspath(__file__)),
737             "data/test_custom_caps_def.yaml")
738         ToscaTemplate(tosca_tpl)
739
740     def test_custom_rel_with_script(self):
741         tosca_tpl = os.path.join(
742             os.path.dirname(os.path.abspath(__file__)),
743             "data/test_tosca_custom_rel_with_script.yaml")
744         tosca = ToscaTemplate(tosca_tpl)
745         rel = tosca.relationship_templates[0]
746         self.assertEqual(rel.type, "tosca.relationships.HostedOn")
747         self.assertTrue(rel.is_derived_from("tosca.relationships.Root"))
748         self.assertEqual(len(rel.interfaces), 1)
749         self.assertEqual(rel.interfaces[0].type, "Configure")