/******************************************************************************* * (c) Copyright 2016 Hewlett-Packard Development Company, L.P. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License v2.0 which accompany this distribution. * * The Apache License is available at * http://www.apache.org/licenses/LICENSE-2.0 * *******************************************************************************/ package io.cloudslang.lang.compiler; import io.cloudslang.lang.compiler.configuration.SlangCompilerSpringConfig; import io.cloudslang.lang.compiler.modeller.result.CompilationModellingResult; import io.cloudslang.lang.compiler.parser.utils.ParserExceptionHandler; import java.net.URI; import java.net.URISyntaxException; import java.util.HashSet; import java.util.Set; import junit.framework.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static junit.framework.Assert.assertEquals; /** * Created by stoneo on 1/22/2015. */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SlangCompilerSpringConfig.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class CompilerErrorsTest { @Autowired private SlangCompiler compiler; @Rule public ExpectedException exception = ExpectedException.none(); @Test public void testEmptyFile() throws Exception { URI resource = getClass().getResource("/corrupted/empty_file.sl").toURI(); Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Source empty_file.sl cannot be empty"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testNavigateOnSameLevelAsSteps() throws Exception { final URI resource = getClass().getResource("/corrupted/flow_navigate_same_level_as_step.sl").toURI(); final URI operation = getClass().getResource("/test_op.sl").toURI(); Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operation)); exception.expect(RuntimeException.class); exception.expectMessage("Error compiling source 'flow_navigate_same_level_as_step.sl'.\n" + "Flow: 'flow_navigate_same_level_as_step' has steps with keyword " + "on the same indentation as the step name " + "or there is no space between step name and hyphen."); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testNavigateToNonExistingStep() throws Exception { final URI resource = getClass().getResource("/corrupted/flow_navigate_to_non_existing_step.sl").toURI(); final URI operation = getClass().getResource("/test_op.sl").toURI(); Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operation)); exception.expect(RuntimeException.class); exception.expectMessage("Failed to compile step: Step1. " + "The step/result name: non_existing_step of navigation: " + "SUCCESS -> non_existing_step is missing"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testNotYamlFile() throws Exception { final URI resource = getClass().getResource("/corrupted/not_yaml_file.sl").toURI(); Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("There was a problem parsing the YAML source: not_yaml_file.sl.\n" + "Source not_yaml_file.sl does not contain YAML content"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testNotOpFlowFile() throws Exception { final URI resource = getClass().getResource("/corrupted/no_op_flow_file.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Error transforming source: no_op_flow_file.sl to a Slang model. " + "Source no_op_flow_file.sl has no content " + "associated with flow/operation/decision/properties property."); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testSystemProperties() throws Exception { final URI systemProperties = getClass().getResource("/corrupted/system_properties.yaml").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("There was a problem parsing the YAML source: system_properties.yaml.\n" + "Cannot create property=user.sys.props.host for JavaBean" + "=io.cloudslang.lang.compiler.parser.model.ParsedSlang"); compiler.compile(SlangSource.fromFile(systemProperties), path); } @Test public void testSystemPropertiesAsDep() throws Exception { final URI flow = getClass().getResource("/basic_flow.yaml").toURI(); final URI operation = getClass().getResource("/test_op.sl").toURI(); final URI systemProperties = getClass().getResource("/corrupted/system_properties.yaml").toURI(); final Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operation)); path.add(SlangSource.fromFile(systemProperties)); exception.expect(RuntimeException.class); exception.expectMessage("There was a problem parsing the YAML source: system_properties.yaml.\n" + "Cannot create property=user.sys.props.host for JavaBean" + "=io.cloudslang.lang.compiler.parser.model.ParsedSlang"); compiler.compile(SlangSource.fromFile(flow), path); } @Test public void testFlowWithNavigationToMissingStep() throws Exception { final URI resource = getClass().getResource("/corrupted/flow_with_navigation_to_missing_step.sl").toURI(); final URI operations = getClass().getResource("/java_op.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operations)); exception.expect(RuntimeException.class); exception.expectMessage("Failed to compile step: Step1. The step/result name: " + "Step2 of navigation: SUCCESS -> Step2 is missing"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testNavigationSectionKeysNotInResultsSection() throws Exception { final URI resource = getClass().getResource("/corrupted/navigation/flow_1.yaml").toURI(); final URI dep1 = getClass().getResource("/corrupted/navigation/op_1.sl").toURI(); Set<SlangSource> dependencies = new HashSet<>(); dependencies.add(SlangSource.fromFile(dep1)); exception.expect(RuntimeException.class); exception.expectMessage( "Cannot compile flow 'flow_1' since for step 'step_1' the navigation keys " + "[KEY_1, KEY_2] have no matching results in its dependency 'io.cloudslang.op_1'." ); compiler.compile(SlangSource.fromFile(resource), dependencies); } @Test public void testNavigationSectionResultsNotWired() throws Exception { final URI resource = getClass().getResource("/corrupted/navigation/flow_2.yaml").toURI(); final URI dep1 = getClass().getResource("/corrupted/navigation/op_2.sl").toURI(); Set<SlangSource> dependencies = new HashSet<>(); dependencies.add(SlangSource.fromFile(dep1)); exception.expect(RuntimeException.class); exception.expectMessage( "Cannot compile flow 'flow_2' since for step 'step_1' the results [CUSTOM_1]" + " of its dependency 'io.cloudslang.op_2' have no matching navigation." ); compiler.compile(SlangSource.fromFile(resource), dependencies); } @Test public void testFlowWithMissingSpaceBeforeFirstImport() throws Exception { //covers "mapping values are not allowed here" error final URI resource = getClass() .getResource("/corrupted/flow_with_missing_space_before_first_import.sl").toURI(); final URI operations = getClass().getResource("/java_op.sl").toURI(); final URI checkWeather = getClass().getResource("/check_Weather.sl").toURI(); final URI flows = getClass().getResource("/flow_with_data.yaml").toURI(); Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operations)); path.add(SlangSource.fromFile(flows)); path.add(SlangSource.fromFile(checkWeather)); exception.expect(RuntimeException.class); exception.expectMessage(ParserExceptionHandler.MAPPING_VALUES_NOT_ALLOWED_HERE_ERROR); exception.expectMessage(ParserExceptionHandler.KEY_VALUE_PAIR_MISSING_OR_INDENTATION_PROBLEM_MSG); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithWrongIndentation() throws Exception { //covers "Unable to find property 'X' on class: io.cloudslang.lang.compiler.parser.model.ParsedSlang" final URI resource = getClass().getResource("/corrupted/flow_with_wrong_indentation.sl").toURI(); final URI operations = getClass().getResource("/java_op.sl").toURI(); final URI flows = getClass().getResource("/flow_with_data.yaml").toURI(); final URI checkWeather = getClass().getResource("/check_Weather.sl").toURI(); Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operations)); path.add(SlangSource.fromFile(flows)); path.add(SlangSource.fromFile(checkWeather)); exception.expect(RuntimeException.class); exception.expectMessage(ParserExceptionHandler.CANNOT_CREATE_PROPERTY_ERROR); exception.expectMessage("Unable to find property"); exception.expectMessage("is not supported by CloudSlang"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWhereMapCannotBeCreated() throws Exception { //covers "No single argument constructor found for interface java.util.Map" final URI resource = getClass().getResource("/corrupted/flow_where_map_cannot_be_created.sl").toURI(); final URI operations = getClass().getResource("/java_op.sl").toURI(); final URI flows = getClass().getResource("/flow_with_data.yaml").toURI(); final URI checkWeather = getClass().getResource("/check_Weather.sl").toURI(); Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operations)); path.add(SlangSource.fromFile(flows)); path.add(SlangSource.fromFile(checkWeather)); exception.expect(RuntimeException.class); exception.expectMessage(ParserExceptionHandler.CANNOT_CREATE_PROPERTY_ERROR); exception.expectMessage(ParserExceptionHandler.KEY_VALUE_PAIR_MISSING_OR_INDENTATION_PROBLEM_MSG); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithCorruptedKeyInImports() throws Exception { //covers problem parsing YAML source "while scanning a simple key" final URI resource = getClass().getResource("/corrupted/flow_with_corrupted_key_in_imports.sl").toURI(); final URI operations = getClass().getResource("/java_op.sl").toURI(); final URI flows = getClass().getResource("/flow_with_data.yaml").toURI(); Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operations)); path.add(SlangSource.fromFile(flows)); exception.expect(RuntimeException.class); exception.expectMessage(ParserExceptionHandler.SCANNING_A_SIMPLE_KEY_ERROR); exception.expectMessage(ParserExceptionHandler.KEY_VALUE_PAIR_MISSING_OR_INDENTATION_PROBLEM_MSG); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithNavigationToMissingDefaultResults() throws Exception { final URI resource = getClass() .getResource("/corrupted/flow_with_navigation_to_missing_default_results.sl").toURI(); final URI operations = getClass().getResource("/java_op.sl").toURI(); Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operations)); exception.expect(RuntimeException.class); exception.expectMessage("Failed to compile step: Step1. " + "The step/result name: SUCCESS of navigation: SUCCESS -> SUCCESS is missing"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithMissingNavigationFromOperationResult() throws Exception { final URI resource = getClass() .getResource("/corrupted/step_with_missing_navigation_from_operation_result_flow.sl").toURI(); final URI operations = getClass().getResource("/java_op.sl").toURI(); Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operations)); exception.expect(RuntimeException.class); exception.expectMessage("Cannot compile flow 'step_with_missing_navigation_from_operation_result_flow' " + "since for step 'step1' the results [FAILURE] of its dependency 'user.ops.java_op' " + "have no matching navigation."); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithMissingImports() throws Exception { final URI resource = getClass().getResource("/corrupted/missing_dependencies_imports_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Source missing_dependencies_imports_flow has " + "dependencies but no path was given to the compiler"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testOpWithMissingNamespace() throws Exception { final URI resource = getClass().getResource("/corrupted/op_without_namespace.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For source[op_without_namespace.sl] namespace cannot be empty."); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithMissingName() throws Exception { final URI resource = getClass().getResource("/corrupted/missing_name_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Executable has no name"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithInputsAsString() throws Exception { final URI resource = getClass().getResource("/corrupted/inputs_type_string_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For flow 'inputs_type_string_flow' syntax is illegal.\n" + "Under property: 'inputs' there should be a list of values, but instead there is a string."); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithInputsAsMap() throws Exception { final URI resource = getClass().getResource("/corrupted/inputs_type_map_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For flow 'inputs_type_string_flow' syntax is illegal.\n" + "Under property: 'inputs' there should be a list of values, but instead there is a map.\n" + "By the Yaml spec lists properties are marked with a '- ' (dash followed by a space)"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithIllegalTypeInput() throws Exception { final URI resource = getClass().getResource("/corrupted/flow_with_wrong_type_input.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For flow 'flow_with_wrong_type_input' syntax is illegal.\n" + "Could not transform Input : 3"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithNoWorkflow() throws Exception { final URI resource = getClass().getResource("/corrupted/no_workflow_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Error compiling no_workflow_flow.sl. Flow: no_workflow has no workflow property"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithNoWorkflowData() throws Exception { final URI resource = getClass().getResource("/corrupted/no_workflow_data_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Error compiling no_workflow_data_flow.sl. " + "Flow: no_workflow_data has no workflow property"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowStepWithNoData() throws Exception { final URI resource = getClass().getResource("/corrupted/no_step_data_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Step: step1 has no data"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowStepWithTwoKeysUnderDo() throws Exception { final URI resource = getClass().getResource("/corrupted/multiple_keys_under_do.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For step 'step1' syntax is illegal.\n" + "Step has too many keys under the 'do' keyword,\n" + "May happen due to wrong indentation"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithStepsAsList() throws Exception { final URI resource = getClass().getResource("/corrupted/workflow_with_step_map.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Flow: 'workflow_with_step_map' syntax is illegal.\n" + "Below 'workflow' property there should be a list of steps and not a map"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithOnFailureStepsAsList() throws Exception { final URI resource = getClass().getResource("/corrupted/on_failure_with_step_map.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Flow: 'on_failure_with_step_map' syntax is illegal.\n" + "Below 'on_failure' property there should be a list of steps and not a map"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithNoRefStep() throws Exception { final URI resource = getClass().getResource("/corrupted/step_with_no_ref_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Step: 'step1' has no reference information"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testStepWithListOfOps() throws Exception { final URI resource = getClass().getResource("/corrupted/step_with_list_of_ops.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For step 'step1' syntax is illegal.\n" + "Under property: 'do' there should be a map of values, but instead there is a list.\n" + "By the Yaml spec maps properties are NOT marked with a '- ' (dash followed by a space)"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testStepWithListOfDos() throws Exception { final URI resource = getClass().getResource("/corrupted/step_with_list_of_do_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Step: step1 syntax is illegal.\n" + "Below step name, there should be a map of values in the format:\n" + "do:\n" + "\top_name:"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testFlowWithMissingRefInPath() throws Exception { final URI resource = getClass().getResource("/basic_flow.yaml").toURI(); final URI op = getClass().getResource("/operation_with_data.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(op)); exception.expect(RuntimeException.class); exception.expectMessage("Reference: 'user.ops.test_op' in executable: 'basic_flow', wasn't found in path"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testInputPrivateAndNoDefault() throws Exception { final URI resource = getClass().getResource("/private_input_without_default.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For operation 'private_input_without_default' syntax is illegal.\n" + "Input: 'input_without_default' is private and required but no default value was specified"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testInputWithInvalidKey() throws Exception { final URI resource = getClass().getResource("/illegal_key_in_input.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For operation 'illegal_key_in_input' syntax is illegal.\n" + "key: karambula in input: input_with_illegal_key is not a known property"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testOperationWithNoActionData() throws Exception { final URI resource = getClass().getResource("/corrupted/operation_with_no_action_data.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Error compiling operation_with_no_action_data.sl. " + "Operation: operation_with_no_action_data has no action data"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testOperationWithListOfActions() throws Exception { final URI resource = getClass().getResource("/corrupted/operation_with_list_of_actions.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("There was a problem parsing the YAML source: operation_with_list_of_actions.sl.\n" + "while parsing a block mapping"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testOperationWithListOfActionTypes() throws Exception { final URI resource = getClass().getResource("/corrupted/operation_with_list_of_action_types.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Action syntax is illegal.\n" + "Under property: 'python_action' there should be a map of values, but instead there is a list.\n" + "By the Yaml spec maps properties are NOT marked with a '- ' (dash followed by a space)"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testParentFlowWithCorruptedSubFlow() throws Exception { final URI resource = getClass().getResource("/corrupted/parent_flow_to_no_step_data_flow.sl").toURI(); final URI subFlow = getClass().getResource("/corrupted/no_step_data_flow.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(subFlow)); exception.expect(RuntimeException.class); exception.expectMessage("Step: step1 has no data"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testStepWithNavigateAsString() throws Exception { final URI resource = getClass().getResource("/corrupted/step_with_string_navigate_value.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For step 'step1' syntax is illegal.\n" + "Under property: 'navigate' there should be a list of values, but instead there is a string."); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testStepWithIllegalTypeOfNavigate() throws Exception { final URI resource = getClass().getResource("/corrupted/step_with_illegal_navigate_type.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For step 'step1' syntax is illegal.\n" + "Data for property: navigate -> 3 is illegal.\n" + " Transformer is: NavigateTransformer"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testDuplicateStepNamesInFlow() throws Exception { final URI resource = getClass().getResource("/corrupted/duplicate_step_name.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("Step name: 'Step1' appears more than once in the workflow. " + "Each step name in the workflow must be unique"); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testNullValueInputFlow() throws Exception { final URI resource = getClass().getResource("/corrupted/flow_with_null_value_input.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); exception.expect(RuntimeException.class); exception.expectMessage("For flow 'flow_with_null_value_input' syntax is illegal.\n" + "Could not transform Input : {input1=null} since it has a null value.\n" + "\n" + "Make sure a value is specified or that indentation is properly done."); compiler.compile(SlangSource.fromFile(resource), path); } @Test public void testValidationOfFlowThatCallsCorruptedFlow() throws Exception { final URI flowUri = getClass().getResource("/corrupted/flow_that_calls_corrupted_flow.sl").toURI(); final URI operation1Uri = getClass().getResource("/test_op.sl").toURI(); final URI operation2Uri = getClass().getResource("/check_op.sl").toURI(); final URI operation3Uri = getClass() .getResource("/corrupted/flow_input_in_step_same_name_as_dependency_output.sl").toURI(); final Set<SlangSource> dependencies = new HashSet<>(); dependencies.add(SlangSource.fromFile(operation1Uri)); dependencies.add(SlangSource.fromFile(operation2Uri)); dependencies.add(SlangSource.fromFile(operation3Uri)); exception.expect(IllegalArgumentException.class); exception.expectMessage("Cannot compile flow " + "'io.cloudslang.flow_input_in_step_same_name_as_dependency_output'. " + "Step 'explicit_alias' has input 'balla' with the same name " + "as the one of the outputs of 'user.ops.test_op'."); compiler.compile(SlangSource.fromFile(flowUri), dependencies); } @Test public void testValidationMatchingNavigation() throws Exception { final URI resource = getClass().getResource("/corrupted/matching-navigation/parent_flow.sl").toURI(); final URI subFlow = getClass().getResource("/corrupted/matching-navigation/child_flow.sl").toURI(); final URI operation1 = getClass().getResource("/corrupted/matching-navigation/test_op.sl").toURI(); final URI operation2 = getClass().getResource("/corrupted/matching-navigation/check_weather.sl").toURI(); final URI operation3 = getClass().getResource("/corrupted/matching-navigation/get_time_zone.sl").toURI(); final URI operation4 = getClass().getResource("/corrupted/matching-navigation/check_number.sl").toURI(); Set<SlangSource> dependencies = new HashSet<>(); dependencies.add(SlangSource.fromFile(subFlow)); dependencies.add(SlangSource.fromFile(operation1)); dependencies.add(SlangSource.fromFile(operation2)); dependencies.add(SlangSource.fromFile(operation3)); dependencies.add(SlangSource.fromFile(operation4)); exception.expect(IllegalArgumentException.class); exception.expectMessage("Cannot compile flow 'child_flow' since for step 'step01' the results [NEGATIVE]" + " of its dependency 'user.ops.get_time_zone' have no matching navigation."); compiler.compile(SlangSource.fromFile(resource), dependencies); } @Test public void testValidationDuplicateFqnIgnoreCase() throws Exception { final URI resource = getClass().getResource("/corrupted/duplicate/duplicate_fqn_1.sl").toURI(); final URI dependency1 = getClass().getResource("/noop.sl").toURI(); final URI dependency2 = getClass().getResource("/corrupted/duplicate/duplicate_fqn_2.sl").toURI(); final URI dependency3 = getClass().getResource("/basic_flow.yaml").toURI(); SlangSource duplicateFqnInitialSource = SlangSource.fromFile(dependency2); Set<SlangSource> dependencies = new HashSet<>(); dependencies.add(SlangSource.fromFile(dependency1)); // change file name from source dependencies.add(new SlangSource(duplicateFqnInitialSource.getContent(), "duplicate_fqn_1.sl")); dependencies.add(SlangSource.fromFile(dependency3)); exception.expect(RuntimeException.class); exception.expectMessage("Duplicate executable found: 'io.CloudSlang.duplicate_fqn_1'"); compiler.compile(SlangSource.fromFile(resource), dependencies); } @Test public void testCompileSource() throws URISyntaxException { final URI flow = getClass().getResource("/compile_errors/loop_with_break_on_non_existing_result.sl").toURI(); final URI operation = getClass().getResource("/compile_errors/print.sl").toURI(); final Set<SlangSource> path = new HashSet<>(); path.add(SlangSource.fromFile(operation)); CompilationModellingResult result = compiler.compileSource(SlangSource.fromFile(flow), path); assertEquals(2, result.getErrors().size()); assertEquals("Argument[print_ values] violates character rules.", result.getErrors().get(0).getMessage()); assertEquals("Cannot compile flow " + "'loops.loop_with_break_on_non_existing_result' " + "since in step 'print_ values' the results [CUSTOM_1, CUSTOM_2] declared in 'break' " + "section are not declared in the dependency 'loops.print' result section.", result.getErrors().get(1).getMessage()); } }