diff options
Diffstat (limited to 'tosca2heat/tosca-parser/toscaparser')
11 files changed, 237 insertions, 74 deletions
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py b/tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py index 3bfd7d0..887e99a 100644 --- a/tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py +++ b/tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py @@ -20,6 +20,7 @@ class ArtifactTypeDef(StatefulEntityType): super(ArtifactTypeDef, self).__init__(atype, self.ARTIFACT_PREFIX, custom_def) self.type = atype + self.custom_def = custom_def self.properties = None if self.PROPERTIES in self.defs: self.properties = self.defs[self.PROPERTIES] @@ -27,17 +28,24 @@ class ArtifactTypeDef(StatefulEntityType): def _get_parent_artifacts(self): artifacts = {} - parent_artif = self.parent_type + parent_artif = self.parent_type.type if self.parent_type else None if parent_artif: while parent_artif != 'tosca.artifacts.Root': + # only support normative artifact, shall be modified future artifacts[parent_artif] = self.TOSCA_DEF[parent_artif] parent_artif = artifacts[parent_artif]['derived_from'] return artifacts @property def parent_type(self): - '''Return an artifact this artifact is derived from.''' - return self.derived_from(self.defs) + '''Return a artifact entity from which this entity is derived.''' + if not hasattr(self, 'defs'): + return None + partifact_entity = self.derived_from(self.defs) + if partifact_entity: + return ArtifactTypeDef(partifact_entity, self.custom_def) + else: + return None def get_artifact(self, name): '''Return the definition of an artifact field by name.''' diff --git a/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py b/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py index 5d620a5..72e7e3f 100644 --- a/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py +++ b/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py @@ -106,8 +106,13 @@ class EntityType(object): value[k] = v if isinstance(value, list): for p_value in parent_value: - if p_value not in value: - value.append(p_value) + if isinstance(p_value, dict): + if p_value.keys()[0] not in [ + item.keys()[0] for item in value]: + value.append(p_value) + else: + if p_value not in value: + value.append(p_value) else: value = copy.copy(parent_value) p = p.parent_type diff --git a/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py b/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py index ec5571c..5587f05 100644 --- a/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py +++ b/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py @@ -52,6 +52,17 @@ class GroupType(StatefulEntityType): self._validate_metadata(self.meta_data) @property + def parent_type(self): + '''Return a group statefulentity of this entity is derived from.''' + if not hasattr(self, 'defs'): + return None + pgroup_entity = self.derived_from(self.defs) + if pgroup_entity: + return GroupType(pgroup_entity, self.custom_def) + else: + return None + + @property def description(self): return self.group_description diff --git a/tosca2heat/tosca-parser/toscaparser/elements/policytype.py b/tosca2heat/tosca-parser/toscaparser/elements/policytype.py index 04cbab5..8fbb0f0 100644 --- a/tosca2heat/tosca-parser/toscaparser/elements/policytype.py +++ b/tosca2heat/tosca-parser/toscaparser/elements/policytype.py @@ -28,6 +28,7 @@ class PolicyType(StatefulEntityType): super(PolicyType, self).__init__(ptype, self.POLICY_PREFIX, custom_def) self.type = ptype + self.custom_def = custom_def self._validate_keys() self.meta_data = None @@ -55,7 +56,7 @@ class PolicyType(StatefulEntityType): def _get_parent_policies(self): policies = {} - parent_policy = self.parent_type + parent_policy = self.parent_type.type if self.parent_type else None if parent_policy: while parent_policy != 'tosca.policies.Root': policies[parent_policy] = self.TOSCA_DEF[parent_policy] @@ -64,8 +65,12 @@ class PolicyType(StatefulEntityType): @property def parent_type(self): - '''Return a policy this policy is derived from.''' - return self.derived_from(self.defs) + '''Return a policy statefulentity of this node is derived from.''' + if not hasattr(self, 'defs'): + return None + ppolicy_entity = self.derived_from(self.defs) + if ppolicy_entity: + return PolicyType(ppolicy_entity, self.custom_def) def get_policy(self, name): '''Return the definition of a policy field by name.''' diff --git a/tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py b/tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py index 9462d38..25440ca 100644 --- a/tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py +++ b/tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py @@ -26,7 +26,7 @@ class RelationshipType(StatefulEntityType): '''Return a relationship this reletionship is derived from.''' prel = self.derived_from(self.defs) if prel: - return RelationshipType(prel) + return RelationshipType(prel, self.custom_def) @property def valid_target_types(self): diff --git a/tosca2heat/tosca-parser/toscaparser/entity_template.py b/tosca2heat/tosca-parser/toscaparser/entity_template.py index 281012b..f416c99 100644 --- a/tosca2heat/tosca-parser/toscaparser/entity_template.py +++ b/tosca2heat/tosca-parser/toscaparser/entity_template.py @@ -81,6 +81,15 @@ class EntityTemplate(object): def type(self): if self.type_definition: return self.type_definition.type + else: + return None + + @property + def parent_type(self): + if self.type_definition: + return self.type_definition.parent_type + else: + return None @property def requirements(self): diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/vRNC/Definitions/rnc_definition.yaml b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/vRNC/Definitions/rnc_definition.yaml index c9d0901..8c98fc9 100644 --- a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/vRNC/Definitions/rnc_definition.yaml +++ b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/vRNC/Definitions/rnc_definition.yaml @@ -61,12 +61,14 @@ node_types: properties: activestatus: type: integer + required: false description: 1 for active or 0 for passive constraints: - valid_values: [ 0, 1 ] id: type: string defaule: MM + required: false description: > A identifier of this VDU within the scope of the VNFD, including version functional description and other @@ -77,6 +79,7 @@ node_types: properties: activestatus: type: integer + required: false description: 1 for active or 0 for passive constraints: - valid_values: [ 0, 1 ] diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/vRNC/Definitions/vRNC.yaml b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/vRNC/Definitions/vRNC.yaml index 2617b4d..6517c4a 100644 --- a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/vRNC/Definitions/vRNC.yaml +++ b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/vRNC/Definitions/vRNC.yaml @@ -35,28 +35,28 @@ dsl_definitions: compute_props_os_DEF: &compute_props_os_DEF architecture: x86_64 type: Linux - distribution: Ubuntu - version: 14.10 + distribution: Cirros + version: 0.3.2 compute_props_host_MM: &compute_props_host_MM - disk_size: 20 GB + disk_size: 1 GB num_cpus: 2 - mem_size: 1024 MB + mem_size: 64 MB compute_props_host_CM: &compute_props_host_CM disk_size: 0 GB num_cpus: 2 - mem_size: 1024 MB + mem_size: 64 MB compute_props_host_DM: &compute_props_host_DM disk_size: 0 GB num_cpus: 2 - mem_size: 1024 MB + mem_size: 64 MB compute_props_host_LB: &compute_props_host_LB disk_size: 0 GB num_cpus: 2 - mem_size: 1024 MB + mem_size: 64 MB # topology template definition of the cloud application or service topology_template: @@ -67,7 +67,7 @@ topology_template: inputs: mm_storage_size: type: integer - default: 20 GB + default: 1 description: mm additional block storage size constraints: - in_range: [ 1, 200 ] @@ -84,6 +84,19 @@ topology_template: # definition of the node templates of the topology node_templates: MM_Active: + type: tosca.nodes.SoftwareComponent + properties: + component_version: 1.0 + requirements: + - host: MM_Active_Host + interfaces: + Standard: + create: + implementation: mm_install.sh + configure: + implementation: mm_active_configure.sh + + MM_Active_Host: type: rnc.nodes.compute.MM properties: activestatus: 1 @@ -101,14 +114,21 @@ topology_template: artifacts: #the VM image of MM vm_image: mm.image + + MM_Passive: + type: tosca.nodes.SoftwareComponent + properties: + component_version: 1.0 + requirements: + - host: MM_Passive_Host interfaces: Standard: create: implementation: mm_install.sh configure: - implementation: mm_active_configure.sh + implementation: mm_passvie_configure.sh - MM_Passive: + MM_Passive_Host: type: rnc.nodes.compute.MM properties: activestatus: 0 @@ -126,14 +146,21 @@ topology_template: artifacts: #the VM image of MM vm_image: mm.image + + CM_Active: + type: tosca.nodes.SoftwareComponent + properties: + component_version: 1.0 + requirements: + - host: CM_Active_Host interfaces: Standard: create: - implementation: mm_install.sh + implementation: cm_install.sh configure: - implementation: mm_passvie_configure.sh + implementation: cm_active_configure.sh - CM_Active: + CM_Active_Host: type: rnc.nodes.compute.CM properties: activestatus: 1 @@ -145,21 +172,28 @@ topology_template: scalable: properties: min_instances: 1 - max_instances: 126 + max_instances: 12 default_instances: 1 requirements: - high_availability: CM_Passive artifacts: #the VM image of CM vm_image: cm.image + + CM_Passive: + type: tosca.nodes.SoftwareComponent + properties: + component_version: 1.0 + requirements: + - host: CM_Passive_Host interfaces: Standard: create: implementation: cm_install.sh configure: - implementation: cm_active_configure.sh + implementation: cm_passvie_configure.sh - CM_Passive: + CM_Passive_Host: type: rnc.nodes.compute.CM properties: activestatus: 0 @@ -171,21 +205,28 @@ topology_template: scalable: properties: min_instances: 1 - max_instances: 126 + max_instances: 12 default_instances: 1 requirements: - high_availability: CM_Active artifacts: #the VM image of CM vm_image: mm.image + + DM: + type: tosca.nodes.SoftwareComponent + properties: + component_version: 1.0 + requirements: + - host: DM_Host interfaces: Standard: create: - implementation: cm_install.sh + implementation: dm_install.sh configure: - implementation: cm_passvie_configure.sh + implementation: dm_configure.sh - DM: + DM_Host: type: rnc.nodes.compute.DM capabilities: os: @@ -195,18 +236,25 @@ topology_template: scalable: properties: min_instances: 1 - max_instances: 120 + max_instances: 12 default_instances: 1 artifacts: vm_image: dm.image + + LB: + type: tosca.nodes.SoftwareComponent + properties: + component_version: 1.0 + requirements: + - host: LB_Host interfaces: Standard: create: - implementation: dm_install.sh + implementation: lb_install.sh configure: - implementation: dm_configure.sh + implementation: lb_configure.sh - LB: + LB_Host: type: rnc.nodes.compute.LB capabilities: os: @@ -216,17 +264,11 @@ topology_template: scalable: properties: min_instances: 1 - max_instances: 20 + max_instances: 2 default_instances: 1 artifacts: #the VM image of LB vm_image: lb.image - interfaces: - Standard: - create: - implementation: lb_install.sh - configure: - implementation: lb_configure.sh MM_BlockStorage: type: rnc.nodes.BlockStorage @@ -285,58 +327,112 @@ topology_template: segmentation_id: 101 dhcp_enabled: false - MM_Port_EMS: + MM_Active_Port_EMS: type: rnc.nodes.CP.MM properties: order: 0 is_default: true requirements: - - virtualBinding: MM_Active + - virtualBinding: MM_Active_Host + - virtualLink: EMS_Net + + MM_Active_Port_EXTERMEDIA: + type: rnc.nodes.CP.MM + properties: + order: 1 + is_default: true + requirements: + - virtualBinding: MM_Active_Host - virtualLink: EMS_Net - MM_Port_EMS: + MM_Active_Port_CTRL: + type: rnc.nodes.CP.MM + properties: + order: 2 + is_default: false + requirements: + - virtualBinding: MM_Active_Host + - virtualLink: CTRL_Net + + MM_Active_Port_INTERMEDIA: + type: rnc.nodes.CP.MM + properties: + order: 3 + is_default: false + requirements: + - virtualBinding: MM_Active_Host + - virtualLink: EXTERMEDIA_Net + + MM_Passive_Port_EMS: type: rnc.nodes.CP.MM properties: order: 0 is_default: true requirements: - - virtualBinding: MM_Active + - virtualBinding: MM_Passive_Host - virtualLink: EMS_Net - MM_Port_CTRL: + MM_Passive_Port_EXTERMEDIA: type: rnc.nodes.CP.MM properties: order: 1 + is_default: true + requirements: + - virtualBinding: MM_Passive_Host + - virtualLink: EMS_Net + + MM_Passive_Port_CTRL: + type: rnc.nodes.CP.MM + properties: + order: 2 is_default: false requirements: - - virtualBinding: MM_Active + - virtualBinding: MM_Passive_Host - virtualLink: CTRL_Net - MM_Port_EXTERMEDIA: + MM_Passive_Port_INTERMEDIA: type: rnc.nodes.CP.MM properties: - order: 2 + order: 3 is_default: false requirements: - - virtualBinding: MM_Active + - virtualBinding: MM_Passive_Host - virtualLink: EXTERMEDIA_Net - CM_Port_CTRL: + CM_Active_Port_CTRL: type: rnc.nodes.CP.CM properties: order: 0 is_default: true requirements: - - virtualBinding: CM_Active + - virtualBinding: CM_Active_Host - virtualLink: CTRL_Net - CM_Port_INTERMEDIA: + CM_Active_Port_INTERMEDIA: type: rnc.nodes.CP.CM properties: order: 1 is_default: false requirements: - - virtualBinding: CM_Active + - virtualBinding: CM_Active_Host + - virtualLink: INTERMEDIA_Net + + CM_Passive_Port_CTRL: + type: rnc.nodes.CP.CM + properties: + order: 0 + is_default: true + requirements: + - virtualBinding: CM_Passive_Host + - virtualLink: CTRL_Net + + CM_Passive_Port_INTERMEDIA: + type: rnc.nodes.CP.CM + properties: + order: 1 + is_default: false + requirements: + - virtualBinding: CM_Passive_Host - virtualLink: INTERMEDIA_Net DM_Port_CTRL: @@ -346,7 +442,7 @@ topology_template: is_default: true requirements: - virtualBinding: DM - - virtualLink: CTRL_Net + - virtualLink: CTRL_Net_Host DM_Port_INTERMEDIA: type: rnc.nodes.CP.DM @@ -354,7 +450,7 @@ topology_template: order: 1 is_default: false requirements: - - virtualBinding: DM + - virtualBinding: DM_Host - virtualLink: INTERMEDIA_Net LB_Port_CTRL: @@ -363,7 +459,7 @@ topology_template: order: 0 is_default: true requirements: - - virtualBinding: LB + - virtualBinding: LB_Host - virtualLink: CTRL_Net LB_Port_INTERMEDIA: @@ -372,7 +468,7 @@ topology_template: order: 1 is_default: false requirements: - - virtualBinding: LB + - virtualBinding: LB_Host - virtualLink: INTERMEDIA_Net LB_Port_EXTERMEDIA: @@ -381,7 +477,7 @@ topology_template: order: 2 is_default: false requirements: - - virtualBinding: LB + - virtualBinding: LB_Host - virtualLink: EXTERMEDIA_Net # definition of the relationship templates of the topology @@ -395,19 +491,19 @@ topology_template: outputs: private_ip_of_MM: description: The private IP address of the MM. - value: { get_attribute: [ MM_Active, private_address ] } + value: { get_attribute: [ MM_Active_Host, private_address ] } private_ip_of_CM: description: The private IP address of the CM. - value: { get_attribute: [ CM_Active, private_address ] } + value: { get_attribute: [ CM_Active_Host, private_address ] } private_ip_of_DM: description: The private IP address of the DM. - value: { get_attribute: [ DM, private_address ] } + value: { get_attribute: [ DM_Host, private_address ] } private_ip_of_LB: description: The private IP address of the LB. - value: { get_attribute: [ LB, private_address ] } + value: { get_attribute: [ LB_Host, private_address ] } # definition of logical groups of node templates within the topology # To be continue about this section diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/test_tosca_vRNC.py b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/test_tosca_vRNC.py index 46a5e29..c839626 100644 --- a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/test_tosca_vRNC.py +++ b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/test_tosca_vRNC.py @@ -35,10 +35,16 @@ class ToscaVRNCTemplateTest(TestCase): def test_nodetemplates(self): expected_node_list = sorted( ["MM_Active", "MM_Passive", "MM_BlockStorage", + "MM_Active_Host", "MM_Passive_Host", "CM_Active", "CM_Passive", "DM", "LB", + "CM_Active_Host", "CM_Passive_Host", "DM_Host", "LB_Host", "EXTERMEDIA_Net", "INTERMEDIA_Net", "EMS_Net", "CTRL_Net", - "MM_Port_EMS", "MM_Port_CTRL", "MM_Port_EXTERMEDIA", - "CM_Port_CTRL", "CM_Port_INTERMEDIA", + "MM_Active_Port_EMS", "MM_Active_Port_CTRL", + "MM_Active_Port_EXTERMEDIA", "MM_Active_Port_INTERMEDIA", + "MM_Passive_Port_EMS", "MM_Passive_Port_CTRL", + "MM_Passive_Port_EXTERMEDIA", "MM_Passive_Port_INTERMEDIA", + "CM_Active_Port_CTRL", "CM_Active_Port_INTERMEDIA", + "CM_Passive_Port_CTRL", "CM_Passive_Port_INTERMEDIA", "DM_Port_CTRL", "DM_Port_INTERMEDIA", "LB_Port_INTERMEDIA", "LB_Port_EXTERMEDIA", "LB_Port_CTRL"]) diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py b/tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py index f0a87ac..358bf28 100644 --- a/tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py +++ b/tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py @@ -60,6 +60,7 @@ class ToscaDefTest(TestCase): def test_group(self): self.assertEqual(group_type.type, "tosca.groups.Root") + self.assertEqual(group_type.parent_type, None) self.assertIn(ifaces.LIFECYCLE_SHORTNAME, group_type.interfaces) def test_capabilities(self): @@ -188,8 +189,9 @@ class ToscaDefTest(TestCase): self.assertIn(ifaces.LIFECYCLE_SHORTNAME, root_node.interfaces) def test_artifacts(self): + self.assertEqual(artif_root_type.parent_type, None) self.assertEqual('tosca.artifacts.Root', - artif_file_type.parent_type) + artif_file_type.parent_type.type) self.assertEqual({}, artif_file_type.parent_artifacts) self.assertEqual(sorted(['tosca.artifacts.Root'], key=lambda x: str(x)), @@ -198,7 +200,7 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) self.assertEqual('tosca.artifacts.Implementation', - artif_bash_type.parent_type) + artif_bash_type.parent_type.type) self.assertEqual({'tosca.artifacts.Implementation': {'derived_from': 'tosca.artifacts.Root', 'description': @@ -212,7 +214,7 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) self.assertEqual('tosca.artifacts.Implementation', - artif_python_type.parent_type) + artif_python_type.parent_type.type) self.assertEqual({'tosca.artifacts.Implementation': {'derived_from': 'tosca.artifacts.Root', 'description': @@ -227,7 +229,7 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) self.assertEqual('tosca.artifacts.Deployment.Image', - artif_container_docker_type.parent_type) + artif_container_docker_type.parent_type.type) self.assertEqual({'tosca.artifacts.Deployment': {'derived_from': 'tosca.artifacts.Root', 'description': @@ -244,7 +246,7 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) self.assertEqual('tosca.artifacts.Deployment.Image', - artif_vm_iso_type.parent_type) + artif_vm_iso_type.parent_type.type) self.assertEqual({'tosca.artifacts.Deployment': {'derived_from': 'tosca.artifacts.Root', 'description': @@ -263,7 +265,7 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) self.assertEqual('tosca.artifacts.Deployment.Image', - artif_vm_qcow2_type.parent_type) + artif_vm_qcow2_type.parent_type.type) self.assertEqual({'tosca.artifacts.Deployment': {'derived_from': 'tosca.artifacts.Root', 'description': @@ -282,8 +284,9 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) def test_policies(self): + self.assertEqual(policy_root_type.parent_type, None) self.assertEqual('tosca.policies.Root', - policy_placement_type.parent_type) + policy_placement_type.parent_type.type) self.assertEqual({}, policy_placement_type.parent_policies) self.assertEqual(sorted(['tosca.policies.Root', 'The TOSCA Policy Type definition that is ' @@ -295,7 +298,7 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) self.assertEqual('tosca.policies.Root', - policy_scaling_type.parent_type) + policy_scaling_type.parent_type.type) self.assertEqual({}, policy_scaling_type.parent_policies) self.assertEqual(sorted(['tosca.policies.Root', 'The TOSCA Policy Type definition that is ' @@ -307,7 +310,7 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) self.assertEqual('tosca.policies.Root', - policy_update_type.parent_type) + policy_update_type.parent_type.type) self.assertEqual({}, policy_update_type.parent_policies) self.assertEqual(sorted(['tosca.policies.Root', 'The TOSCA Policy Type definition that is ' @@ -319,7 +322,7 @@ class ToscaDefTest(TestCase): key=lambda x: str(x))) self.assertEqual('tosca.policies.Root', - policy_performance_type.parent_type) + policy_performance_type.parent_type.type) self.assertEqual({}, policy_performance_type.parent_policies) self.assertEqual(sorted(['tosca.policies.Root', 'The TOSCA Policy Type definition that is ' diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py index 3fd49bf..ac55059 100644 --- a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py +++ b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py @@ -134,6 +134,19 @@ class ToscaTemplateTest(TestCase): self.assertEqual('Linux', os_props['type'].value) self.assertEqual('Linux', os_type_prop) + def test_node_inheritance_type(self): + wordpress_node = [ + node for node in self.tosca.nodetemplates + if node.name == 'wordpress'][0] + self.assertTrue( + wordpress_node.is_derived_from("tosca.nodes.WebApplication")) + self.assertTrue( + wordpress_node.is_derived_from("tosca.nodes.Root")) + self.assertFalse( + wordpress_node.is_derived_from("tosca.policies.Root")) + self.assertFalse( + wordpress_node.is_derived_from("tosca.groups.Root")) + def test_outputs(self): self.assertEqual( ['website_url'], @@ -211,6 +224,8 @@ class ToscaTemplateTest(TestCase): for key in relation.keys(): rel_tpl = relation.get(key).get_relationship_template() if rel_tpl: + self.assertTrue(rel_tpl[0].is_derived_from( + "tosca.relationships.Root")) interfaces = rel_tpl[0].interfaces for interface in interfaces: self.assertEqual(config_interface, @@ -728,5 +743,7 @@ class ToscaTemplateTest(TestCase): "data/test_tosca_custom_rel_with_script.yaml") tosca = ToscaTemplate(tosca_tpl) rel = tosca.relationship_templates[0] + self.assertEqual(rel.type, "tosca.relationships.HostedOn") + self.assertTrue(rel.is_derived_from("tosca.relationships.Root")) self.assertEqual(len(rel.interfaces), 1) self.assertEqual(rel.interfaces[0].type, "Configure") |