From 2236f9d810af0d2ef480eafbfa2abcc2b3cd932e Mon Sep 17 00:00:00 2001 From: "Betzer, Rony (rb844h)" Date: Thu, 4 Oct 2018 16:47:13 +0300 Subject: UT coverage report with tox and virtualenv UT coverage report with tox and virtualenv Change-Id: I90d6d4099e8cf43201082d5094865ee78c0bad9e Issue-ID: SDC-1756 Signed-off-by: Betzer, Rony (rb844h) --- app/requirements.txt | 3 +- app/tests/__init__.py | 0 app/tests/test_database.py | 21 ++ app/tests/test_node_templates.py | 71 +++++++ app/tests/test_topology_template.py | 35 ++++ app/tests/test_value_templates.py | 227 +++++++++++++++++++++ ...st_value_templates_calculate_function_result.py | 77 +++++++ app/tests/utils/test_utils.py | 24 +++ 8 files changed, 457 insertions(+), 1 deletion(-) create mode 100644 app/tests/__init__.py create mode 100644 app/tests/test_database.py create mode 100644 app/tests/test_node_templates.py create mode 100644 app/tests/test_topology_template.py create mode 100644 app/tests/test_value_templates.py create mode 100644 app/tests/test_value_templates_calculate_function_result.py create mode 100644 app/tests/utils/test_utils.py (limited to 'app') diff --git a/app/requirements.txt b/app/requirements.txt index cb7ff9f..0d63990 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -1,4 +1,4 @@ -PyYAML==3.11 +PyYAML argparse==1.4.0 dateutils==0.6.6 python-dateutil==2.5.3 @@ -9,3 +9,4 @@ virtualenv==12.1.1 utils web.py==0.40.dev0 + diff --git a/app/tests/__init__.py b/app/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/test_database.py b/app/tests/test_database.py new file mode 100644 index 0000000..fea520c --- /dev/null +++ b/app/tests/test_database.py @@ -0,0 +1,21 @@ +import unittest +from toscalib.templates.database import ToscaDB +from tests.utils.test_utils import init_template + + +class TestDatabaseMethods(unittest.TestCase): + + def test_prepare_schema(self): + db = ToscaDB() + res = db._prepare_schema() + self.assertEqual(res, {'00_YAMLORDER_tosca_definitions_version': 'tosca_simple_yaml_1_0_0'}) + db = init_template().db + res = db._prepare_schema() + self.assertEqual(res, {'00_YAMLORDER_tosca_definitions_version': 'tosca_simple_yaml_1_0_0', '08_YAMLORDER_capability_types': {'tosca.capabilities.dummy': {'properties': {'capabilityProperty': {'type': 'string'}}}, + 'tosca.capabilities.substitute': {'properties': {'capabilityProperty': {'type': 'string'}}}}, '11_YAMLORDER_node_types': {'nodeTypeName': {'attributes': {'attributeName': {'type': 'string'}}, + 'capabilities': {'capabilityName': {'type': 'tosca.capabilities.dummy'}}, 'id': 'nodeId', 'properties': {'propertyName': {'type': 'string'}}, 'requirements': [{'dummyRequirement': {'capability': 'tosca.capabilities.dummy'}}]}, + 'substituteNodeType': {'capabilities': {'substituteCapability': {'type': 'tosca.capabilities.substitute'}}, 'id': 'subNodeId', 'properties': {'inputName': {'type': 'string'}}, 'requirements': [{'substituteRequirement': {'capability': 'tosca.capabilities.substitute'}}]}}}) + + + + diff --git a/app/tests/test_node_templates.py b/app/tests/test_node_templates.py new file mode 100644 index 0000000..15d5480 --- /dev/null +++ b/app/tests/test_node_templates.py @@ -0,0 +1,71 @@ +import unittest +from tests.utils.test_utils import init_template +from toscalib.templates.node import Node + + +class TestNodeTemplateMethods(unittest.TestCase): + + def test_instantiate_with_type(self): + template = init_template() + node = Node(template, 'myNode', template.db.NODE_TYPES.get('nodeTypeName')) + self.assertEqual(1, len(node.attributes)) + node._instatiateWithType(template.db.NODE_TYPES.get('substituteNodeType')) + self.assertEqual(0, len(node.attributes)) + + def test_parse_pre_defined_content(self): + template = init_template() + node = Node(template, 'myNode', template.db.NODE_TYPES.get('nodeTypeName')) + self.assertIsNone(node.properties.get('propertyName').value) + prop_sec = {'properties': {'propertyName': 'template_value'}} + node._parse_pre_defined_content(prop_sec) + self.assertEqual('template_value', node.properties.get('propertyName').value.value) + + # TODO uncomment after merging ecomp latest code + # def test_update_get_node_name_property_value(self): + # template = init_template() + # node = Node(template, 'myNode', template.db.NODE_TYPES.get('nodeTypeName')) + # prop_sec = {'properties': {'propertyName': '__GET_NODE_NAME__'}} + # node._parse_pre_defined_content(prop_sec) + # self.assertEqual('__GET_NODE_NAME__', node.properties.get('propertyName').value.value) + # node._update_get_node_name() + # self.assertEqual('myNode', node.properties.get('propertyName').value.value) + + # TODO uncomment after merging ecomp latest code + # def test_update_get_node_name_capability_property_value(self): + # template = init_template() + # node = Node(template, 'myNode', template.db.NODE_TYPES.get('nodeTypeName')) + # prop_sec = {'capabilities': {'capabilityName': {'properties': {'capabilityProperty': '__GET_NODE_NAME__'}}}} + # node._parse_pre_defined_content(prop_sec) + # self.assertEqual('__GET_NODE_NAME__', node._get_capability_property('capabilityName', 'capabilityProperty').value.value) + # node._update_get_node_name() + # self.assertEqual('myNode', node._get_capability_property('capabilityName', 'capabilityProperty').value.value) + + def test_update_prefix(self): + template = init_template() + node = template.node_dict.get('nodeName') + prop_sec = {'properties': {'propertyName': {'get_input': 'inputName'}}, 'capabilities': {'capabilityName': {'properties': {'capabilityProperty': {'get_property': ['nodeName', 'propertyName']}}}}} + node._parse_pre_defined_content(prop_sec) + node._update_prefix('PREFIX_') + self.assertEqual('PREFIX_nodeName', node.name) + self.assertEqual('PREFIX_nodeName', node.id.value.function.extra_data[0]) + self.assertEqual('PREFIX_inputName', node.properties.get('propertyName').value.function.target_property) + self.assertEqual('PREFIX_nodeName', node._get_capability_property('capabilityName', 'capabilityProperty').value.function.extra_data[0]) + + def test_verify_functions(self): + template = init_template() + node = template.node_dict.get('nodeName') + prop_sec = {'properties': {'propertyName': {'get_input': 'inputName'}}, 'capabilities': {'capabilityName': {'properties': {'capabilityProperty': {'get_property': ['nodeName', 'propertyName']}}}}} + node._parse_pre_defined_content(prop_sec) + self.assertIsNone(node.properties.get('propertyName').value.function.value_from_item) + self.assertIsNone(node._get_capability_property('capabilityName', 'capabilityProperty').value.function.value_from_item) + self.assertIsNone(node._get_capability_property('capabilityName', 'capabilityProperty').value.function.value_from_node) + node._verify_functions() + self.assertIsNotNone(node.properties.get('propertyName').value.function.value_from_item) + self.assertIsNotNone(node._get_capability_property('capabilityName', 'capabilityProperty').value.function.value_from_item) + self.assertIsNotNone(node._get_capability_property('capabilityName', 'capabilityProperty').value.function.value_from_node) + self.assertEqual(template.inputs.get('inputName'), node.properties.get('propertyName').value.function.value_from_item) + self.assertEqual(node.properties.get('propertyName'), node._get_capability_property('capabilityName', 'capabilityProperty').value.function.value_from_item) + self.assertEqual(node, node._get_capability_property('capabilityName', 'capabilityProperty').value.function.value_from_node) + + + diff --git a/app/tests/test_topology_template.py b/app/tests/test_topology_template.py new file mode 100644 index 0000000..8e7da5a --- /dev/null +++ b/app/tests/test_topology_template.py @@ -0,0 +1,35 @@ +import unittest +from toscalib.templates.topology import ToscaTopology +from tests.utils.test_utils import init_template + + +class TestTopologyTemplateMethods(unittest.TestCase): + + def test_update_mapping_template_pointer(self): + template = init_template() + sub_sec = {'node_type': 'substituteNodeType', 'capabilities': {'substituteCapability': ['nodeName', 'capabilityName']}} + sub_type = template.db.NODE_TYPES.get('substituteNodeType') + self.assertIsNone(sub_type.mapping_template) + template._parse_substitution(template.db, sub_sec) + self.assertIsNotNone(sub_type.mapping_template) + self.assertEqual(sub_type.mapping_template, template) + + def test_parse_substitution(self): + template = init_template() + sub_sec = {'node_type': 'substituteNodeType', 'requirements': {'substituteRequirement': ['node2', 'dummyRequirement']}, 'capabilities': {'substituteCapability': ['nodeName', 'capabilityName']}} + self.assertIsNone(template.sub_type) + self.assertEqual(len(template.sub_rules), 0) + template._parse_substitution(template.db, sub_sec) + self.assertEqual(template.sub_type, 'substituteNodeType') + self.assertEqual(len(template.sub_rules), 3) + + def test_prepare_output(self): + template = ToscaTopology('topoName') + res = template._prepare_output() + self.assertEqual(res, {'00_YAMLORDER_tosca_definitions_version': 'tosca_simple_yaml_1_0_0', '14_YAMLORDER_topology_template': {}}) + template = init_template() + res = template._prepare_output() + self.assertEqual(res, {'00_YAMLORDER_tosca_definitions_version': 'tosca_simple_yaml_1_0_0', '14_YAMLORDER_topology_template': {'11_YAMLORDER_inputs': {'inputName': {'00_YAMLORDER_type': 'string'}}, + '13_YAMLORDER_node_templates': {'node2': {'00_YAMLORDER_type': 'nodeTypeName', '01_YAMLORDER_properties': {'propertyName': None},'05_YAMLORDER_requirements': [{'dummyRequirement': 'nodeName'}]}, + 'nodeName': {'00_YAMLORDER_type': 'nodeTypeName', '01_YAMLORDER_properties': {'propertyName': None}}}}}) + diff --git a/app/tests/test_value_templates.py b/app/tests/test_value_templates.py new file mode 100644 index 0000000..bc98fa8 --- /dev/null +++ b/app/tests/test_value_templates.py @@ -0,0 +1,227 @@ +import unittest +from toscalib.templates.value import _is_function +from tests.utils.test_utils import init_template + + +class TestValueMethods(unittest.TestCase): + + def test_value_is_get_input_function(self): + value = {'get_input': 'some_input_param'} + res = _is_function(value) + self.assertEqual(res.target_property, 'some_input_param') + self.assertEqual(res.type, 'get_input') + + def test_value_is_simple_string(self): + value = 'not_a_function' + res = _is_function(value) + self.assertIsNone(res) + + def test_value_is_not_valid_function(self): + value = {'function': 'unknown'} + res = _is_function(value) + self.assertIsNone(res) + + def test_value_too_many_functions(self): + value = {'get_input': 'some_input_param', 'get_property': 'some_value'} + res = _is_function(value) + self.assertIsNone(res) + + def test_value_is_concat_function(self): + value = {'concat': ['first', 'second']} + res = _is_function(value) + self.assertEqual(res.type, 'concat') + self.assertEqual(res.extra_data[0].raw_value, 'first') + self.assertEqual(res.extra_data[0].type, 'string') + self.assertEqual(res.extra_data[0].value, 'first') + self.assertEqual(res.extra_data[1].raw_value, 'second') + self.assertEqual(res.extra_data[1].type, 'string') + self.assertEqual(res.extra_data[1].value, 'second') + + def test_invalid_function_values_not_list(self): + value = {'concat': {'first': 'one', 'second': 'two'}} + res = _is_function(value) + self.assertIsNone(res) + + def test_value_is_valid_function(self): + value = {'get_property': ['first', 'second']} + res = _is_function(value) + self.assertEqual(res.type, 'get_property') + self.assertListEqual(res.extra_data, value['get_property']) + + def test_update_get_input_value_prefix(self): + value = {'get_input': 'some_input_param'} + res = _is_function(value) + self.assertEqual(res.target_property, 'some_input_param') + res._update_prefix('PREFIX_') + self.assertEqual(res.target_property, 'PREFIX_some_input_param') + + def test_update_get_property_value_no_prefix(self): + value = {'get_property': ['NO_PREFIX', 'some_property']} + res = _is_function(value) + self.assertEqual(res.extra_data[0], 'NO_PREFIX') + res._update_prefix('PREFIX_') + self.assertEqual(res.extra_data[0], 'PREFIX') + + def test_update_concat_get_input_value_prefix(self): + value = {'concat': [{'get_input': 'some_input_param'}, 'second']} + res = _is_function(value) + self.assertEqual(res.extra_data[0].function.target_property, 'some_input_param') + self.assertEqual(res.extra_data[1].value, 'second') + res._update_prefix('PREFIX_') + self.assertEqual(res.extra_data[0].function.target_property, 'PREFIX_some_input_param') + self.assertEqual(res.extra_data[1].value, 'second') + + def test_update_get_input_function_reference(self): + template = init_template() + value = {'get_input': 'inputName'} + res = _is_function(value) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template) + self.assertEqual(res.value_from_item, template.inputs.get('inputName')) + + # TODO uncomment after merging latest ecomp code + # def test_update_get_input_function_reference_auto_generate_input(self): + # template = init_template() + # node = template.node_dict.get('nodeName') + # value = {'get_input': 'propertyName'} + # res = _is_function(value) + # self.assertIsNone(res.value_from_item) + # self.assertIsNone(template.inputs.get('nodeName_propertyName')) + # self.assertEqual(res.target_property, 'propertyName') + # res._update_function_reference(template, node, node.properties.get('propertyName')) + # self.assertIsNotNone(res.value_from_item) + # self.assertEqual(res.value_from_item, template.inputs.get('nodeName_propertyName')) + + def test_update_get_property_function_reference_node_not_found(self): + value = {'get_property': ['node_name', 'property_name']} + res = _is_function(value) + self.assertIsNone(res.value_from_item) + res._update_function_reference(init_template()) + self.assertIsNone(res.value_from_item) + + def test_update_get_property_function_reference_self_property(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'get_property': ['SELF', 'propertyName']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template, node) + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node.properties.get('propertyName')) + + def test_update_get_property_function_reference_other_node_property(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'get_property': ['nodeName', 'propertyName']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template) + self.assertIsNotNone(res.value_from_node) + self.assertIsNotNone(res.value_from_item) + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node._get_property_item('propertyName')) + + def test_update_get_property_function_reference_capability_property(self): + template = init_template() + value = {'get_property': ['nodeName', 'capabilityName', 'capabilityProperty']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template) + self.assertIsNotNone(res.value_from_node) + self.assertIsNotNone(res.value_from_item) + node = template.node_dict.get('nodeName') + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node._get_capability_property('capabilityName', 'capabilityProperty')) + + def test_update_get_property_function_reference_requirement_capability_property(self): + template = init_template() + value = {'get_property': ['node2', 'dummyRequirement', 'capabilityProperty']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template) + self.assertIsNotNone(res.value_from_node) + self.assertIsNotNone(res.value_from_item) + node = template.node_dict.get('nodeName') + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node._get_capability_property('capabilityName', 'capabilityProperty')) + + def test_update_get_property_function_reference_requirement_target_property(self): + template = init_template() + value = {'get_property': ['node2', 'dummyRequirement', 'propertyName']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template) + self.assertIsNotNone(res.value_from_node) + self.assertIsNotNone(res.value_from_item) + node = template.node_dict.get('nodeName') + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node._get_property_item('propertyName')) + + def test_update_get_attribute_function_reference_invalid_params(self): + value = {'get_attribute': ['no_such_node', 'some_attribute']} + res = _is_function(value) + res._update_function_reference(init_template()) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + + def test_update_get_attribute_function_self_attribute(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'get_attribute': ['SELF', 'attributeName']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template, node) + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node.attributes.get('attributeName')) + + def test_update_get_attribute_function_node_id_attribute(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'get_attribute': ['SELF', 'id']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template, node) + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node.id) + + def test_update_get_attribute_function_other_node_id_attribute(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'get_attribute': ['nodeName', 'id']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template) + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node.id) + + def test_update_get_attribute_function_requirement_target_attribute(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'get_attribute': ['node2', 'dummyRequirement', 'attributeName']} + res = _is_function(value) + self.assertIsNone(res.value_from_node) + self.assertIsNone(res.value_from_item) + res._update_function_reference(template) + self.assertEqual(res.value_from_node, node) + self.assertEqual(res.value_from_item, node.attributes.get('attributeName')) + + def test_update_concat_function_reference(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'concat': [{'get_attribute': ['nodeName', 'id']}, 'second']} + res = _is_function(value) + self.assertIsNone(res.extra_data[0].function.value_from_node) + res._update_function_reference(template) + self.assertIsNotNone(res.extra_data[0].function.value_from_node) + self.assertIsNotNone(res.extra_data[0].function.value_from_item) + self.assertEqual(res.extra_data[0].function.value_from_node, node) + self.assertEqual(res.extra_data[0].function.value_from_item, node.id) + diff --git a/app/tests/test_value_templates_calculate_function_result.py b/app/tests/test_value_templates_calculate_function_result.py new file mode 100644 index 0000000..512c68e --- /dev/null +++ b/app/tests/test_value_templates_calculate_function_result.py @@ -0,0 +1,77 @@ +import unittest +from toscalib.templates.value import _is_function +from tests.utils.test_utils import init_template + + +class TestCalculateFunctionValueMethods(unittest.TestCase): + + def test_get_input_function_representation(self): + value = {'get_input': 'inputName'} + func = _is_function(value) + self.assertEqual(func.target_property, 'inputName') + res = func._get_function_representation() + self.assertEqual(res, value) + + def test_get_self_property_function_representation(self): + value = {'get_property': ['SELF', 'propertyName']} + func = _is_function(value) + self.assertIsNotNone(func.extra_data) + self.assertIsNone(func.value_from_node) + res = func._get_function_representation() + self.assertEqual(res, value) + template = init_template() + node = template.node_dict.get('nodeName') + func._update_function_reference(template, node) + self.assertIsNotNone(func.value_from_node) + res = func._get_function_representation() + self.assertEqual(res, {'get_property': ['nodeName', 'propertyName']}) + + def test_get_attribute_function_representation(self): + value = {'get_attribute': ['SELF', 'attributeName']} + func = _is_function(value) + self.assertIsNotNone(func.extra_data) + self.assertIsNone(func.value_from_node) + res = func._get_function_representation() + self.assertEqual(res, value) + template = init_template() + node = template.node_dict.get('nodeName') + func._update_function_reference(template, node) + self.assertIsNotNone(func.value_from_node) + res = func._get_function_representation() + self.assertEqual(res, {'get_attribute': ['nodeName', 'attributeName']}) + + def test_get_id_attribute_function_representation(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'get_attribute': ['SELF', 'id']} + func = _is_function(value) + func._update_function_reference(template, node) + self.assertIsNotNone(func.value_from_node) + res = func._get_function_representation() + self.assertEqual(res, {'get_attribute': ['nodeName', 'id']}) + res = func._get_function_representation('heat') + self.assertEqual(res, {'get_id': 'nodeName'}) + + def test_calculate_concat_function_result(self): + template = init_template() + node = template.node_dict.get('nodeName') + value = {'concat': [{'get_attribute': ['SELF', 'id']}, {'concat': [{'get_property': ['SELF', 'propertyName']}, 'third', '4']}]} + func = _is_function(value) + res = func._calculate_function_result() + self.assertEqual(res, (value, 2)) + func._update_function_reference(template, node) + res = func._calculate_function_result() + expected = {'concat': [{'get_attribute': ['nodeName', 'id']}, {'concat': [{'get_property': ['nodeName', 'propertyName']}, 'third', '4']}]} + self.assertEqual(res, (expected, 2)) + + def test_calculate_property_function_result(self): + template = init_template() + value = {'get_property': ['node2', 'dummyRequirement', 'propertyName']} + func = _is_function(value) + res = func._calculate_function_result() + self.assertEqual(res, (value, 2)) + func._update_function_reference(template) + res = func._calculate_function_result() + expected = ({'get_property': ['nodeName', 'propertyName']}, 2) + self.assertEqual(res, expected) + diff --git a/app/tests/utils/test_utils.py b/app/tests/utils/test_utils.py new file mode 100644 index 0000000..953683b --- /dev/null +++ b/app/tests/utils/test_utils.py @@ -0,0 +1,24 @@ +from toscalib.templates.topology import ToscaTopology +from toscalib.templates.database import ToscaDB +from toscalib.types.node import NodeType +from toscalib.types.capability import CapabilityType + + +def init_template(): + db = ToscaDB() + capability_type = CapabilityType('tosca.capabilities.dummy', {'properties': {'capabilityProperty': {'type': 'string'}}}) + sub_capability = CapabilityType('tosca.capabilities.substitute', {'properties': {'capabilityProperty': {'type': 'string'}}}) + capability_type._parse_content(db) + sub_capability._parse_content(db) + db._import_capability_type(capability_type) + db._import_capability_type(sub_capability) + node_type = NodeType('nodeTypeName', {'id': 'nodeId', 'attributes': {'attributeName': {'type': 'string'}}, 'properties': {'propertyName': {'type': 'string'}}, 'capabilities': {'capabilityName': {'type': 'tosca.capabilities.dummy'}}, 'requirements': [{'dummyRequirement': {'capability': 'tosca.capabilities.dummy'}}]}) + sub_node = NodeType('substituteNodeType', {'id': 'subNodeId', 'properties': {'inputName': {'type': 'string'}}, 'capabilities': {'substituteCapability': {'type': 'tosca.capabilities.substitute'}}, 'requirements': [{'substituteRequirement': {'capability': 'tosca.capabilities.substitute'}}]}) + node_type._parse_content(db) + sub_node._parse_content(db) + db._import_node_type(node_type) + db._import_node_type(sub_node) + template = ToscaTopology('templateName', None, {'inputs': {'inputName': {'type': 'string'}}, 'node_templates': {'nodeName': {'type': 'nodeTypeName'}, 'node2': {'type': 'nodeTypeName', 'requirements': [{'dummyRequirement': 'nodeName'}]}}}) + template._parse_content(db) + return template + -- cgit 1.2.3-korg