######## # Copyright (c) 2013 GigaSpaces Technologies Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # * See the License for the specific language governing permissions and # * limitations under the License. import os import yaml as yml from urllib import pathname2url from dsl_parser import exceptions from dsl_parser import constants from dsl_parser import version from dsl_parser import models from dsl_parser.tests.abstract_test_parser import AbstractTestParser from dsl_parser.parser import parse_from_path from dsl_parser.parser import parse as dsl_parse from dsl_parser.interfaces.constants import NO_OP from dsl_parser.interfaces.utils import operation_mapping from dsl_parser.constants import TYPE_HIERARCHY def op_struct(plugin_name, mapping, inputs=None, executor=None, max_retries=None, retry_interval=None): if not inputs: inputs = {} result = { 'plugin': plugin_name, 'operation': mapping, 'inputs': inputs, 'executor': executor, 'has_intrinsic_functions': False, 'max_retries': max_retries, 'retry_interval': retry_interval } return result def workflow_op_struct(plugin_name, mapping, parameters=None): if not parameters: parameters = {} return { 'plugin': plugin_name, 'operation': mapping, 'parameters': parameters } class TestParserApi(AbstractTestParser): def _assert_minimal_blueprint(self, result, expected_type='test_type'): self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_node', node['name']) self.assertEquals(expected_type, node['type']) self.assertEquals('val', node['properties']['key']) # self.assertEquals(1, node['instances']['deploy']) def test_minimal_blueprint(self): result = self.parse(self.MINIMAL_BLUEPRINT) self._assert_minimal_blueprint(result) def test_import_from_path(self): yaml = self.create_yaml_with_imports([self.MINIMAL_BLUEPRINT]) result = self.parse(yaml) self._assert_minimal_blueprint(result) def _assert_blueprint(self, result): node = result['nodes'][0] self.assertEquals('test_type', node['type']) plugin_props = [p for p in node['plugins'] if p['name'] == 'test_plugin'][0] self.assertEquals(11, len(plugin_props)) self.assertEquals('test_plugin', plugin_props[constants.PLUGIN_NAME_KEY]) operations = node['operations'] self.assertEquals(op_struct('test_plugin', 'install', executor='central_deployment_agent'), operations['install']) self.assertEquals(op_struct('test_plugin', 'install', executor='central_deployment_agent'), operations['test_interface1.install']) self.assertEquals(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), operations['terminate']) self.assertEquals(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), operations['test_interface1.terminate']) def test_type_with_single_explicit_interface_and_plugin(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + self.BASIC_PLUGIN + """ node_types: test_type: interfaces: test_interface1: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} start: implementation: test_plugin.start inputs: {} properties: install_agent: default: false key: {} number: default: 80 boolean: default: false complex: default: key1: value1 key2: value2 """ result = self.parse(yaml) self._assert_blueprint(result) def test_type_with_interfaces_and_basic_plugin(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS result = self.parse(yaml) self._assert_blueprint(result) first_node = result['nodes'][0] parsed_plugins = first_node['plugins'] expected_plugins = [{ constants.PLUGIN_NAME_KEY: 'test_plugin', constants.PLUGIN_SOURCE_KEY: 'dummy', constants.PLUGIN_INSTALL_KEY: True, constants.PLUGIN_EXECUTOR_KEY: constants.CENTRAL_DEPLOYMENT_AGENT, constants.PLUGIN_INSTALL_ARGUMENTS_KEY: None, constants.PLUGIN_PACKAGE_NAME: None, constants.PLUGIN_PACKAGE_VERSION: None, constants.PLUGIN_SUPPORTED_PLATFORM: None, constants.PLUGIN_DISTRIBUTION: None, constants.PLUGIN_DISTRIBUTION_VERSION: None, constants.PLUGIN_DISTRIBUTION_RELEASE: None }] self.assertEquals(parsed_plugins, expected_plugins) def test_type_with_interface_and_plugin_with_install_args(self): yaml = self.PLUGIN_WITH_INTERFACES_AND_PLUGINS_WITH_INSTALL_ARGS result = self.parse(yaml, dsl_version=self.BASIC_VERSION_SECTION_DSL_1_1) self._assert_blueprint(result) first_node = result['nodes'][0] parsed_plugins = first_node['plugins'] expected_plugins = [{ constants.PLUGIN_NAME_KEY: 'test_plugin', constants.PLUGIN_SOURCE_KEY: 'dummy', constants.PLUGIN_INSTALL_KEY: True, constants.PLUGIN_EXECUTOR_KEY: constants.CENTRAL_DEPLOYMENT_AGENT, constants.PLUGIN_INSTALL_ARGUMENTS_KEY: '-r requirements.txt', constants.PLUGIN_PACKAGE_NAME: None, constants.PLUGIN_PACKAGE_VERSION: None, constants.PLUGIN_SUPPORTED_PLATFORM: None, constants.PLUGIN_DISTRIBUTION: None, constants.PLUGIN_DISTRIBUTION_VERSION: None, constants.PLUGIN_DISTRIBUTION_RELEASE: None }] self.assertEquals(parsed_plugins, expected_plugins) def test_dsl_with_type_with_operation_mappings(self): yaml = self.create_yaml_with_imports( [self.BASIC_NODE_TEMPLATES_SECTION, self.BASIC_PLUGIN]) + """ node_types: test_type: properties: key: {} interfaces: test_interface1: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} test_interface2: start: implementation: other_test_plugin.start inputs: {} shutdown: implementation: other_test_plugin.shutdown inputs: {} plugins: other_test_plugin: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) node = result['nodes'][0] self._assert_blueprint(result) operations = node['operations'] self.assertEquals(op_struct('other_test_plugin', 'start', executor='central_deployment_agent'), operations['start']) self.assertEquals(op_struct('other_test_plugin', 'start', executor='central_deployment_agent'), operations['test_interface2.start']) self.assertEquals(op_struct('other_test_plugin', 'shutdown', executor='central_deployment_agent'), operations['shutdown']) self.assertEquals(op_struct('other_test_plugin', 'shutdown', executor='central_deployment_agent'), operations['test_interface2.shutdown']) def test_recursive_imports(self): bottom_level_yaml = self.BASIC_TYPE bottom_file_name = self.make_yaml_file(bottom_level_yaml) mid_level_yaml = self.BASIC_PLUGIN + """ imports: - {0}""".format(bottom_file_name) mid_file_name = self.make_yaml_file(mid_level_yaml) top_level_yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ imports: - {0}""".format(mid_file_name) result = self.parse(top_level_yaml) self._assert_blueprint(result) def test_parse_dsl_from_file(self): filename = self.make_yaml_file(self.BASIC_VERSION_SECTION_DSL_1_0 + self.MINIMAL_BLUEPRINT) result = parse_from_path(filename) self._assert_minimal_blueprint(result) def test_import_empty_list(self): yaml = self.MINIMAL_BLUEPRINT + """ imports: [] """ result = self.parse(yaml) self._assert_minimal_blueprint(result) def test_blueprint_description_field(self): yaml = self.MINIMAL_BLUEPRINT + self.BASIC_VERSION_SECTION_DSL_1_2 +\ """ description: sample description """ result = self.parse(yaml) self._assert_minimal_blueprint(result) self.assertIn('description', result) self.assertEquals('sample description', result['description']) def test_blueprint_description_field_omitted(self): yaml = self.MINIMAL_BLUEPRINT + self.BASIC_VERSION_SECTION_DSL_1_2 result = self.parse(yaml) self._assert_minimal_blueprint(result) self.assertIn('description', result) self.assertEquals(None, result['description']) def test_diamond_imports(self): bottom_level_yaml = self.BASIC_TYPE bottom_file_name = self.make_yaml_file(bottom_level_yaml) mid_level_yaml = self.BASIC_PLUGIN + """ imports: - {0}""".format(bottom_file_name) mid_file_name = self.make_yaml_file(mid_level_yaml) mid_level_yaml2 = """ imports: - {0}""".format(bottom_file_name) mid_file_name2 = self.make_yaml_file(mid_level_yaml2) top_level_yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ imports: - {0} - {1}""".format(mid_file_name, mid_file_name2) result = self.parse(top_level_yaml) self._assert_blueprint(result) def _create_importable_yaml_for_version_1_3_and_above(self, importable): imported_yaml = self.make_yaml_file( self.BASIC_TYPE + self.BASIC_PLUGIN + importable) main_yaml = """ imports: - {0}""".format(imported_yaml) + \ self.BASIC_NODE_TEMPLATES_SECTION + \ self.BASIC_INPUTS + \ self.BASIC_OUTPUTS return main_yaml def _verify_1_2_and_below_non_mergeable_imports(self, importable, import_type): main_yaml = self._create_importable_yaml_for_version_1_3_and_above( importable) ex = self.assertRaises( exceptions.DSLParsingLogicException, self.parse_1_2, main_yaml) self.assertIn("Import failed: non-mergeable field: '{0}'".format( import_type), str(ex)) def _verify_1_3_and_above_mergeable_imports(self, importable): main_yaml = self._create_importable_yaml_for_version_1_3_and_above( importable) result = self.parse_1_3(main_yaml) self._assert_blueprint(result) def test_version_1_2_and_above_input_imports(self): importable = """ inputs: test_input2: default: value """ self._verify_1_2_and_below_non_mergeable_imports( importable, 'inputs') self._verify_1_3_and_above_mergeable_imports(importable) def test_version_1_2_and_above_node_template_imports(self): importable = """ node_templates: test_node2: type: test_type properties: key: "val" """ self._verify_1_2_and_below_non_mergeable_imports( importable, 'node_templates') self._verify_1_3_and_above_mergeable_imports(importable) def test_version_1_2_and_above_output_imports(self): importable = """ outputs: test_output2: value: value """ self._verify_1_2_and_below_non_mergeable_imports( importable, 'outputs') self._verify_1_3_and_above_mergeable_imports(importable) def test_node_get_type_properties_including_overriding_properties(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: properties: key: default: "not_val" key2: default: "val2" """ result = self.parse(yaml) # this will also check property "key" = "val" self._assert_minimal_blueprint(result) node = result['nodes'][0] self.assertEquals('val2', node['properties']['key2']) def test_type_properties_empty_properties(self): yaml = """ node_templates: test_node: type: test_type node_types: test_type: properties: {} """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_node', node['name']) self.assertEquals('test_type', node['type']) def test_type_properties_empty_property(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: properties: key: {} """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_node', node['name']) self.assertEquals('test_type', node['type']) self.assertEquals('val', node['properties']['key']) # TODO: assert node-type's default and description values once # 'node_types' is part of the parser's output def test_type_properties_property_with_description_only(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: properties: key: description: property_desc """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_node', node['name']) self.assertEquals('test_type', node['type']) self.assertEquals('val', node['properties']['key']) # TODO: assert type's default and description values once 'type' is # part of the parser's output def test_type_properties_standard_property(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: properties: key: default: val description: property_desc type: string """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_node', node['name']) self.assertEquals('test_type', node['type']) self.assertEquals('val', node['properties']['key']) # TODO: assert type's default and description values once 'type' is # part of the parser's output def test_type_properties_derivation(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: properties: key: default: "not_val" key2: default: "val2" derived_from: "test_type_parent" test_type_parent: properties: key: default: "val1_parent" key2: default: "val2_parent" key3: default: "val3_parent" """ result = self.parse(yaml) # this will also check property "key" = "val" self._assert_minimal_blueprint(result) node = result['nodes'][0] self.assertEquals('val2', node['properties']['key2']) self.assertEquals('val3_parent', node['properties']['key3']) def test_empty_types_hierarchy_in_node(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: properties: key: default: "not_val" key2: default: "val2" """ result = self.parse(yaml) node = result['nodes'][0] self.assertEqual(1, len(node[TYPE_HIERARCHY])) self.assertEqual('test_type', node[TYPE_HIERARCHY][0]) def test_types_hierarchy_in_node(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: derived_from: "test_type_parent" properties: key: default: "not_val" key2: default: "val2" test_type_parent: {} """ result = self.parse(yaml) node = result['nodes'][0] self.assertEqual(2, len(node[TYPE_HIERARCHY])) self.assertEqual('test_type_parent', node[TYPE_HIERARCHY][0]) self.assertEqual('test_type', node[TYPE_HIERARCHY][1]) def test_types_hierarchy_order_in_node(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: derived_from: "test_type_parent" properties: key: default: "not_val" key2: default: "val2" test_type_parent: derived_from: "parent_type" parent_type: {} """ result = self.parse(yaml) node = result['nodes'][0] self.assertEqual(3, len(node[TYPE_HIERARCHY])) self.assertEqual('parent_type', node[TYPE_HIERARCHY][0]) self.assertEqual('test_type_parent', node[TYPE_HIERARCHY][1]) self.assertEqual('test_type', node[TYPE_HIERARCHY][2]) def test_type_properties_recursive_derivation(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ node_types: test_type: properties: key: default: "not_val" key2: default: "val2" derived_from: "test_type_parent" test_type_parent: properties: key: default: "val_parent" key2: default: "val2_parent" key4: default: "val4_parent" derived_from: "test_type_grandparent" test_type_grandparent: properties: key: default: "val1_grandparent" key2: default: "val2_grandparent" key3: default: "val3_grandparent" derived_from: "test_type_grandgrandparent" test_type_grandgrandparent: {} """ result = self.parse(yaml) # this will also check property "key" = "val" self._assert_minimal_blueprint(result) node = result['nodes'][0] self.assertEquals('val2', node['properties']['key2']) self.assertEquals('val3_grandparent', node['properties']['key3']) self.assertEquals('val4_parent', node['properties']['key4']) def test_type_interface_derivation(self): yaml = self.create_yaml_with_imports( [self.BASIC_NODE_TEMPLATES_SECTION, self.BASIC_PLUGIN]) + """ node_types: test_type: properties: key: {} interfaces: test_interface1: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} test_interface2: start: implementation: test_plugin2.start inputs: {} stop: implementation: test_plugin2.stop inputs: {} test_interface3: op1: implementation: test_plugin3.op inputs: {} derived_from: test_type_parent test_type_parent: interfaces: test_interface1: install: implementation: nop_plugin.install inputs: {} terminate: implementation: nop_plugin.install inputs: {} test_interface2: start: implementation: test_plugin2.start inputs: {} stop: implementation: test_plugin2.stop inputs: {} test_interface3: op1: implementation: test_plugin3.op inputs: {} test_interface4: op2: implementation: test_plugin4.op2 inputs: {} plugins: test_plugin2: executor: central_deployment_agent source: dummy test_plugin3: executor: central_deployment_agent source: dummy test_plugin4: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) self._assert_blueprint(result) node = result['nodes'][0] operations = node['operations'] self.assertEquals(12, len(operations)) self.assertEquals(op_struct('test_plugin2', 'start', executor='central_deployment_agent'), operations['start']) self.assertEquals(op_struct('test_plugin2', 'start', executor='central_deployment_agent'), operations['test_interface2.start']) self.assertEquals(op_struct('test_plugin2', 'stop', executor='central_deployment_agent'), operations['stop']) self.assertEquals(op_struct('test_plugin2', 'stop', executor='central_deployment_agent'), operations['test_interface2.stop']) self.assertEquals(op_struct('test_plugin3', 'op', executor='central_deployment_agent'), operations['op1']) self.assertEquals(op_struct('test_plugin3', 'op', executor='central_deployment_agent'), operations['test_interface3.op1']) self.assertEquals(op_struct('test_plugin4', 'op2', executor='central_deployment_agent'), operations['op2']) self.assertEquals(op_struct('test_plugin4', 'op2', executor='central_deployment_agent'), operations['test_interface4.op2']) self.assertEquals(4, len(node['plugins'])) def test_type_interface_recursive_derivation(self): yaml = self.create_yaml_with_imports( [self.BASIC_NODE_TEMPLATES_SECTION, self.BASIC_PLUGIN]) + """ node_types: test_type: properties: key: {} interfaces: test_interface1: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} derived_from: test_type_parent test_type_parent: derived_from: test_type_grandparent test_type_grandparent: interfaces: test_interface1: install: implementation: non_plugin.install inputs: {} terminate: implementation: non_plugin.terminate inputs: {} test_interface2: start: implementation: test_plugin2.start inputs: {} stop: implementation: test_plugin2.stop inputs: {} plugins: test_plugin2: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) self._assert_blueprint(result) node = result['nodes'][0] operations = node['operations'] self.assertEquals(8, len(operations)) self.assertEquals(op_struct('test_plugin2', 'start', executor='central_deployment_agent'), operations['start']) self.assertEquals(op_struct('test_plugin2', 'start', executor='central_deployment_agent'), operations['test_interface2.start']) self.assertEquals(op_struct('test_plugin2', 'stop', executor='central_deployment_agent'), operations['stop']) self.assertEquals(op_struct('test_plugin2', 'stop', executor='central_deployment_agent'), operations['test_interface2.stop']) self.assertEquals(2, len(node['plugins'])) def test_two_explicit_interfaces_with_same_operation_name(self): yaml = self.create_yaml_with_imports( [self.BASIC_NODE_TEMPLATES_SECTION, self.BASIC_PLUGIN]) + """ node_types: test_type: properties: key: {} interfaces: test_interface1: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} test_interface2: install: implementation: other_test_plugin.install inputs: {} shutdown: implementation: other_test_plugin.shutdown inputs: {} plugins: other_test_plugin: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) node = result['nodes'][0] self.assertEquals('test_type', node['type']) operations = node['operations'] self.assertEquals(op_struct('test_plugin', 'install', executor='central_deployment_agent'), operations['test_interface1.install']) self.assertEquals(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), operations['terminate']) self.assertEquals(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), operations['test_interface1.terminate']) self.assertEquals(op_struct('other_test_plugin', 'install', executor='central_deployment_agent'), operations['test_interface2.install']) self.assertEquals(op_struct('other_test_plugin', 'shutdown', executor='central_deployment_agent'), operations['shutdown']) self.assertEquals(op_struct('other_test_plugin', 'shutdown', executor='central_deployment_agent'), operations['test_interface2.shutdown']) self.assertEquals(6, len(operations)) def test_relative_path_import(self): bottom_level_yaml = self.BASIC_TYPE self.make_file_with_name(bottom_level_yaml, 'bottom_level.yaml') mid_level_yaml = self.BASIC_PLUGIN + """ imports: - \"bottom_level.yaml\"""" mid_file_name = self.make_yaml_file(mid_level_yaml) top_level_yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ imports: - {0}""".format(mid_file_name) result = self.parse(top_level_yaml) self._assert_blueprint(result) def test_import_from_file_uri(self): yaml = self.create_yaml_with_imports([self.MINIMAL_BLUEPRINT], True) result = self.parse(yaml) self._assert_minimal_blueprint(result) def test_relative_file_uri_import(self): bottom_level_yaml = self.BASIC_TYPE self.make_file_with_name(bottom_level_yaml, 'bottom_level.yaml') mid_level_yaml = self.BASIC_PLUGIN + """ imports: - \"bottom_level.yaml\"""" mid_file_name = self.make_yaml_file(mid_level_yaml) top_level_yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ imports: - {0}""".format('file:///' + pathname2url(mid_file_name)) result = self.parse(top_level_yaml) self._assert_blueprint(result) def test_empty_top_level_relationships(self): yaml = self.MINIMAL_BLUEPRINT + """ relationships: {} """ result = self.parse(yaml) self._assert_minimal_blueprint(result) self.assertEquals(0, len(result['relationships'])) def test_empty_top_level_relationships_empty_relationship(self): yaml = self.MINIMAL_BLUEPRINT + """ relationships: test_relationship: {} """ result = self.parse(yaml) self._assert_minimal_blueprint(result) self.assertEqual({'name': 'test_relationship', 'properties': {}, 'source_interfaces': {}, 'target_interfaces': {}, 'type_hierarchy': ['test_relationship']}, result['relationships']['test_relationship']) def test_top_level_relationships_single_complete_relationship(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ relationships: empty_rel: {} test_relationship: derived_from: empty_rel source_interfaces: test_interface3: test_interface3_op1: {} target_interfaces: test_interface4: test_interface4_op1: implementation: test_plugin.task_name inputs: {} """ result = self.parse(yaml) self._assert_blueprint(result) self.assertEqual({'name': 'empty_rel', 'properties': {}, 'source_interfaces': {}, 'target_interfaces': {}, 'type_hierarchy': ['empty_rel']}, result['relationships']['empty_rel']) test_relationship = result['relationships']['test_relationship'] self.assertEquals('test_relationship', test_relationship['name']) self.assertEquals(test_relationship['type_hierarchy'], ['empty_rel', 'test_relationship']) result_test_interface_3 = \ test_relationship['source_interfaces']['test_interface3'] self.assertEquals(NO_OP, result_test_interface_3['test_interface3_op1']) result_test_interface_4 = \ test_relationship['target_interfaces']['test_interface4'] self.assertEquals( operation_mapping(implementation='test_plugin.task_name', inputs={}, executor=None, max_retries=None, retry_interval=None), result_test_interface_4['test_interface4_op1']) def test_top_level_relationships_recursive_imports(self): bottom_level_yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ relationships: empty_rel: {} test_relationship: derived_from: empty_rel source_interfaces: test_interface2: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} """ bottom_file_name = self.make_yaml_file(bottom_level_yaml) mid_level_yaml = """ relationships: test_relationship2: derived_from: "test_relationship3" imports: - {0}""".format(bottom_file_name) mid_file_name = self.make_yaml_file(mid_level_yaml) top_level_yaml = """ relationships: test_relationship3: target_interfaces: test_interface2: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} imports: - """ + mid_file_name result = self.parse(top_level_yaml) self._assert_blueprint(result) self.assertEqual({'name': 'empty_rel', 'properties': {}, 'source_interfaces': {}, 'target_interfaces': {}, 'type_hierarchy': ['empty_rel']}, result['relationships']['empty_rel']) test_relationship = result['relationships']['test_relationship'] self.assertEquals('test_relationship', test_relationship['name']) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), test_relationship['source_interfaces'][ 'test_interface2']['install']) self.assertEqual( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), test_relationship['source_interfaces'][ 'test_interface2']['terminate']) self.assertEquals( 2, len(test_relationship['source_interfaces'][ 'test_interface2'])) self.assertEquals(6, len(test_relationship)) test_relationship2 = result['relationships']['test_relationship2'] self.assertEquals('test_relationship2', test_relationship2['name']) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), test_relationship2['target_interfaces'][ 'test_interface2']['install']) self.assertEqual( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), test_relationship2['target_interfaces'][ 'test_interface2']['terminate']) self.assertEquals( 2, len(test_relationship2['target_interfaces'][ 'test_interface2'])) self.assertEquals(6, len(test_relationship2)) test_relationship3 = result['relationships']['test_relationship3'] self.assertEquals('test_relationship3', test_relationship3['name']) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), test_relationship3['target_interfaces'][ 'test_interface2']['install']) self.assertEqual( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), test_relationship3['target_interfaces'][ 'test_interface2']['terminate']) self.assertEquals( 2, len(test_relationship3['target_interfaces'][ 'test_interface2'])) self.assertEquals(5, len(test_relationship3)) def test_top_level_relationship_properties(self): yaml = self.MINIMAL_BLUEPRINT + """ relationships: test_relationship: properties: without_default_value: {} with_simple_default_value: default: 1 with_object_default_value: default: comp1: 1 comp2: 2 """ result = self.parse(yaml) self._assert_minimal_blueprint(result) relationships = result['relationships'] self.assertEquals(1, len(relationships)) test_relationship = relationships['test_relationship'] properties = test_relationship['properties'] self.assertIn('without_default_value', properties) self.assertIn('with_simple_default_value', properties) self.assertEquals({'default': 1}, properties[ 'with_simple_default_value']) self.assertEquals({'default': {'comp1': 1, 'comp2': 2}}, properties[ 'with_object_default_value']) def test_top_level_relationship_properties_inheritance(self): yaml = self.MINIMAL_BLUEPRINT + """ relationships: test_relationship1: properties: prop1: {} prop2: {} prop3: default: prop3_value_1 derived1: default: derived1_value test_relationship2: derived_from: test_relationship1 properties: prop2: default: prop2_value_2 prop3: default: prop3_value_2 prop4: {} prop5: {} prop6: default: prop6_value_2 derived2: default: derived2_value test_relationship3: derived_from: test_relationship2 properties: prop5: default: prop5_value_3 prop6: default: prop6_value_3 prop7: {} """ result = self.parse(yaml) self._assert_minimal_blueprint(result) relationships = result['relationships'] self.assertEquals(3, len(relationships)) r1_properties = relationships['test_relationship1']['properties'] r2_properties = relationships['test_relationship2']['properties'] r3_properties = relationships['test_relationship3']['properties'] self.assertEquals(4, len(r1_properties)) self.assertIn('prop1', r1_properties) self.assertIn('prop2', r1_properties) self.assertIn('prop3', r1_properties) self.assertIn('derived1', r1_properties) self.assertEquals({'default': 'prop3_value_1'}, r1_properties['prop3']) self.assertEquals({'default': 'derived1_value'}, r1_properties[ 'derived1']) self.assertEquals(8, len(r2_properties)) self.assertIn('prop1', r2_properties) self.assertIn('prop2', r2_properties) self.assertIn('prop3', r2_properties) self.assertIn('prop4', r2_properties) self.assertIn('prop5', r2_properties) self.assertIn('prop6', r2_properties) self.assertIn('derived1', r2_properties) self.assertIn('derived2', r2_properties) self.assertEquals({'default': 'prop2_value_2'}, r2_properties[ 'prop2']) self.assertEquals({'default': 'prop3_value_2'}, r2_properties[ 'prop3']) self.assertEquals({'default': 'prop6_value_2'}, r2_properties[ 'prop6']) self.assertEquals({'default': 'derived1_value'}, r2_properties[ 'derived1']) self.assertEquals({'default': 'derived2_value'}, r2_properties[ 'derived2']) self.assertEquals(9, len(r3_properties)) self.assertIn('prop1', r3_properties) self.assertIn('prop2', r3_properties) self.assertIn('prop3', r3_properties) self.assertIn('prop4', r3_properties) self.assertIn('prop5', r3_properties) self.assertIn('prop6', r3_properties) self.assertIn('prop7', r3_properties) self.assertIn('derived1', r3_properties) self.assertIn('derived2', r3_properties) self.assertEquals({'default': 'prop2_value_2'}, r3_properties[ 'prop2']) self.assertEquals({'default': 'prop3_value_2'}, r3_properties[ 'prop3']) self.assertEquals({'default': 'prop5_value_3'}, r3_properties[ 'prop5']) self.assertEquals({'default': 'prop6_value_3'}, r3_properties[ 'prop6']) self.assertEquals({'default': 'derived1_value'}, r3_properties[ 'derived1']) self.assertEquals({'default': 'derived2_value'}, r3_properties[ 'derived2']) def test_instance_relationships_empty_relationships_section(self): yaml = self.MINIMAL_BLUEPRINT + """ relationships: [] """ result = self.parse(yaml) self._assert_minimal_blueprint(result) self.assertTrue(isinstance(result['nodes'][0]['relationships'], list)) self.assertEqual(0, len(result['nodes'][0]['relationships'])) def test_instance_relationships_standard_relationship(self): yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: test_relationship target: test_node source_interfaces: test_interface1: install: test_plugin.install relationships: test_relationship: {} plugins: test_plugin: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) self.assertEquals('test_node2', nodes[1]['id']) self.assertEquals(1, len(nodes[1]['relationships'])) relationship = nodes[1]['relationships'][0] self.assertEquals('test_relationship', relationship['type']) self.assertEquals('test_node', relationship['target_id']) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['source_interfaces']['test_interface1']['install']) relationship_source_operations = relationship['source_operations'] self.assertEqual(op_struct('test_plugin', 'install', executor='central_deployment_agent'), relationship_source_operations['install']) self.assertEqual( op_struct('test_plugin', 'install', executor='central_deployment_agent'), relationship_source_operations['test_interface1.install']) self.assertEqual(2, len(relationship_source_operations)) self.assertEquals(8, len(relationship)) plugin_def = nodes[1]['plugins'][0] self.assertEquals('test_plugin', plugin_def['name']) def test_instance_relationships_duplicate_relationship(self): # right now, having two relationships with the same (type,target) # under one node is valid yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: test_relationship target: test_node - type: test_relationship target: test_node relationships: test_relationship: {} """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) self.assertEquals('test_node2', nodes[1]['id']) self.assertEquals(2, len(nodes[1]['relationships'])) self.assertEquals('test_relationship', nodes[1]['relationships'][0]['type']) self.assertEquals('test_relationship', nodes[1]['relationships'][1]['type']) self.assertEquals('test_node', nodes[1]['relationships'][0]['target_id']) self.assertEquals('test_node', nodes[1]['relationships'][1]['target_id']) self.assertEquals(8, len(nodes[1]['relationships'][0])) self.assertEquals(8, len(nodes[1]['relationships'][1])) def test_instance_relationships_relationship_inheritance(self): # possibly 'inheritance' is the wrong term to use here, # the meaning is for checking that the relationship properties from the # top-level relationships # section are used for instance-relationships which declare their types # note there are no overrides in this case; these are tested in the # next, more thorough test yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: test_relationship target: test_node source_interfaces: interface1: op1: test_plugin.task_name1 relationships: relationship: {} test_relationship: derived_from: relationship target_interfaces: interface2: op2: implementation: test_plugin.task_name2 inputs: {} plugins: test_plugin: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) relationship = nodes[1]['relationships'][0] self.assertEquals('test_relationship', relationship['type']) self.assertEquals('test_node', relationship['target_id']) self.assertEqual( operation_mapping(implementation='test_plugin.task_name1', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['source_interfaces']['interface1']['op1']) self.assertEqual( operation_mapping(implementation='test_plugin.task_name2', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['target_interfaces']['interface2']['op2']) rel_source_ops = relationship['source_operations'] self.assertEqual(op_struct('test_plugin', 'task_name1', executor='central_deployment_agent'), rel_source_ops['op1']) self.assertEqual(op_struct('test_plugin', 'task_name1', executor='central_deployment_agent'), rel_source_ops['interface1.op1']) self.assertEquals(2, len(rel_source_ops)) rel_target_ops = relationship['target_operations'] self.assertEqual(op_struct('test_plugin', 'task_name2', executor='central_deployment_agent'), rel_target_ops['op2']) self.assertEqual(op_struct('test_plugin', 'task_name2', executor='central_deployment_agent'), rel_target_ops['interface2.op2']) self.assertEquals(2, len(rel_target_ops)) self.assertEquals(8, len(relationship)) def test_instance_relationship_properties_inheritance(self): yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type properties: key: "val" relationships: - type: empty_relationship target: test_node properties: prop1: prop1_value_new prop2: prop2_value_new prop7: prop7_value_new_instance relationships: empty_relationship: properties: prop1: {} prop2: {} prop7: {} """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) relationships = result['relationships'] self.assertEquals(1, len(relationships)) i_properties = nodes[1]['relationships'][0]['properties'] self.assertEquals(3, len(i_properties)) self.assertEquals('prop1_value_new', i_properties['prop1']) self.assertEquals('prop2_value_new', i_properties['prop2']) self.assertEquals('prop7_value_new_instance', i_properties['prop7']) def test_relationships_and_node_recursive_inheritance(self): # testing for a complete inheritance path for relationships # from top-level relationships to a relationship instance yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: relationship target: test_node source_interfaces: test_interface3: install: test_plugin.install target_interfaces: test_interface1: install: test_plugin.install relationships: relationship: derived_from: parent_relationship source_interfaces: test_interface2: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} parent_relationship: target_interfaces: test_interface3: install: {} plugins: test_plugin: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) node_relationship = nodes[1]['relationships'][0] relationship = result['relationships']['relationship'] parent_relationship = result['relationships']['parent_relationship'] self.assertEquals(2, len(result['relationships'])) self.assertEquals(5, len(parent_relationship)) self.assertEquals(6, len(relationship)) self.assertEquals(8, len(node_relationship)) self.assertEquals('parent_relationship', parent_relationship['name']) self.assertEquals(1, len(parent_relationship['target_interfaces'])) self.assertEquals(1, len(parent_relationship['target_interfaces'] ['test_interface3'])) self.assertEquals( {'implementation': '', 'inputs': {}, 'executor': None, 'max_retries': None, 'retry_interval': None}, parent_relationship['target_interfaces'][ 'test_interface3']['install']) self.assertEquals('relationship', relationship['name']) self.assertEquals('parent_relationship', relationship['derived_from']) self.assertEquals(1, len(relationship['target_interfaces'])) self.assertEquals(1, len(relationship['target_interfaces'] ['test_interface3'])) self.assertEquals( NO_OP, relationship['target_interfaces']['test_interface3']['install']) self.assertEquals(1, len(relationship['source_interfaces'])) self.assertEquals(2, len(relationship['source_interfaces'] ['test_interface2'])) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['source_interfaces']['test_interface2']['install']) self.assertEqual( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['source_interfaces'][ 'test_interface2']['terminate']) self.assertEquals('relationship', node_relationship['type']) self.assertEquals('test_node', node_relationship['target_id']) self.assertEquals(2, len(node_relationship['target_interfaces'])) self.assertEquals(1, len(node_relationship['target_interfaces'] ['test_interface3'])) self.assertEquals( NO_OP, node_relationship['target_interfaces'][ 'test_interface3']['install']) self.assertEquals(1, len(node_relationship['target_interfaces'] ['test_interface1'])) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), node_relationship['target_interfaces'][ 'test_interface1']['install']) self.assertEquals(2, len(node_relationship['source_interfaces'])) self.assertEquals(1, len(node_relationship['source_interfaces'] ['test_interface3'])) self.assertEquals( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), node_relationship['source_interfaces'][ 'test_interface2']['install']) self.assertEquals(2, len(node_relationship['source_interfaces'] ['test_interface2'])) self.assertEquals( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), node_relationship['source_interfaces'][ 'test_interface2']['install']) self.assertEquals( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), node_relationship['source_interfaces'][ 'test_interface2']['terminate']) rel_source_ops = node_relationship['source_operations'] self.assertEquals(4, len(rel_source_ops)) self.assertEqual(op_struct('test_plugin', 'install', executor='central_deployment_agent'), rel_source_ops['test_interface2.install']) self.assertEqual(op_struct('test_plugin', 'install', executor='central_deployment_agent'), rel_source_ops['test_interface3.install']) self.assertEqual(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), rel_source_ops['terminate']) self.assertEqual(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), rel_source_ops['test_interface2.terminate']) rel_target_ops = node_relationship['target_operations'] self.assertEquals(2, len(rel_target_ops)) self.assertEqual(op_struct('', '', {}), rel_target_ops['test_interface3.install']) self.assertEqual(op_struct('test_plugin', 'install', executor='central_deployment_agent'), rel_target_ops['test_interface1.install']) def test_relationship_interfaces_inheritance_merge(self): # testing for a complete inheritance path for relationships # from top-level relationships to a relationship instance yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: relationship target: test_node target_interfaces: test_interface: destroy: test_plugin.destroy1 source_interfaces: test_interface: install2: test_plugin.install2 destroy2: test_plugin.destroy2 relationships: parent_relationship: target_interfaces: test_interface: install: {} source_interfaces: test_interface: install2: {} relationship: derived_from: parent_relationship target_interfaces: test_interface: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} source_interfaces: test_interface: install2: implementation: test_plugin.install inputs: {} terminate2: implementation: test_plugin.terminate inputs: {} plugins: test_plugin: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) node_relationship = nodes[1]['relationships'][0] relationship = result['relationships']['relationship'] parent_relationship = result['relationships']['parent_relationship'] self.assertEquals(2, len(result['relationships'])) self.assertEquals(5, len(parent_relationship)) self.assertEquals(6, len(relationship)) self.assertEquals(8, len(node_relationship)) self.assertEquals('parent_relationship', parent_relationship['name']) self.assertEquals(1, len(parent_relationship['target_interfaces'])) self.assertEquals(1, len(parent_relationship['target_interfaces'] ['test_interface'])) self.assertIn('install', parent_relationship['target_interfaces'] ['test_interface']) self.assertEquals(1, len(parent_relationship['source_interfaces'])) self.assertEquals(1, len(parent_relationship['source_interfaces'] ['test_interface'])) self.assertIn('install2', parent_relationship[ 'source_interfaces']['test_interface']) self.assertEquals('relationship', relationship['name']) self.assertEquals('parent_relationship', relationship['derived_from']) self.assertEquals(1, len(relationship['target_interfaces'])) self.assertEquals(2, len(relationship['target_interfaces'] ['test_interface'])) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['target_interfaces']['test_interface']['install']) self.assertEqual( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['target_interfaces'][ 'test_interface']['terminate']) self.assertEquals(1, len(relationship['source_interfaces'])) self.assertEquals( 2, len(relationship['source_interfaces']['test_interface'])) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['source_interfaces']['test_interface']['install2']) self.assertEqual( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['source_interfaces'][ 'test_interface']['terminate2']) self.assertEquals('relationship', node_relationship['type']) self.assertEquals('test_node', node_relationship['target_id']) self.assertEquals(1, len(node_relationship['target_interfaces'])) self.assertEquals( 3, len(node_relationship['target_interfaces']['test_interface'])) self.assertEqual( operation_mapping(implementation='test_plugin.install', inputs={}, executor=None, max_retries=None, retry_interval=None), node_relationship['target_interfaces'][ 'test_interface']['install']) self.assertEqual( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['target_interfaces'][ 'test_interface']['terminate']) self.assertEqual( operation_mapping(implementation='test_plugin.destroy1', inputs={}, executor=None, max_retries=None, retry_interval=None), node_relationship['target_interfaces'][ 'test_interface']['destroy']) self.assertEquals(1, len(node_relationship['source_interfaces'])) self.assertEquals( 3, len(node_relationship['source_interfaces'][ 'test_interface'])) self.assertEquals( operation_mapping(implementation='test_plugin.install2', inputs={}, executor=None, max_retries=None, retry_interval=None), node_relationship['source_interfaces'][ 'test_interface']['install2']) self.assertEqual( operation_mapping(implementation='test_plugin.terminate', inputs={}, executor=None, max_retries=None, retry_interval=None), relationship['source_interfaces']['test_interface']['terminate2']) self.assertEquals( operation_mapping(implementation='test_plugin.destroy2', inputs={}, executor=None, max_retries=None, retry_interval=None), node_relationship['source_interfaces'][ 'test_interface']['destroy2']) rel_source_ops = node_relationship['source_operations'] self.assertEqual(op_struct('test_plugin', 'install2', executor='central_deployment_agent'), rel_source_ops['install2']) self.assertEqual(op_struct('test_plugin', 'install2', executor='central_deployment_agent'), rel_source_ops['test_interface.install2']) self.assertEqual(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), rel_source_ops['terminate2']) self.assertEqual(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), rel_source_ops['test_interface.terminate2']) self.assertEqual(op_struct('test_plugin', 'destroy2', executor='central_deployment_agent'), rel_source_ops['destroy2']) self.assertEqual(op_struct('test_plugin', 'destroy2', executor='central_deployment_agent'), rel_source_ops['test_interface.destroy2']) self.assertEquals(6, len(rel_source_ops)) rel_target_ops = node_relationship['target_operations'] self.assertEqual(op_struct('test_plugin', 'install', executor='central_deployment_agent'), rel_target_ops['install']) self.assertEqual(op_struct('test_plugin', 'install', executor='central_deployment_agent'), rel_target_ops['test_interface.install']) self.assertEqual(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), rel_target_ops['terminate']) self.assertEqual(op_struct('test_plugin', 'terminate', executor='central_deployment_agent'), rel_target_ops['test_interface.terminate']) self.assertEqual(op_struct('test_plugin', 'destroy1', executor='central_deployment_agent'), rel_target_ops['destroy']) self.assertEqual(op_struct('test_plugin', 'destroy1', executor='central_deployment_agent'), rel_target_ops['test_interface.destroy']) self.assertEquals(6, len(rel_source_ops)) def test_relationship_no_type_hierarchy(self): yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: relationship target: test_node relationships: relationship: {} """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) relationship = nodes[1]['relationships'][0] self.assertTrue('type_hierarchy' in relationship) type_hierarchy = relationship['type_hierarchy'] self.assertEqual(1, len(type_hierarchy)) self.assertEqual('relationship', type_hierarchy[0]) def test_relationship_type_hierarchy(self): yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: rel2 target: test_node relationships: relationship: {} rel2: derived_from: relationship """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) relationship = nodes[1]['relationships'][0] self.assertTrue('type_hierarchy' in relationship) type_hierarchy = relationship['type_hierarchy'] self.assertEqual(2, len(type_hierarchy)) self.assertEqual('relationship', type_hierarchy[0]) self.assertEqual('rel2', type_hierarchy[1]) def test_relationship_3_types_hierarchy(self): yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: rel3 target: test_node relationships: relationship: {} rel2: derived_from: relationship rel3: derived_from: rel2 """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) relationship = nodes[1]['relationships'][0] self.assertTrue('type_hierarchy' in relationship) type_hierarchy = relationship['type_hierarchy'] self.assertEqual(3, len(type_hierarchy)) self.assertEqual('relationship', type_hierarchy[0]) self.assertEqual('rel2', type_hierarchy[1]) self.assertEqual('rel3', type_hierarchy[2]) def test_agent_plugin_in_node_contained_in_host_contained_in_container(self): # noqa yaml = """ plugins: plugin: executor: host_agent source: source node_templates: compute: type: cloudify.nodes.Compute relationships: - target: container type: cloudify.relationships.contained_in container: type: container app: type: app interfaces: interface: operation: plugin.operation relationships: - target: compute type: cloudify.relationships.contained_in node_types: cloudify.nodes.Compute: {} container: {} app: {} relationships: cloudify.relationships.contained_in: {} """ result = self.parse(yaml) self.assertEqual('compute', self.get_node_by_name(result, 'compute')['host_id']) def test_node_host_id_field(self): yaml = """ node_templates: test_node: type: cloudify.nodes.Compute properties: key: "val" node_types: cloudify.nodes.Compute: properties: key: {} """ result = self.parse(yaml) self.assertEquals('test_node', result['nodes'][0]['host_id']) def test_node_host_id_field_via_relationship(self): yaml = """ node_templates: test_node1: type: cloudify.nodes.Compute test_node2: type: another_type relationships: - type: cloudify.relationships.contained_in target: test_node1 test_node3: type: another_type relationships: - type: cloudify.relationships.contained_in target: test_node2 node_types: cloudify.nodes.Compute: {} another_type: {} relationships: cloudify.relationships.contained_in: {} """ result = self.parse(yaml) self.assertEquals('test_node1', result['nodes'][1]['host_id']) self.assertEquals('test_node1', result['nodes'][2]['host_id']) def test_node_host_id_field_via_node_supertype(self): yaml = """ node_templates: test_node1: type: another_type node_types: cloudify.nodes.Compute: {} another_type: derived_from: cloudify.nodes.Compute """ result = self.parse(yaml) self.assertEquals('test_node1', result['nodes'][0]['host_id']) def test_node_host_id_field_via_relationship_derived_from_inheritance( self): yaml = """ node_templates: test_node1: type: cloudify.nodes.Compute test_node2: type: another_type relationships: - type: test_relationship target: test_node1 node_types: cloudify.nodes.Compute: {} another_type: {} relationships: cloudify.relationships.contained_in: {} test_relationship: derived_from: cloudify.relationships.contained_in """ result = self.parse(yaml) self.assertEquals('test_node1', result['nodes'][1]['host_id']) def test_node_type_operation_override(self): yaml = """ node_templates: test_node1: type: cloudify.nodes.MyCompute node_types: cloudify.nodes.Compute: interfaces: test_interface: start: test_plugin.start cloudify.nodes.MyCompute: derived_from: cloudify.nodes.Compute interfaces: test_interface: start: test_plugin.overriding_start plugins: test_plugin: executor: host_agent source: dummy """ result = self.parse(yaml) start_operation = result['nodes'][0]['operations']['start'] self.assertEqual('overriding_start', start_operation['operation']) def test_node_type_node_template_operation_override(self): yaml = """ node_templates: test_node1: type: cloudify.nodes.Compute interfaces: test_interface: start: test_plugin.overriding_start node_types: cloudify.nodes.Compute: interfaces: test_interface: start: test_plugin.start plugins: test_plugin: executor: host_agent source: dummy """ result = self.parse(yaml) start_operation = result['nodes'][0]['operations']['start'] self.assertEqual('overriding_start', start_operation['operation']) def test_executor_override_node_types(self): yaml = """ node_templates: test_node1: type: cloudify.nodes.MyCompute node_types: cloudify.nodes.Compute: interfaces: test_interface: start: executor: central_deployment_agent implementation: test_plugin.start inputs: {} cloudify.nodes.MyCompute: derived_from: cloudify.nodes.Compute interfaces: test_interface: start: executor: host_agent implementation: test_plugin.start inputs: {} plugins: test_plugin: executor: host_agent source: dummy """ result = self.parse(yaml) plugin = result['nodes'][0]['plugins_to_install'][0] self.assertEquals('test_plugin', plugin['name']) self.assertEquals(1, len(result['nodes'][0]['plugins_to_install'])) def test_executor_override_plugin_declaration(self): yaml = """ node_templates: test_node1: type: cloudify.nodes.Compute node_types: cloudify.nodes.Compute: interfaces: test_interface: start: executor: central_deployment_agent implementation: test_plugin.start inputs: {} plugins: test_plugin: executor: host_agent source: dummy """ result = self.parse(yaml) plugin = result['nodes'][0]['deployment_plugins_to_install'][0] self.assertEquals('test_plugin', plugin['name']) self.assertEquals(1, len(result['nodes'][0][ 'deployment_plugins_to_install'])) def test_executor_override_type_declaration(self): yaml = """ node_templates: test_node1: type: cloudify.nodes.Compute interfaces: test_interface: start: executor: host_agent inputs: {} node_types: cloudify.nodes.Compute: interfaces: test_interface: start: executor: central_deployment_agent implementation: test_plugin.start inputs: {} plugins: test_plugin: executor: host_agent source: dummy """ result = self.parse(yaml) plugin = result['nodes'][0]['plugins_to_install'][0] self.assertEquals('test_plugin', plugin['name']) self.assertEquals(1, len(result['nodes'][0][ 'plugins_to_install'])) def test_import_resources(self): resource_file_name = 'resource_file.yaml' file_path = self.make_file_with_name( self.MINIMAL_BLUEPRINT, resource_file_name, 'resources') resources_base_path = os.path.dirname(file_path) yaml = """ imports: - {0}""".format(resource_file_name) result = self.parse(yaml, resources_base_path=resources_base_path) self._assert_minimal_blueprint(result) def test_recursive_imports_with_inner_circular(self): bottom_level_yaml = """ imports: - {0} """.format( os.path.join(self._temp_dir, "mid_level.yaml")) + self.BASIC_TYPE bottom_file_name = self.make_yaml_file(bottom_level_yaml) mid_level_yaml = self.BASIC_PLUGIN + """ imports: - {0}""".format(bottom_file_name) mid_file_name = self.make_file_with_name(mid_level_yaml, 'mid_level.yaml') top_level_yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ imports: - {0}""".format(mid_file_name) result = self.parse(top_level_yaml) self._assert_blueprint(result) def test_recursive_imports_with_complete_circle(self): bottom_level_yaml = """ imports: - {0} """.format( os.path.join(self._temp_dir, "top_level.yaml")) + self.BASIC_TYPE bottom_file_name = self.make_yaml_file(bottom_level_yaml) mid_level_yaml = self.BASIC_PLUGIN + """ imports: - {0}""".format(bottom_file_name) mid_file_name = self.make_yaml_file(mid_level_yaml) top_level_yaml = \ self.BASIC_VERSION_SECTION_DSL_1_0 + \ self.BASIC_NODE_TEMPLATES_SECTION +\ """ imports: - {0}""".format(mid_file_name) top_file_name = self.make_file_with_name( top_level_yaml, 'top_level.yaml') result = parse_from_path(top_file_name) self._assert_blueprint(result) def test_node_without_host_id(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + """ test_node2: type: cloudify.nodes.Compute node_types: cloudify.nodes.Compute: {} test_type: properties: key: {} """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) self.assertFalse('host_id' in nodes[0]) self.assertEquals('test_node2', nodes[1]['host_id']) def test_multiple_instances(self): yaml = self.MINIMAL_BLUEPRINT + """ instances: deploy: 2 """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) self.assertEquals('val', node['properties']['key']) self.assertEquals(2, node['instances']['deploy']) def test_import_types_combination(self): yaml = self.create_yaml_with_imports([self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type2 """]) + """ node_types: test_type2: {} """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) node1 = nodes[0] node2 = nodes[1] self.assertEquals('test_node', node1['id']) self.assertEquals('test_type', node1['type']) self.assertEquals('val', node1['properties']['key']) # self.assertEquals(1, node1['instances']['deploy']) self.assertEquals('test_node2', node2['id']) self.assertEquals('test_type2', node2['type']) # self.assertEquals(1, node2['instances']['deploy']) def test_relationship_operation_mapping_with_properties_injection(self): yaml = self.MINIMAL_BLUEPRINT + """ test_node2: type: test_type relationships: - type: test_relationship target: test_node source_interfaces: test_interface1: install: implementation: test_plugin.install inputs: key: value relationships: test_relationship: {} plugins: test_plugin: executor: central_deployment_agent source: dummy """ result = self.parse(yaml) self.assertEquals(2, len(result['nodes'])) nodes = self._sort_result_nodes(result['nodes'], ['test_node', 'test_node2']) relationship1 = nodes[1]['relationships'][0] rel1_source_ops = relationship1['source_operations'] self.assertEqual( op_struct('test_plugin', 'install', {'key': 'value'}, executor='central_deployment_agent'), rel1_source_ops['install']) self.assertEqual( op_struct('test_plugin', 'install', {'key': 'value'}, executor='central_deployment_agent'), rel1_source_ops['test_interface1.install']) def test_no_workflows(self): result = self.parse(self.MINIMAL_BLUEPRINT) self.assertEquals(result['workflows'], {}) def test_empty_workflows(self): yaml = self.MINIMAL_BLUEPRINT + """ workflows: {} """ result = self.parse(yaml) self.assertEqual(result['workflows'], {}) def test_workflow_basic_mapping(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ workflows: workflow1: test_plugin.workflow1 """ result = self.parse(yaml) workflows = result['workflows'] self.assertEqual(1, len(workflows)) self.assertEqual(workflow_op_struct('test_plugin', 'workflow1',), workflows['workflow1']) workflow_plugins_to_install = result['workflow_plugins_to_install'] self.assertEqual(1, len(workflow_plugins_to_install)) self.assertEqual('test_plugin', workflow_plugins_to_install[0]['name']) def test_workflow_advanced_mapping(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ workflows: workflow1: mapping: test_plugin.workflow1 parameters: prop1: default: value1 mandatory_prop: {} nested_prop: default: nested_key: nested_value nested_list: - val1 - val2 """ result = self.parse(yaml) workflows = result['workflows'] self.assertEqual(1, len(workflows)) parameters = { 'prop1': {'default': 'value1'}, 'mandatory_prop': {}, 'nested_prop': { 'default': { 'nested_key': 'nested_value', 'nested_list': [ 'val1', 'val2' ] } } } self.assertEqual(workflow_op_struct('test_plugin', 'workflow1', parameters), workflows['workflow1']) workflow_plugins_to_install = result['workflow_plugins_to_install'] self.assertEqual(1, len(workflow_plugins_to_install)) self.assertEqual('test_plugin', workflow_plugins_to_install[0]['name']) def test_workflow_imports(self): workflows1 = """ workflows: workflow1: test_plugin.workflow1 """ workflows2 = """ plugins: test_plugin2: executor: central_deployment_agent source: dummy workflows: workflow2: test_plugin2.workflow2 """ yaml = self.create_yaml_with_imports([ self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS, workflows1, workflows2 ]) result = self.parse(yaml) workflows = result['workflows'] self.assertEqual(2, len(workflows)) self.assertEqual(workflow_op_struct('test_plugin', 'workflow1'), workflows['workflow1']) self.assertEqual(workflow_op_struct('test_plugin2', 'workflow2'), workflows['workflow2']) workflow_plugins_to_install = result['workflow_plugins_to_install'] self.assertEqual(2, len(workflow_plugins_to_install)) self.assertEqual('test_plugin', workflow_plugins_to_install[0]['name']) self.assertEqual('test_plugin2', workflow_plugins_to_install[1]['name']) def test_relationship_type_properties_empty_properties(self): yaml = """ node_templates: test_node: type: test_type node_types: test_type: {} relationships: test_relationship: properties: {} """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) relationship = result['relationships']['test_relationship'] self.assertEquals({}, relationship['properties']) def test_relationship_type_properties_empty_property(self): yaml = self.MINIMAL_BLUEPRINT + """ relationships: test_relationship: properties: key: {} """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) relationship = result['relationships']['test_relationship'] self.assertEquals({'key': {}}, relationship['properties']) def test_relationship_type_properties_property_with_description_only(self): yaml = self.MINIMAL_BLUEPRINT + """ relationships: test_relationship: properties: key: description: property_desc """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) relationship = result['relationships']['test_relationship'] self.assertEquals({'key': {'description': 'property_desc'}}, relationship['properties']) def test_relationship_type_properties_standard_property(self): yaml = self.MINIMAL_BLUEPRINT + """ relationships: test_relationship: properties: key: default: val description: property_desc type: string """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) relationship = result['relationships']['test_relationship'] self.assertEquals( {'key': {'default': 'val', 'description': 'property_desc', 'type': 'string'}}, relationship['properties']) def test_workflow_parameters_empty_parameters(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ workflows: test_workflow: mapping: test_plugin.workflow1 parameters: {} """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) workflow = result['workflows']['test_workflow'] self.assertEquals({}, workflow['parameters']) def test_workflow_parameters_empty_parameter(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ workflows: test_workflow: mapping: test_plugin.workflow1 parameters: key: {} """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) workflow = result['workflows']['test_workflow'] self.assertEquals({'key': {}}, workflow['parameters']) def test_workflow_parameters_parameter_with_description_only(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ workflows: test_workflow: mapping: test_plugin.workflow1 parameters: key: description: parameter_desc """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) workflow = result['workflows']['test_workflow'] self.assertEquals({'key': {'description': 'parameter_desc'}}, workflow['parameters']) def test_workflow_parameters_standard_parameter(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ workflows: test_workflow: mapping: test_plugin.workflow1 parameters: key: default: val description: parameter_desc type: string """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) self.assertEquals('test_type', node['type']) workflow = result['workflows']['test_workflow'] self.assertEquals( {'key': {'default': 'val', 'description': 'parameter_desc', 'type': 'string'}}, workflow['parameters']) def test_policy_type_properties_empty_properties(self): policy_types = dict( policy_types=dict( policy_type=dict( source='the_source', properties=dict()))) yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + '\n' + \ yml.safe_dump(policy_types) result = self.parse(yaml) self.assertEqual(result['policy_types'], policy_types['policy_types']) def test_policy_type_properties_empty_property(self): policy_types = dict( policy_types=dict( policy_type=dict( source='the_source', properties=dict( property=dict())))) yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + '\n' + \ yml.safe_dump(policy_types) result = self.parse(yaml) self.assertEqual(result['policy_types'], policy_types['policy_types']) def test_policy_type_properties_property_with_description_only(self): policy_types = dict( policy_types=dict( policy_type=dict( source='the_source', properties=dict( property=dict( description='property description'))))) yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + '\n' + \ yml.safe_dump(policy_types) result = self.parse(yaml) self.assertEqual(result['policy_types'], policy_types['policy_types']) def test_policy_type_properties_property_with_default_only(self): policy_types = dict( policy_types=dict( policy_type=dict( source='the_source', properties=dict( property=dict( default='default_value'))))) yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + '\n' + \ yml.safe_dump(policy_types) result = self.parse(yaml) self.assertEqual(result['policy_types'], policy_types['policy_types']) def test_policy_type_properties_standard_property(self): policy_types = dict( policy_types=dict( policy_type=dict( source='the_source', properties=dict( property=dict( default='default_value', description='property description', type='string'))))) yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + '\n' + \ yml.safe_dump(policy_types) result = self.parse(yaml) self.assertEqual(result['policy_types'], policy_types['policy_types']) def test_policy_type_imports(self): policy_types = [] for i in range(2): policy_types.append(dict( policy_types={ 'policy_type{0}'.format(i): dict( source='the_source', properties=dict( property=dict( default='default_value', description='property description')))})) yaml = self.create_yaml_with_imports([ self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS, yml.safe_dump(policy_types[0]), yml.safe_dump(policy_types[1]), ]) expected_result = dict( policy_types=policy_types[0]['policy_types']) expected_result['policy_types'].update(policy_types[1]['policy_types']) result = self.parse(yaml) self.assertEqual(result['policy_types'], expected_result['policy_types']) def test_policy_trigger_imports(self): policy_triggers = [] for i in range(2): policy_triggers.append(dict( policy_triggers={ 'policy_trigger{0}'.format(i): dict( source='the_source', parameters=dict( property=dict( default='default_value', description='property description', type='string')))})) yaml = self.create_yaml_with_imports([ self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS, yml.safe_dump(policy_triggers[0]), yml.safe_dump(policy_triggers[1]), ]) expected_result = dict( policy_triggers=policy_triggers[0]['policy_triggers']) expected_result['policy_triggers'].update(policy_triggers[1][ 'policy_triggers']) result = self.parse(yaml) self.assertEqual(result['policy_triggers'], expected_result['policy_triggers']) def test_groups_schema_properties_merge(self): yaml = self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS + """ policy_types: policy_type: properties: key1: default: value1 key2: description: key2 description key3: default: value3 source: source groups: group: members: [test_node] policies: policy: type: policy_type properties: key2: group_value2 key3: group_value3 """ result = self.parse(yaml) groups = result['groups'] self.assertEqual(1, len(groups)) group = groups['group'] self.assertEqual(['test_node'], group['members']) self.assertEqual(1, len(group['policies'])) policy = group['policies']['policy'] self.assertEqual('policy_type', policy['type']) self.assertEqual({ 'key1': 'value1', 'key2': 'group_value2', 'key3': 'group_value3' }, policy['properties']) def test_groups_imports(self): groups = [] for i in range(2): groups.append(dict( groups={ 'group{0}'.format(i): dict( members=['test_node'], policies=dict( policy=dict( type='policy_type', properties={}, triggers={})))})) policy_types = """ policy_types: policy_type: properties: {} source: source """ yaml = self.create_yaml_with_imports([ self.BLUEPRINT_WITH_INTERFACES_AND_PLUGINS, policy_types, yml.safe_dump(groups[0]), yml.safe_dump(groups[1])]) expected_result = dict( groups=groups[0]['groups']) expected_result['groups'].update(groups[1]['groups']) result = self.parse(yaml) self.assertEqual(result['groups'], expected_result['groups']) def test_operation_mapping_with_properties_injection(self): yaml = self.BASIC_NODE_TEMPLATES_SECTION + self.BASIC_PLUGIN + """ node_types: test_type: properties: key: {} interfaces: test_interface1: install: implementation: test_plugin.install inputs: key: default: value """ result = self.parse(yaml) node = result['nodes'][0] self.assertEquals('test_type', node['type']) operations = node['operations'] self.assertEquals( op_struct('test_plugin', 'install', {'key': 'value'}, executor='central_deployment_agent'), operations['install']) self.assertEquals( op_struct('test_plugin', 'install', {'key': 'value'}, executor='central_deployment_agent'), operations['test_interface1.install']) def test_merge_plugins_and_interfaces_imports(self): yaml = self.create_yaml_with_imports( [self.BASIC_NODE_TEMPLATES_SECTION, self.BASIC_PLUGIN]) + """ plugins: other_test_plugin: executor: central_deployment_agent source: dummy node_types: test_type: properties: key: {} interfaces: test_interface1: install: implementation: test_plugin.install inputs: {} terminate: implementation: test_plugin.terminate inputs: {} test_interface2: start: implementation: other_test_plugin.start inputs: {} shutdown: implementation: other_test_plugin.shutdown inputs: {} """ result = self.parse(yaml) node = result['nodes'][0] self._assert_blueprint(result) operations = node['operations'] self.assertEquals(op_struct('other_test_plugin', 'start', executor='central_deployment_agent'), operations['start']) self.assertEquals(op_struct('other_test_plugin', 'start', executor='central_deployment_agent'), operations['test_interface2.start']) self.assertEquals(op_struct('other_test_plugin', 'shutdown', executor='central_deployment_agent'), operations['shutdown']) self.assertEquals(op_struct('other_test_plugin', 'shutdown', executor='central_deployment_agent'), operations['test_interface2.shutdown']) def test_node_interfaces_operation_mapping(self): yaml = self.BASIC_PLUGIN + self.BASIC_NODE_TEMPLATES_SECTION + """ interfaces: test_interface1: install: test_plugin.install terminate: test_plugin.terminate node_types: test_type: properties: key: {} """ result = self.parse(yaml) self._assert_blueprint(result) def test_property_schema_type_property_with_intrinsic_functions(self): yaml = """ node_templates: test_node: type: test_type properties: int1: { get_input: x } node_types: test_type: properties: int1: type: integer inputs: x: {} """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) def test_property_schema_type_property(self): yaml = """ node_templates: test_node: type: test_type properties: string1: val string2: true string3: 5 string4: 5.7 boolean1: true boolean2: false boolean3: False boolean4: FALSE boolean5: Yes boolean6: On boolean7: No boolean8: Off integer1: 5 integer2: -5 integer3: 1000000000000 integer4: 0 float1: 5.7 float2: 5.735935 float3: 5.0 float4: 5 float5: -5.7 node_types: test_type: properties: string1: type: string string2: type: string string3: type: string string4: type: string boolean1: type: boolean boolean2: type: boolean boolean3: type: boolean boolean4: type: boolean boolean5: type: boolean boolean6: type: boolean boolean7: type: boolean boolean8: type: boolean integer1: type: integer integer2: type: integer integer3: type: integer integer4: type: integer float1: type: float float2: type: float float3: type: float float4: type: float float5: type: float """ result = self.parse(yaml) self.assertEquals(1, len(result['nodes'])) node = result['nodes'][0] self.assertEquals('test_node', node['id']) def test_version_field(self): yaml = self.MINIMAL_BLUEPRINT + self.BASIC_VERSION_SECTION_DSL_1_0 result = dsl_parse(yaml) self._assert_minimal_blueprint(result) def test_version_field_with_versionless_imports(self): imported_yaml = str() imported_yaml_filename = self.make_yaml_file(imported_yaml) yaml = """ imports: - {0}""".format(imported_yaml_filename) + \ self.BASIC_VERSION_SECTION_DSL_1_0 + \ self.MINIMAL_BLUEPRINT result = dsl_parse(yaml) self._assert_minimal_blueprint(result) def test_version_field_with_imports_with_version(self): imported_yaml = self.BASIC_VERSION_SECTION_DSL_1_0 imported_yaml_filename = self.make_yaml_file(imported_yaml) yaml = """ imports: - {0}""".format(imported_yaml_filename) + \ self.BASIC_VERSION_SECTION_DSL_1_0 + \ self.MINIMAL_BLUEPRINT result = dsl_parse(yaml) self._assert_minimal_blueprint(result) def test_script_mapping(self): yaml = self.BASIC_VERSION_SECTION_DSL_1_0 + """ plugins: script: executor: central_deployment_agent install: false node_types: type: interfaces: test: op: implementation: stub.py inputs: {} op2: implementation: stub.py inputs: key: default: value relationships: relationship: source_interfaces: test: op: implementation: stub.py inputs: {} target_interfaces: test: op: implementation: stub.py inputs: {} workflows: workflow: stub.py workflow2: mapping: stub.py parameters: key: default: value node_templates: node1: type: type relationships: - target: node2 type: relationship node2: type: type """ self.make_file_with_name(content='content', filename='stub.py') yaml_path = self.make_file_with_name(content=yaml, filename='blueprint.yaml') result = self.parse_from_path(yaml_path) node = [n for n in result['nodes'] if n['name'] == 'node1'][0] relationship = node['relationships'][0] operation = node['operations']['test.op'] operation2 = node['operations']['test.op2'] source_operation = relationship['source_operations']['test.op'] target_operation = relationship['target_operations']['test.op'] workflow = result['workflows']['workflow'] workflow2 = result['workflows']['workflow2'] def assert_operation(op, extra_properties=False): inputs = {'script_path': 'stub.py'} if extra_properties: inputs.update({'key': 'value'}) self.assertEqual(op, op_struct( plugin_name=constants.SCRIPT_PLUGIN_NAME, mapping=constants.SCRIPT_PLUGIN_RUN_TASK, inputs=inputs, executor='central_deployment_agent')) assert_operation(operation) assert_operation(operation2, extra_properties=True) assert_operation(source_operation) assert_operation(target_operation) self.assertEqual(workflow['operation'], constants.SCRIPT_PLUGIN_EXECUTE_WORKFLOW_TASK) self.assertEqual(1, len(workflow['parameters'])) self.assertEqual(workflow['parameters']['script_path']['default'], 'stub.py') self.assertEqual(workflow['plugin'], constants.SCRIPT_PLUGIN_NAME) self.assertEqual(workflow2['operation'], constants.SCRIPT_PLUGIN_EXECUTE_WORKFLOW_TASK) self.assertEqual(2, len(workflow2['parameters'])) self.assertEqual(workflow2['parameters']['script_path']['default'], 'stub.py') self.assertEqual(workflow2['parameters']['key']['default'], 'value') self.assertEqual(workflow['plugin'], constants.SCRIPT_PLUGIN_NAME) def test_version(self): def assertion(version_str, expected): version = self.parse(self.MINIMAL_BLUEPRINT, dsl_version=version_str)['version'] version = models.Version(version) self.assertEqual(version.raw, version_str.split(' ')[1].strip()) self.assertEqual(version.definitions_name, 'cloudify_dsl') self.assertEqual(version.definitions_version, expected) assertion(self.BASIC_VERSION_SECTION_DSL_1_0, expected=(1, 0)) assertion(self.BASIC_VERSION_SECTION_DSL_1_1, expected=(1, 1)) assertion(self.BASIC_VERSION_SECTION_DSL_1_2, expected=(1, 2)) def test_version_comparison(self): def parse_version(ver): parsed = version.parse_dsl_version('cloudify_dsl_{0}'.format(ver)) major, minor, micro = parsed if micro is None: micro = 0 return major, minor, micro versions = [ (1, '1_0'), (1, '1_0_0'), (2, '1_0_1'), (3, '1_1'), (3, '1_1_0'), (4, '1_2'), (4, '1_2_0'), (5, '2_0'), ] for ord1, ver1 in versions: parsed_ver1 = parse_version(ver1) for ord2, ver2 in versions: parsed_ver2 = parse_version(ver2) if ord1 == ord2: comp_func = self.assertEqual elif ord1 < ord2: comp_func = self.assertLess else: comp_func = self.assertGreater comp_func(parsed_ver1, parsed_ver2) def test_dsl_definitions(self): yaml = """ dsl_definitions: def1: &def1 prop1: val1 prop2: val2 def2: &def2 prop3: val3 prop4: val4 node_types: type1: properties: prop1: default: default_val1 prop2: default: default_val2 prop3: default: default_val3 prop4: default: default_val4 node_templates: node1: type: type1 properties: <<: *def1 <<: *def2 node2: type: type1 properties: *def1 node3: type: type1 properties: *def2 """ plan = self.parse_1_2(yaml) self.assertNotIn('dsl_definitions', plan) node1 = self.get_node_by_name(plan, 'node1') node2 = self.get_node_by_name(plan, 'node2') node3 = self.get_node_by_name(plan, 'node3') self.assertEqual({ 'prop1': 'val1', 'prop2': 'val2', 'prop3': 'val3', 'prop4': 'val4', }, node1['properties']) self.assertEqual({ 'prop1': 'val1', 'prop2': 'val2', 'prop3': 'default_val3', 'prop4': 'default_val4', }, node2['properties']) self.assertEqual({ 'prop1': 'default_val1', 'prop2': 'default_val2', 'prop3': 'val3', 'prop4': 'val4', }, node3['properties']) def test_dsl_definitions_as_list(self): yaml = """ dsl_definitions: - &def1 prop1: val1 prop2: val2 - &def2 prop3: val3 prop4: val4 node_types: type1: properties: prop1: default: default_val1 prop2: default: default_val2 prop3: default: default_val3 prop4: default: default_val4 node_templates: node1: type: type1 properties: <<: *def1 <<: *def2 """ plan = self.parse_1_2(yaml) self.assertNotIn('dsl_definitions', plan) node1 = self.get_node_by_name(plan, 'node1') self.assertEqual({ 'prop1': 'val1', 'prop2': 'val2', 'prop3': 'val3', 'prop4': 'val4', }, node1['properties']) def test_dsl_definitions_in_imports(self): imported_yaml = self.BASIC_VERSION_SECTION_DSL_1_2 + """ dsl_definitions: - &def1 prop1: default: val1 node_types: type1: properties: *def1 """ imported_yaml_filename = self.make_yaml_file(imported_yaml) yaml = """ dsl_definitions: - &def1 prop1: val2 imports: - {0} node_templates: node1: type: type1 node2: type: type1 properties: *def1 """.format(imported_yaml_filename) plan = self.parse_1_2(yaml) self.assertNotIn('dsl_definitions', plan) node1 = self.get_node_by_name(plan, 'node1') node2 = self.get_node_by_name(plan, 'node2') self.assertEqual({ 'prop1': 'val1', }, node1['properties']) self.assertEqual({ 'prop1': 'val2', }, node2['properties']) def test_null_default(self): yaml = """ plugins: p: install: false executor: central_deployment_agent node_types: type: {} node_templates: node: type: type workflows: workflow: mapping: p.workflow parameters: parameter: default: null """ workflow = self.parse(yaml)['workflows']['workflow'] parameter = workflow['parameters']['parameter'] self.assertIn('default', parameter) def test_required_property(self): yaml = """ node_types: type: properties: none_required_prop: required: false required_prop: required: true node_templates: node: type: type properties: required_prop: value """ properties = self.parse_1_2(yaml)['nodes'][0]['properties'] self.assertEqual(len(properties), 1) self.assertEqual(properties['required_prop'], 'value') def test_null_property_value(self): yaml = """ node_types: type: properties: prop1: default: null prop2: default: some_value prop3: {} prop4: required: false node_templates: node: type: type properties: prop1: null prop2: null prop3: null prop4: null """ properties = self.parse_1_2(yaml)['nodes'][0]['properties'] self.assertEqual(len(properties), 4) for value in properties.values(): self.assertIsNone(value) def test_validate_version_false(self): yaml = """ description: description dsl_definitions: definition: value plugins: plugin: executor: central_deployment_agent install: false install_arguments: --arg node_types: type: interfaces: interface: op: implementation: plugin.task.op max_retries: 1 retry_interval: 1 data_types: type: properties: prop: required: false node_templates: node: type: type """ self.assertRaises(exceptions.DSLParsingException, self.parse, yaml, dsl_version=self.BASIC_VERSION_SECTION_DSL_1_0, validate_version=True) self.parse(yaml, dsl_version=self.BASIC_VERSION_SECTION_DSL_1_0, validate_version=False) def test_validate_version_false_different_versions_in_imports(self): imported1 = self.BASIC_VERSION_SECTION_DSL_1_0 imported2 = self.BASIC_VERSION_SECTION_DSL_1_1 imported3 = self.BASIC_VERSION_SECTION_DSL_1_2 imported4 = self.BASIC_VERSION_SECTION_DSL_1_3 yaml = self.create_yaml_with_imports([imported1, imported2, imported3, imported4]) yaml += """ node_types: type: {} node_templates: node: type: type """ self.assertRaises(exceptions.DSLParsingException, self.parse, yaml, dsl_version=self.BASIC_VERSION_SECTION_DSL_1_0, validate_version=True) self.parse(yaml, dsl_version=self.BASIC_VERSION_SECTION_DSL_1_0, validate_version=False) def test_plugin_fields(self): yaml = """ tosca_definitions_version: cloudify_dsl_1_2 node_types: type: properties: prop1: default: value cloudify.nodes.Compute: properties: prop1: default: value node_templates: node1: type: type interfaces: interface: op: plugin1.op node2: type: cloudify.nodes.Compute interfaces: interface: op: plugin2.op """ base_plugin_def = {'distribution': 'dist', 'distribution_release': 'release', 'distribution_version': 'version', 'install': True, 'install_arguments': '123', 'package_name': 'name', 'package_version': 'version', 'source': 'source', 'supported_platform': 'any'} deployment_plugin_def = base_plugin_def.copy() deployment_plugin_def['executor'] = 'central_deployment_agent' host_plugin_def = base_plugin_def.copy() host_plugin_def['executor'] = 'host_agent' raw_parsed = yml.safe_load(yaml) raw_parsed['plugins'] = { 'plugin1': deployment_plugin_def, 'plugin2': host_plugin_def } parsed = self.parse_1_2(yml.safe_dump(raw_parsed)) expected_plugin1 = deployment_plugin_def.copy() expected_plugin1['name'] = 'plugin1' expected_plugin2 = host_plugin_def.copy() expected_plugin2['name'] = 'plugin2' plugin1 = parsed['deployment_plugins_to_install'][0] node2 = self.get_node_by_name(parsed, 'node2') plugin2 = node2['plugins_to_install'][0] self.assertEqual(expected_plugin1, plugin1) self.assertEqual(expected_plugin2, plugin2)