/*******************************************************************************
* (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.model.Metadata;
import io.cloudslang.lang.compiler.modeller.model.StepMetadata;
import io.cloudslang.lang.compiler.modeller.result.MetadataModellingResult;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SlangCompilerSpringConfig.class)
public class MetadataExtractorTest {
private static final String NEWLINE = System.lineSeparator();
private static final String DESCRIPTION_AND_PREREQUISITES = "description: " + NEWLINE +
" Parses the given JSON input to retrieve the" + NEWLINE +
" corresponding value addressed by the json_path input." + NEWLINE +
"prerequisites: jenkinsapi Python module";
private static final String SOME_OTHER_RESULT = "SOME_OTHER_RESULT";
@Autowired
private MetadataExtractor metadataExtractor;
@Test
public void testExtractMetadataDecision() throws Exception {
URI operation = getClass().getResource("/metadata/metadata_decision.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 0);
Assert.assertTrue(metadata.getStepDescriptions().size() == 0);
assertExecutableMetadata03(metadata);
}
@Test
public void testExtractMetadataOperation() throws Exception {
URI operation = getClass().getResource("/metadata/metadata_operation.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 0);
Assert.assertTrue(metadata.getStepDescriptions().size() == 0);
assertExecutableMetadata03(metadata);
}
@Test
public void testMetadataPrettyPrint() throws Exception {
URI operation = getClass().getResource("/metadata/metadata.sl").toURI();
Metadata metadata = metadataExtractor.extractMetadata(SlangSource.fromFile(operation));
String metadataToPrint = metadata.prettyPrint();
Assert.assertNotNull(metadataToPrint);
Assert.assertFalse(metadataToPrint.contains("io.cloudslang.lang.compiler.modeller.model.Metadata"));
Assert.assertTrue(metadataToPrint.contains(DESCRIPTION_AND_PREREQUISITES));
Assert.assertTrue(metadataToPrint.contains(SOME_OTHER_RESULT));
Assert.assertFalse(metadataToPrint.contains(SOME_OTHER_RESULT + ":"));
}
@Test
public void testExtractDescription01() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_01.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 0);
assertExecutableMetadata01(metadata);
// step description
Map<String, String> stepInputs = new HashMap<>();
stepInputs.put("step_input_1", "description step input 1");
stepInputs.put("step_input_2",
"description step input 2 line 1" +
NEWLINE +
"description step input 2 line 2"
);
Map<String, String> stepOutputs = new HashMap<>();
stepOutputs.put("step_output_1", "description step output 1");
stepOutputs.put("step_output_2", "description step output 2");
StepMetadata expectedStepMetadata = new StepMetadata("step_1", stepInputs, stepOutputs);
List<StepMetadata> stepDescriptions = metadata.getStepDescriptions();
Assert.assertTrue(stepDescriptions.size() == 1);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(0));
}
@Test
public void testExtractDescription02() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_05.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 0);
assertExecutableMetadata02(metadata);
List<StepMetadata> stepDescriptions = metadata.getStepDescriptions();
Assert.assertTrue(stepDescriptions.size() == 5);
assertStep01(stepDescriptions);
assertStep03(stepDescriptions);
assertStep04(stepDescriptions);
assertStep05(stepDescriptions);
assertStep06(stepDescriptions);
}
@Test
public void testExtractDescription03() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_06.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 1);
assertErrorMessages(metadata.getErrors(), "Multiple top level descriptions found at line numbers: [9, 53]");
List<StepMetadata> stepDescriptions = metadata.getStepDescriptions();
Assert.assertTrue(stepDescriptions.size() == 0);
assertExecutableMetadata04(metadata);
}
@Test
public void testExtractDescription04() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_07.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 1);
assertErrorMessages(metadata.getErrors(),
"Error at line [7] - Line is not acceptable inside description section");
Assert.assertEquals(new Metadata(), metadata.getMetadata());
List<StepMetadata> stepDescriptions = metadata.getStepDescriptions();
Assert.assertTrue(stepDescriptions.size() == 1);
assertStep07(stepDescriptions);
}
@Test
public void testExtractDescription08() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_08.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 0);
Assert.assertEquals(new Metadata(), metadata.getMetadata());
List<StepMetadata> stepDescriptions = metadata.getStepDescriptions();
Assert.assertTrue(stepDescriptions.size() == 1);
assertStep01(stepDescriptions);
}
@Test
public void testExtractDescription09() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_09.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 1);
assertErrorMessages(metadata.getErrors(),
"Unrecognized tag for step description section: @step_invalid_tag");
Assert.assertEquals(new Metadata(), metadata.getMetadata());
List<StepMetadata> stepDescriptions = metadata.getStepDescriptions();
Assert.assertTrue(stepDescriptions.size() == 5);
assertStep08(stepDescriptions);
assertStep03(stepDescriptions);
assertStep04(stepDescriptions);
assertStep05(stepDescriptions);
assertStep06(stepDescriptions);
}
@Test
public void testExtractDescription10() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_10.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 1);
assertErrorMessages(metadata.getErrors(),
"Unrecognized tag for executable description section: @invalid_flow_tag");
assertExecutableMetadata01(metadata);
// step description
Map<String, String> stepInputs = new HashMap<>();
stepInputs.put("step_input_1", "description step input 1");
stepInputs.put("step_input_2",
"description step input 2 line 1" +
NEWLINE +
"description step input 2 line 2"
);
Map<String, String> stepOutputs = new HashMap<>();
stepOutputs.put("step_output_1", "description step output 1");
stepOutputs.put("step_output_2", "description step output 2");
StepMetadata expectedStepMetadata = new StepMetadata("step_1", stepInputs, stepOutputs);
List<StepMetadata> stepDescriptions = metadata.getStepDescriptions();
Assert.assertTrue(stepDescriptions.size() == 1);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(0));
}
@Test
public void testExtractDescription11() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_12.sl").toURI();
MetadataModellingResult metadata =
metadataExtractor.extractMetadataModellingResult(SlangSource.fromFile(operation));
Assert.assertTrue(metadata.getErrors().size() == 10);
assertErrorMessages(
metadata.getErrors(),
"Unrecognized tag for executable description section: @bo$$First",
"Unrecognized tag for executable description section: @bo$$",
"For executable parameter name for tag[@output] is missing. Format should be [@output name]",
"For executable parameter name for tag[@result] is missing. Format should be [@result name]",
"Unrecognized tag for executable description section: @nasty_tag",
"Unrecognized tag for step description section: @description",
"Unrecognized tag for step description section: @bo$$First",
"Unrecognized tag for step description section: @bo$$",
"For step[step_1] parameter name for tag[@output] is missing. Format should be [@output name]",
"Unrecognized tag for step description section: @nasty_tag"
);
List<StepMetadata> stepDescriptions = metadata.getStepDescriptions();
Assert.assertTrue(stepDescriptions.size() == 1);
assertExecutableMetadata05(metadata);
assertStep09(stepDescriptions);
}
@Test
public void testCheckstyle01() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_02.sl").toURI();
List<RuntimeException> checkstyleViolations =
metadataExtractor.validateCheckstyle(SlangSource.fromFile(operation));
assertErrorMessages(
checkstyleViolations,
"Error at line [1] - Previous line should be delimiter line (120 characters of `#`)",
"Error at line [7] - " +
"There should be an empty line between two sections of different tags (@input and @output)",
"Error at line [30] - " +
"There should be an empty line between two sections of different tags (@input and @output)",
"Error at line [32] - " +
"Next line should be delimiter line (90 characters of `#`)"
);
}
@Test
public void testCheckstyle02() throws Exception {
URI operation = getClass().getResource("/metadata/step/step_description_11.sl").toURI();
List<RuntimeException> checkstyleViolations =
metadataExtractor.validateCheckstyle(SlangSource.fromFile(operation));
assertErrorMessages(
checkstyleViolations,
"Error at line [4] - There should be an empty line between two " +
"sections of different tags (@description and @input)",
"Error at line [9] - There should be an empty line between two " +
"sections of different tags (@output and @result)",
"Error at line [25] - Previous line should be delimiter line (90 characters of `#`)"
);
}
private void assertStep01(List<StepMetadata> stepDescriptions) {
Map<String, String> stepInputs = new HashMap<>();
stepInputs.put("step_input_1", "description step input 1");
stepInputs.put("step_input_2",
"description step input 2 line 1" +
NEWLINE +
"description step input 2 line 2"
);
stepInputs.put("step_input_3", "");
Map<String, String> stepOutputs = new HashMap<>();
stepOutputs.put("step_output_1", "description step output 1");
stepOutputs.put("step_output_2", "description step output 2");
StepMetadata expectedStepMetadata = new StepMetadata("step_1", stepInputs, stepOutputs);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(0));
}
private void assertStep03(List<StepMetadata> stepDescriptions) {
Map<String, String> stepInputs = new HashMap<>();
stepInputs.put("step_input_1",
"description step input 1 line 1" +
NEWLINE +
"description step input 1 line 2" +
NEWLINE +
"description step input 1 line 3" +
NEWLINE +
"description step input 1 line 4" +
NEWLINE +
"`abc`65756756765753545^&&&##@21321"
);
stepInputs.put("step_input_4", "description step input 4 line 1");
Map<String, String> stepOutputs = new HashMap<>();
stepOutputs.put("step_output_1", "description step output 1");
stepOutputs.put("step_output_2",
"description step output 2 line 1" +
NEWLINE +
"description step output 2 line 2"
);
StepMetadata expectedStepMetadata = new StepMetadata("step_3", stepInputs, stepOutputs);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(1));
}
private void assertStep04(List<StepMetadata> stepDescriptions) {
Map<String, String> stepInputs = new HashMap<>();
Map<String, String> stepOutputs = new HashMap<>();
stepOutputs.put("step_output_1", "description step output 1");
stepOutputs.put("step_output_2",
"description step output 2 line 1" +
NEWLINE +
"description step output 2 line 2"
);
StepMetadata expectedStepMetadata = new StepMetadata("step_4", stepInputs, stepOutputs);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(2));
}
private void assertStep05(List<StepMetadata> stepDescriptions) {
Map<String, String> stepInputs = new HashMap<>();
Map<String, String> stepOutputs = new HashMap<>();
StepMetadata expectedStepMetadata = new StepMetadata("step_5", stepInputs, stepOutputs);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(3));
}
private void assertStep06(List<StepMetadata> stepDescriptions) {
Map<String, String> stepInputs = new HashMap<>();
Map<String, String> stepOutputs = new HashMap<>();
StepMetadata expectedStepMetadata = new StepMetadata("step_6", stepInputs, stepOutputs);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(4));
}
private void assertStep07(List<StepMetadata> stepDescriptions) {
Map<String, String> stepInputs = new HashMap<>();
stepInputs.put("step_input_1",
"description step input 1" +
NEWLINE +
"@input step_input_2 description step input 2 line 1" +
NEWLINE +
"description step input 2 line 2"
);
stepInputs.put("step_input_3", "");
Map<String, String> stepOutputs = new HashMap<>();
stepOutputs.put("step_output_1",
"description step output 11" +
NEWLINE +
"description step output 12"
);
stepOutputs.put("step_output_2", "description step output 2");
StepMetadata expectedStepMetadata = new StepMetadata("step_1", stepInputs, stepOutputs);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(0));
}
private void assertStep08(List<StepMetadata> stepDescriptions) {
Map<String, String> stepInputs = new HashMap<>();
stepInputs.put("step_input_1", "description step input 1");
stepInputs.put("step_input_2",
"description step input 2 line 1" +
NEWLINE +
"description step input 2 line 2"
);
stepInputs.put("step_input_3", "");
Map<String, String> stepOutputs = new HashMap<>();
StepMetadata expectedStepMetadata = new StepMetadata("step_1", stepInputs, stepOutputs);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(0));
}
private void assertExecutableMetadata01(MetadataModellingResult metadata) {
Metadata expectedExecutableMetadata = new Metadata();
expectedExecutableMetadata.setDescription("Generated flow description");
expectedExecutableMetadata.setPrerequisites("");
Map<String, String> expectedInputs = new HashMap<>();
expectedInputs.put("input_1",
"Generated description flow input 1 line 1" +
NEWLINE +
"Generated description flow input 1 line 2"
);
expectedInputs.put("input_2", "Generated description flow input 2");
expectedExecutableMetadata.setInputs(expectedInputs);
Map<String, String> outputs = new HashMap<>();
outputs.put("output_1", "Generated description flow output 1");
expectedExecutableMetadata.setOutputs(outputs);
Map<String, String> expectedResults = new HashMap<>();
expectedResults.put("SUCCESS", "Flow completed successfully.");
expectedResults.put("FAILURE", "Failure occurred during execution.");
expectedExecutableMetadata.setResults(expectedResults);
Metadata actualExecutableMetadata = metadata.getMetadata();
Assert.assertEquals(expectedExecutableMetadata, actualExecutableMetadata);
}
private void assertExecutableMetadata02(MetadataModellingResult metadata) {
Metadata expectedExecutableMetadata = new Metadata();
expectedExecutableMetadata.setDescription("Generated flow description");
expectedExecutableMetadata.setPrerequisites("Generated flow prerequisites");
Map<String, String> expectedInputs = new HashMap<>();
expectedInputs.put("input_1",
"Generated description flow input 1 line 1" +
NEWLINE +
"Generated description flow input 1 line 2"
);
expectedInputs.put("input_2", "Generated description flow input 2");
expectedExecutableMetadata.setInputs(expectedInputs);
Map<String, String> outputs = new HashMap<>();
outputs.put("output_1", "Generated description flow output 1");
expectedExecutableMetadata.setOutputs(outputs);
Map<String, String> expectedResults = new HashMap<>();
expectedResults.put("SUCCESS", "Flow completed successfully.");
expectedResults.put("FAILURE", "Failure occurred during execution.");
expectedExecutableMetadata.setResults(expectedResults);
Metadata actualExecutableMetadata = metadata.getMetadata();
Assert.assertEquals(expectedExecutableMetadata, actualExecutableMetadata);
}
private void assertExecutableMetadata03(MetadataModellingResult metadata) {
Metadata expectedExecutableMetadata = new Metadata();
expectedExecutableMetadata.setDescription(
"Parses the given JSON input to retrieve the" +
NEWLINE +
"corresponding value addressed by the json_path input."
);
expectedExecutableMetadata.setPrerequisites("jenkinsapi Python module");
Map<String, String> expectedInputs = new HashMap<>();
expectedInputs.put("json_input",
"JSON data input" +
NEWLINE +
"Example: '{\"k1\": {\"k2\": [\"v1\", \"v2\"]}}'"
);
expectedInputs.put("json_path",
"path from which to retrieve value represented as a list of keys and/or indices." +
NEWLINE +
"Passing an empty list ([]) will retrieve the " +
"entire json_input. - Example: [\"k1\", \"k2\", 1]" +
NEWLINE +
"More information after newline" +
NEWLINE +
"whatever description that will be ignored."
);
expectedExecutableMetadata.setInputs(expectedInputs);
Map<String, String> outputs = new HashMap<>();
outputs.put("value", "the corresponding value of the key referred to by json_path");
outputs.put("return_result", "parsing was successful or not");
outputs.put("return_code", "'0' if parsing was successful, '-1' otherwise");
outputs.put("error_message",
"error message if there was an error when executing," +
NEWLINE +
"empty otherwise"
);
expectedExecutableMetadata.setOutputs(outputs);
Map<String, String> expectedResults = new HashMap<>();
expectedResults.put("SUCCESS", "parsing was successful (return_code == '0')");
expectedResults.put("FAILURE", "otherwise");
expectedResults.put("SOME_OTHER_RESULT", "");
expectedExecutableMetadata.setResults(expectedResults);
Metadata actualExecutableMetadata = metadata.getMetadata();
Assert.assertEquals(expectedExecutableMetadata, actualExecutableMetadata);
}
private void assertExecutableMetadata04(MetadataModellingResult metadata) {
Metadata expectedExecutableMetadata = new Metadata();
expectedExecutableMetadata.setDescription("Generated flow description");
expectedExecutableMetadata.setPrerequisites("Generated flow prerequisites");
Map<String, String> expectedInputs = new HashMap<>();
expectedInputs.put("input_1", "Example: '{\"k1\": {\"k2\": [\"v1\", \"v2\"]}}'");
expectedInputs.put("input_2", "Generated description flow input 2");
expectedExecutableMetadata.setInputs(expectedInputs);
Map<String, String> outputs = new HashMap<>();
outputs.put("output_1", "Generated description flow output 1");
outputs.put("return_code", "'0' if parsing was successful, '-1' otherwise");
expectedExecutableMetadata.setOutputs(outputs);
Map<String, String> expectedResults = new HashMap<>();
expectedExecutableMetadata.setResults(expectedResults);
Metadata actualExecutableMetadata = metadata.getMetadata();
Assert.assertEquals(expectedExecutableMetadata, actualExecutableMetadata);
}
private void assertExecutableMetadata05(MetadataModellingResult metadata) {
Metadata expectedExecutableMetadata = new Metadata();
expectedExecutableMetadata.setDescription("Generated flow description");
expectedExecutableMetadata.setPrerequisites("");
Map<String, String> expectedInputs = new HashMap<>();
expectedInputs.put("input_1",
"Generated description flow input 1 line 1" +
NEWLINE +
"Generated description flow input 1 line 2"
);
expectedInputs.put("input_2#", "4$3#####*909009885^: Generated description flow input 2");
expectedExecutableMetadata.setInputs(expectedInputs);
Map<String, String> outputs = new HashMap<>();
outputs.put("output_1",
"Generated description flow output 1" +
NEWLINE +
"@ output output_2: Generated description flow output 2"
);
outputs.put("bo$$Second", "Generated description @bo$$ line 1");
outputs.put("bo$$",
"Generated description @bo$$ line 1" +
NEWLINE +
"X @bo$$: Generated description @bo$$ line 1"
);
expectedExecutableMetadata.setOutputs(outputs);
Map<String, String> expectedResults = new HashMap<>();
expectedResults.put("SUCCESS", "Flow completed successfully.");
expectedResults.put("FAILURE", "Failure occurred during execution." + NEWLINE + "@");
expectedExecutableMetadata.setResults(expectedResults);
Metadata actualExecutableMetadata = metadata.getMetadata();
Assert.assertEquals(expectedExecutableMetadata, actualExecutableMetadata);
}
private void assertStep09(List<StepMetadata> stepDescriptions) {
Map<String, String> stepInputs = new HashMap<>();
stepInputs.put("input_1",
"Generated description flow input 1 line 1" +
NEWLINE +
"Generated description flow input 1 line 2"
);
stepInputs.put("input_2#", "4$3#####*909009885^: Generated description flow input 2");
Map<String, String> stepOutputs = new HashMap<>();
stepOutputs.put("output_1",
"Generated description flow output 1" +
NEWLINE +
"@ output output_2: Generated description flow output 2"
);
stepOutputs.put("bo$$Second", "Generated description @bo$$ line 1");
stepOutputs.put("bo$$",
"Generated description @bo$$ line 1" +
NEWLINE +
"X @bo$$: Generated description @bo$$ line 1"
);
stepOutputs.put("output_SUCCESS", "Flow completed successfully.");
stepOutputs.put("output_FAILURE", "Failure occurred during execution." + NEWLINE + "@");
StepMetadata expectedStepMetadata = new StepMetadata("step_1", stepInputs, stepOutputs);
Assert.assertEquals(expectedStepMetadata, stepDescriptions.get(0));
}
private void assertErrorMessages(List<RuntimeException> actualErrors, String... expectedErrorMessages) {
Assert.assertEquals(expectedErrorMessages.length, actualErrors.size());
int current = 0;
for (RuntimeException ex : actualErrors) {
Assert.assertEquals(expectedErrorMessages[current++], ex.getMessage());
}
}
}