/******************************************************************************* * (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 com.google.common.collect.Lists; import com.google.common.collect.Sets; import io.cloudslang.lang.compiler.configuration.SlangCompilerSpringConfig; import io.cloudslang.lang.compiler.modeller.model.Decision; import io.cloudslang.lang.compiler.modeller.model.Executable; import io.cloudslang.lang.entities.CompilationArtifact; import io.cloudslang.lang.entities.ScoreLangConstants; import io.cloudslang.lang.entities.bindings.Input; import io.cloudslang.lang.entities.bindings.Output; import io.cloudslang.lang.entities.bindings.Result; import io.cloudslang.lang.entities.bindings.ScriptFunction; import io.cloudslang.lang.entities.bindings.values.ValueFactory; import io.cloudslang.score.api.ExecutionPlan; import io.cloudslang.score.api.ExecutionStep; import java.io.Serializable; import java.net.URL; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import junit.framework.Assert; import org.apache.commons.collections4.MapUtils; 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 com.google.common.collect.Sets.newHashSet; import static io.cloudslang.lang.compiler.SlangSource.fromFile; /** * @author Bonczidai Levente * @since 7/7/2016 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SlangCompilerSpringConfig.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class CompileDecisionTest { private static final HashSet<ScriptFunction> SP_SCRIPT_FUNCTIONS_SET = newHashSet(ScriptFunction.GET_SYSTEM_PROPERTY); @Rule public ExpectedException exception = ExpectedException.none(); @Autowired private SlangCompiler compiler; private Set<SlangSource> emptySetSlangSource = Collections.emptySet(); private Set<String> emptySetSystemProperties = Collections.emptySet(); private List<Output> emptyListOutputs = Collections.emptyList(); private Map<String, Serializable> emptyActionData = Collections.emptyMap(); private List<Input> inputs1 = Lists.newArrayList( new Input.InputBuilder("x", null).build(), new Input.InputBuilder("y", null).build() ); private List<Input> inputs2 = Lists.newArrayList( new Input.InputBuilder("x", null).build(), new Input.InputBuilder("y", null).build(), new Input.InputBuilder("z", "default_value").withRequired(false).build() ); private List<Input> inputs3 = Lists.newArrayList( new Input.InputBuilder("x", "${get_sp('user.sys.prop1')}") .withSystemPropertyDependencies(newHashSet("user.sys.prop1")) .withFunctionDependencies(SP_SCRIPT_FUNCTIONS_SET) .build(), new Input.InputBuilder("y", "${get_sp('user.sys.prop2')}") .withRequired(false) .withSystemPropertyDependencies(newHashSet("user.sys.prop2")) .withFunctionDependencies(SP_SCRIPT_FUNCTIONS_SET) .build() ); private List<Output> outputs1 = Lists.newArrayList( new Output("sum", ValueFactory.create("${x+y}")) ); private List<Output> outputs2 = Lists.newArrayList( new Output( "sum", ValueFactory.create("${get_sp('user.sys.prop3')}"), SP_SCRIPT_FUNCTIONS_SET, newHashSet("user.sys.prop3") ) ); private Set<String> spSet1 = newHashSet( "user.sys.prop1", "user.sys.prop2", "user.sys.prop3", "user.sys.prop4" ); List<Result> results1 = Lists.newArrayList( new Result("EQUAL", ValueFactory.create("${x == y}")), new Result("LESS_THAN", ValueFactory.create("${x < y}")), new Result("GREATER_THAN", null) ); List<Result> results2 = Lists.newArrayList( new Result( "EQUAL", ValueFactory.create("${x == get_sp('user.sys.prop4')}"), SP_SCRIPT_FUNCTIONS_SET, newHashSet("user.sys.prop4") ), new Result("LESS_THAN", ValueFactory.create("${x < y}")), new Result("GREATER_THAN", null) ); @Test public void testDecision1PreCompile() throws Exception { URL decision = getClass().getResource("/decision/decision_1.sl"); Executable executable = compiler.preCompile(fromFile(decision.toURI())); Assert.assertNotNull(executable); Assert.assertTrue(executable instanceof Decision); Decision expectedDecision = new Decision( emptyActionData, emptyActionData, "user.decisions", "decision_1", inputs1, outputs1, results1, Collections.<String>emptySet(), emptySetSystemProperties ); Assert.assertEquals(expectedDecision, executable); } @Test public void testDecision1() throws Exception { URL decision = getClass().getResource("/decision/decision_1.sl"); CompilationArtifact compilationArtifact = compiler.compile(fromFile(decision.toURI()), emptySetSlangSource); validateCompilationArtifact(compilationArtifact, inputs1, outputs1, results1, emptySetSystemProperties); } @Test public void testDecision2() throws Exception { URL decision = getClass().getResource("/decision/decision_2.sl"); CompilationArtifact compilationArtifact = compiler.compile(fromFile(decision.toURI()), emptySetSlangSource); validateCompilationArtifact(compilationArtifact, inputs2, emptyListOutputs, results1, emptySetSystemProperties); } @Test public void testDecisionSystemPropertyDependencies() throws Exception { URL decision = getClass().getResource("/decision/decision_3_sp.sl"); CompilationArtifact compilationArtifact = compiler.compile(fromFile(decision.toURI()), emptySetSlangSource); validateCompilationArtifact(compilationArtifact, inputs3, outputs2, results2, spSet1); } @Test public void testDecisionWrongKey() throws Exception { URL decision = getClass().getResource("/decision/decision_4_unrecognized_key.sl"); exception.expect(RuntimeException.class); exception.expectMessage( "Artifact {decision_4_py_action_key} has unrecognized tag {wrong_key}." + " Please take a look at the supported features per versions link" ); compiler.compile(fromFile(decision.toURI()), emptySetSlangSource); } @Test public void testDecisionPyActionKey() throws Exception { URL decision = getClass().getResource("/decision/decision_4_py_action_key.sl"); exception.expect(RuntimeException.class); exception.expectMessage( "Artifact {decision_4_py_action_key} has unrecognized tag {python_action}." + " Please take a look at the supported features per versions link" ); compiler.compile(fromFile(decision.toURI()), emptySetSlangSource); } @Test public void testDecisionMissingResults() throws Exception { URL decision = getClass().getResource("/decision/decision_wo_results.sl"); exception.expect(RuntimeException.class); exception.expectMessage( "Artifact {decision_wo_results} syntax is invalid:" + " 'results' section cannot be empty for executable type 'decision'" ); compiler.compile(fromFile(decision.toURI()), emptySetSlangSource); } private void validateCompilationArtifact( CompilationArtifact compilationArtifact, List<Input> expectedInputs, List<Output> expectedOutputs, List<Result> expectedResults, Set<String> expectedSystemProperties) { Assert.assertNotNull(compilationArtifact); validateExecutionPlan(compilationArtifact.getExecutionPlan(), expectedInputs, expectedOutputs, expectedResults); Assert.assertTrue(MapUtils.isEmpty(compilationArtifact.getDependencies())); Assert.assertEquals(expectedInputs, compilationArtifact.getInputs()); Assert.assertEquals(expectedSystemProperties, compilationArtifact.getSystemProperties()); } private void validateExecutionPlan( ExecutionPlan executionPlan, Object expectedInputs, Object expectedOutputs, Object expectedResults) { Assert.assertNotNull(executionPlan); Map<Long, ExecutionStep> steps = executionPlan.getSteps(); Assert.assertNotNull(steps); Assert.assertEquals(2, steps.size()); ExecutionStep firstStep = steps.get(1L); Assert.assertNotNull(firstStep); Map<String, ?> actionData1 = firstStep.getActionData(); Assert.assertNotNull(actionData1); //inputs Object actualInputs = actionData1.get(ScoreLangConstants.EXECUTABLE_INPUTS_KEY); Assert.assertEquals(expectedInputs, actualInputs); ExecutionStep secondStep = steps.get(2L); Assert.assertNotNull(secondStep); Map<String, ?> actionData2 = secondStep.getActionData(); Assert.assertNotNull(actionData2); //outputs Object actualOutputs = actionData2.get(ScoreLangConstants.EXECUTABLE_OUTPUTS_KEY); Assert.assertEquals(expectedOutputs, actualOutputs); //results Object actualResults = actionData2.get(ScoreLangConstants.EXECUTABLE_RESULTS_KEY); Assert.assertEquals(expectedResults, actualResults); } }