/******************************************************************************* * (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()); } } }