/*******************************************************************************
* (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.ExecutableModellingResult;
import io.cloudslang.lang.compiler.validator.PreCompileValidatorImpl;
import java.net.URI;
import java.util.List;
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 org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Created by Ifat Gavish on 29/02/2016
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SlangCompilerSpringConfig.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class PreCompilerErrorsTest {
@Autowired
private SlangCompiler compiler;
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void testNotOpFlowFile() throws Exception {
URI resource = getClass().getResource("/corrupted/no_op_flow_file.sl").toURI();
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.preCompileSource(SlangSource.fromFile(resource));
}
@Test
public void testOpWithMissingNamespace() throws Exception {
URI resource = getClass().getResource("/corrupted/op_without_namespace.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For source[op_without_namespace.sl] namespace cannot be empty.");
throw result.getErrors().get(0);
}
@Test
public void testOpWithActionAndWorkflow() throws Exception {
URI resource = getClass().getResource("/corrupted/op_with_action_and_workflow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Conflicting keys[workflow, python_action] at: op_with_action_and_workflow");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithMissingName() throws Exception {
URI resource = getClass().getResource("/corrupted/missing_name_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Executable has no name");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithNullFileName() throws Exception {
URI resource = getClass().getResource("/corrupted/wrong_name_operation.sl").toURI();
ExecutableModellingResult result =
compiler.preCompileSource(new SlangSource(SlangSource.fromFile(resource).getContent(), null));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("should be declared in a file named \"test_op\" " +
"plus a valid extension(sl, sl.yaml, sl.yml, prop.sl, yaml, yml)");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithWrongName() throws Exception {
URI resource = getClass().getResource("/corrupted/wrong_name_operation.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("should be declared in a file named \"test_op.sl\"");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithWrongNameSlYamlExtension() throws Exception {
URI resource = getClass().getResource("/corrupted/wrong_name_operation.sl.yaml").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("should be declared in a file named \"test_op.sl.yaml\"");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithWrongNameSlYmlExtension() throws Exception {
URI resource = getClass().getResource("/corrupted/wrong_name_operation.sl.yml").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("should be declared in a file named \"test_op.sl.yml\"");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithWrongNameYamlExtension() throws Exception {
URI resource = getClass().getResource("/corrupted/wrong_name_operation.yaml").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("should be declared in a file named \"test_op.yaml\"");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithWrongNameYmlExtension() throws Exception {
URI resource = getClass().getResource("/corrupted/wrong_name_operation.yml").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("should be declared in a file named \"test_op.yml\"");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithWrongNameWrongExtension() throws Exception {
URI resource = getClass().getResource("/corrupted/wrong_name_operation.wrong").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("it should be declared in a file named \"test_op\" " +
"plus a valid extension(sl, sl.yaml, sl.yml, prop.sl, yaml, yml)");
throw result.getErrors().get(0);
}
@Test
public void testFlowSameInputAndOutputName() throws Exception {
URI resource = getClass().getResource("/corrupted/same_input_and_output_name.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Inputs and outputs names should be different for " +
"\"io.cloudslang.base.json.same_input_and_output_name\". " +
"Please rename input/output \"json_path\"");
throw result.getErrors().get(0);
}
@Test
public void testFlowSamePrivateInputAndOutputName() throws Exception {
URI resource = getClass().getResource("/corrupted/same_private_input_and_output_name.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertEquals(0, result.getErrors().size());
}
@Test
public void testFlowWithInputsAsString() throws Exception {
URI resource = getClass().getResource("/corrupted/inputs_type_string_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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.");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithInputsAsMap() throws Exception {
URI resource = getClass().getResource("/corrupted/inputs_type_map_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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)");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithIllegalTypeInput() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_with_wrong_type_input.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For flow 'flow_with_wrong_type_input' syntax is illegal.\n" +
"Could not transform Input : 3");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithNoWorkflow() throws Exception {
URI resource = getClass().getResource("/corrupted/no_workflow_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Error compiling no_workflow_flow.sl. Flow: no_workflow has no workflow property");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithNoWorkflowData() throws Exception {
URI resource = getClass().getResource("/corrupted/no_workflow_data_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Error compiling no_workflow_data_flow.sl. Flow: no_workflow_data has " +
"no workflow property");
throw result.getErrors().get(0);
}
@Test
public void testFlowStepWithNoData() throws Exception {
URI resource = getClass().getResource("/corrupted/no_step_data_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Step: step1 has no data");
throw result.getErrors().get(0);
}
@Test
public void testFlowStepWithTwoKeysUnderDo() throws Exception {
URI resource = getClass().getResource("/corrupted/multiple_keys_under_do.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithStepsAsList() throws Exception {
URI resource = getClass().getResource("/corrupted/workflow_with_step_map.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithOnFailureStepsAsList() throws Exception {
URI resource = getClass().getResource("/corrupted/on_failure_with_step_map.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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");
throw result.getErrors().get(0);
}
@Test
public void testOpResultNamedOnFailure() throws Exception {
URI resource = getClass().getResource("/corrupted/on_failure/op_1.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For operation 'op_1' syntax is illegal.");
exception.expectMessage("Result cannot be called 'on_failure'.");
throw result.getErrors().get(0);
}
@Test
public void testFlowResultNamedOnFailure() throws Exception {
URI resource = getClass().getResource("/corrupted/on_failure/flow_1.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For flow 'flow_1' syntax is illegal.");
exception.expectMessage("Result cannot be called 'on_failure'.");
throw result.getErrors().get(0);
}
@Test
public void testDecisionResultNamedOnFailure() throws Exception {
URI resource = getClass().getResource("/corrupted/on_failure/decision_1.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For decision 'decision_1' syntax is illegal.");
exception.expectMessage("Result cannot be called 'on_failure'.");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithNoRefStep() throws Exception {
URI resource = getClass().getResource("/corrupted/step_with_no_ref_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Step: 'step1' has no reference information");
throw result.getErrors().get(0);
}
@Test
public void testStepWithListOfOps() throws Exception {
URI resource = getClass().getResource("/corrupted/step_with_list_of_ops.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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)");
throw result.getErrors().get(0);
}
@Test
public void testStepWithListOfDos() throws Exception {
URI resource = getClass().getResource("/corrupted/step_with_list_of_do_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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:");
throw result.getErrors().get(0);
}
@Test
public void testInputPrivateAndNoDefault() throws Exception {
URI resource = getClass().getResource("/private_input_without_default.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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");
throw result.getErrors().get(0);
}
@Test
public void testWrongTag() throws Exception {
URI resource = getClass().getResource("/corrupted/private_input_without_default_wrong_tag.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Artifact {private_input_without_default} has unrecognized tag {action}. " +
"Please take a look at the supported features per versions link");
throw result.getErrors().get(0);
}
@Test
public void testInputWithInvalidKey() throws Exception {
URI resource = getClass().getResource("/illegal_key_in_input.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithNoActionData() throws Exception {
URI resource = getClass().getResource("/corrupted/operation_with_no_action_data.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Error compiling operation_with_no_action_data.sl. " +
"Operation: operation_with_no_action_data has no action data");
throw result.getErrors().get(0);
}
@Test
public void testOperationWithListOfActionTypes() throws Exception {
URI resource = getClass().getResource("/corrupted/operation_with_list_of_action_types.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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)");
throw result.getErrors().get(0);
}
@Test
public void testParentFlowWithCorruptedSubFlow() throws Exception {
URI subFlow = getClass().getResource("/corrupted/no_step_data_flow.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(subFlow));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Step: step1 has no data");
throw result.getErrors().get(0);
}
@Test
public void testStepWithNavigateAsString() throws Exception {
URI resource = getClass().getResource("/corrupted/step_with_string_navigate_value.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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.");
throw result.getErrors().get(0);
}
@Test
public void testStepWithIllegalTypeOfNavigate() throws Exception {
URI resource = getClass().getResource("/corrupted/step_with_illegal_navigate_type.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For step 'step1' syntax is illegal.\n" +
"Data for property: navigate -> 3 is illegal.\n" +
" Transformer is: NavigateTransformer");
throw result.getErrors().get(0);
}
@Test
public void testDuplicateStepNamesInFlow() throws Exception {
URI resource = getClass().getResource("/corrupted/duplicate_step_name.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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");
throw result.getErrors().get(0);
}
@Test
public void testNullValueInputFlow() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_with_null_value_input.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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.");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithResultExpressions() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_with_result_expressions.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
List<RuntimeException> errors = result.getErrors();
assertEquals(2, errors.size());
validateExceptionMessage(
errors.get(0),
"Flow: 'flow_with_result_expressions' syntax is illegal. Error compiling result: 'SUCCESS'. " +
"Explicit values are not allowed for flow results. Correct format is: '- SUCCESS'.",
"SUCCESS",
PreCompileValidatorImpl.FLOW_RESULTS_WITH_EXPRESSIONS_MESSAGE
);
validateExceptionMessage(
errors.get(1),
"Flow: 'flow_with_result_expressions' syntax is illegal. Error compiling result: 'CUSTOM'. " +
"Explicit values are not allowed for flow results. Correct format is: '- CUSTOM'.",
"CUSTOM",
PreCompileValidatorImpl.FLOW_RESULTS_WITH_EXPRESSIONS_MESSAGE
);
}
private void validateExceptionMessage(
RuntimeException ex,
String flowName,
String resultName,
String expressionMessage) {
String errorMessage = ex.getMessage();
assertTrue(errorMessage.contains(flowName));
assertTrue(errorMessage.contains(resultName));
assertTrue(errorMessage.contains(expressionMessage));
}
@Test
public void testFlowNavigateNull() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_navigate_map.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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 map.\n" +
"By the Yaml spec lists properties are marked with a '- ' (dash followed by a space)");
throw result.getErrors().get(0);
}
@Test
public void testFlowOnFailureSkipped() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_on_failure_skipped.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Error compiling source 'flow_on_failure_skipped.sl'.\n" +
"Flow: 'flow_on_failure_skipped' has steps with keyword on the same indentation as the step name or " +
"there is no space between step name and hyphen.");
throw result.getErrors().get(0);
}
@Test
public void testFlowOnFailureMissingStep() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_on_failure_missing_step.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Flow: 'flow_on_failure_missing_step' syntax is illegal.\n" +
"There is no step below the 'on_failure' property.");
throw result.getErrors().get(0);
}
@Test
public void testFlowNavigateMultipleElementsForRule() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_navigate_multiple_elements_for_rule.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For step 'Step1' syntax is illegal.\n" +
"Each list item in the navigate section should contain exactly one key:value pair.");
throw result.getErrors().get(0);
}
@Test
public void testFlowNavigateIntKey() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_navigate_int_key.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For step 'Step1' syntax is illegal.\n" +
"Each key in the navigate section should be a string.");
throw result.getErrors().get(0);
}
@Test
public void testFlowNavigateIntValue() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_navigate_int_value.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For step 'Step1' syntax is illegal.\n" +
"Each value in the navigate section should be a string.");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithUnreachableSteps() throws Exception {
URI resource = getClass().getResource("/corrupted/unreachable_steps.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Step 'print_message2' is unreachable.");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithUnreachableFlowResult() throws Exception {
URI resource = getClass().getResource("/corrupted/unreachable_flow_results_explicit_nav.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("The following results are not wired: [UNREACHABLE_RESULT].");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithUnreachableFlowResultMissingNavigation() throws Exception {
URI resource = getClass().getResource("/corrupted/unreachable_flow_results_missing_nav.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
List<RuntimeException> errors = result.getErrors();
assertTrue(errors.size() == 2);
assertContains(errors, 0, "Failed to compile step: print_message1. " +
"The step/result name: CUSTOM of navigation: FAILURE -> CUSTOM is missing");
assertContains(errors, 1, "The following results are not wired: [UNREACHABLE_RESULT].");
}
@Test
public void testFlowWithUnreachableOnFailureStep() throws Exception {
URI resource = getClass().getResource("/corrupted/unreachable_on_failure_step.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("on_failure step 'print_on_failure_1' is unreachable.");
throw result.getErrors().get(0);
}
@Test
public void testFlowBothResultAndStepNameAfter() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_name_step_result_after.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
List<RuntimeException> errors = result.getErrors();
assertTrue(errors.size() == 1);
assertContains(
errors,
0,
"Navigation target: 'COLLISION_ITEM' is declared both as step name and flow result."
);
}
@Test
public void testFlowBothResultAndStepNameBefore() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_name_step_result_before.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
List<RuntimeException> errors = result.getErrors();
assertTrue(errors.size() == 1);
assertContains(
errors,
0,
"Navigation target: 'COLLISION_ITEM' is declared both as step name and flow result."
);
}
@Test
public void testFlowBothResultAndStepNameCurrent() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_name_step_result_current.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
List<RuntimeException> errors = result.getErrors();
assertTrue(errors.size() == 1);
assertContains(
errors,
0,
"Navigation target: 'COLLISION_ITEM' is declared both as step name and flow result."
);
}
@Test
public void testFlowBothResultAndStepNameAfterCurrent() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_name_step_result_after_current.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
List<RuntimeException> errors = result.getErrors();
assertTrue(errors.size() == 1);
assertContains(
errors,
0,
"Navigation target: 'COLLISION_ITEM' is declared both as step name and flow result."
);
}
@Test
public void testFlowWithUnreachableStepReachableFromOnFailureStep() throws Exception {
URI resource = getClass().getResource("/corrupted/on_failure_contains_navigate_section.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Flow: 'on_failure_contains_navigate_section' syntax is illegal.\n" +
"The step below 'on_failure' property should not contain a \"navigate\" section.");
throw result.getErrors().get(0);
}
@Test
public void testNavigateToNonExistingStep() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_navigate_to_non_existing_step.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
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");
throw result.getErrors().get(0);
}
@Test
public void testNavigationRuleIncorrectType() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_navigation_rule_incorrect_type.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For step 'Step1' syntax is illegal.");
exception.expectMessage("Navigation rule should be a Map. " +
"Actual type is java.util.ArrayList: [SUCCESS, SUCCESS]");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithInvalidInputs() throws Exception {
URI resource = getClass().getResource("/corrupted/flow_with_invalid_inputs.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For flow 'flow_with_invalid_inputs' syntax is illegal.\n" +
"Invalid syntax after input \"input1\". Please check all inputs are provided as a list " +
"and each input is preceded by a hyphen. Input \"input2\" is missing the hyphen.");
throw result.getErrors().get(0);
}
@Test
public void testFlowWithUnreachableTasksOneReachableFromUnreachableTask() throws Exception {
URI resource = getClass()
.getResource("/corrupted/unreachable_tasks_one_reachable_from_unreachable_task.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Step 'print_message2' is unreachable.");
throw result.getErrors().get(0);
}
@Test
public void testNullPublishValue() throws Exception {
URI resource = getClass().getResource("/corrupted/null_publish_value.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("For step 'CheckWeather' syntax is illegal.");
exception.expectMessage("Could not transform Output : {var_with_null_value=null} since it has a null value.");
throw result.getErrors().get(0);
}
@Test
public void testDefaultNavigationMissingResult() throws Exception {
URI resource = getClass().getResource("/corrupted/default_navigation_missing_result.sl").toURI();
ExecutableModellingResult result = compiler.preCompileSource(SlangSource.fromFile(resource));
assertTrue(result.getErrors().size() > 0);
exception.expect(RuntimeException.class);
exception.expectMessage("Failed to compile step: jedi_training_1. " +
"The step/result name: FAILURE of navigation: FAILURE -> FAILURE is missing");
throw result.getErrors().get(0);
}
private void assertContains(List<RuntimeException> errors, int index, String message) {
@SuppressWarnings("all")
RuntimeException rex1 = errors.get(index);
Assert.assertTrue(rex1.getMessage().contains(message));
}
}