/******************************************************************************* * (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.runtime.bindings; import io.cloudslang.dependency.api.services.DependencyService; import io.cloudslang.dependency.api.services.MavenConfig; import io.cloudslang.dependency.impl.services.DependencyServiceImpl; import io.cloudslang.dependency.impl.services.MavenConfigImpl; import io.cloudslang.lang.entities.SystemProperty; import io.cloudslang.lang.entities.bindings.Output; import io.cloudslang.lang.entities.bindings.values.Value; import io.cloudslang.lang.entities.bindings.values.ValueFactory; import io.cloudslang.lang.runtime.bindings.scripts.ScriptEvaluator; import io.cloudslang.runtime.api.python.PythonRuntimeService; import io.cloudslang.runtime.impl.python.PythonExecutionCachedEngine; import io.cloudslang.runtime.impl.python.PythonExecutionEngine; import io.cloudslang.runtime.impl.python.PythonRuntimeServiceImpl; import io.cloudslang.score.events.EventBus; import io.cloudslang.score.events.EventBusImpl; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.python.google.common.collect.Lists; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import static java.util.Collections.singletonList; /** * Date: 11/7/2014 * * @author Bonczidai Levente */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = OutputsBindingTest.Config.class) public class OutputsBindingTest { private static final long DEFAULT_TIMEOUT = 10000; @SuppressWarnings("unchecked") private static final Set<SystemProperty> EMPTY_SET = Collections.EMPTY_SET; @Autowired private OutputsBinding outputsBinding; @Test(timeout = DEFAULT_TIMEOUT) public void testOperationEmptyOutputs() { Map<String, Value> operationContext = new HashMap<>(); Map<String, Value> actionReturnValues = new HashMap<>(); List<Output> outputs = new LinkedList<>(); Map<String, Value> result = outputsBinding .bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); Assert.assertTrue("result cannot be null", result != null); Assert.assertTrue("result should be empty", result.isEmpty()); } @Test(timeout = DEFAULT_TIMEOUT) public void testOperationOutputsNoExpression() { Map<String, Value> operationContext = prepareOperationContext(); Map<String, Value> actionReturnValues = prepareActionReturnValues(); List<Output> outputs = singletonList(createNoExpressionOutput("host1")); Map<String, Value> result = outputsBinding .bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); Map<String, Value> expectedOutputs = new HashMap<>(); expectedOutputs.put("host1", ValueFactory.create("valueHost1")); Assert.assertEquals("Binding results are not as expected", expectedOutputs, result); } @Test(timeout = DEFAULT_TIMEOUT) public void testOperationOutputsNoExpressionMultipleOutputs() { Map<String, Value> operationContext = prepareOperationContext(); Map<String, Value> actionReturnValues = prepareActionReturnValues(); List<Output> outputs = Arrays.asList(createNoExpressionOutput("host1"), createNoExpressionOutput("host2")); Map<String, Value> result = outputsBinding .bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); Map<String, Value> expectedOutputs = new HashMap<>(); expectedOutputs.put("host1", ValueFactory.create("valueHost1")); expectedOutputs.put("host2", ValueFactory.create("valueHost2")); Assert.assertEquals("Binding results are not as expected", expectedOutputs, result); } @Test public void testOperationOutputsNoExpressionAtAll() { Map<String, Value> operationContext = prepareOperationContext(); Map<String, Value> actionReturnValues = new HashMap<>(); List<Output> outputs = singletonList(createNoExpressionOutput("actionOutputKey1")); Map<String, Value> boundOutputs = outputsBinding .bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); Assert.assertTrue(boundOutputs.containsKey("actionOutputKey1")); Assert.assertEquals(null, boundOutputs.get("actionOutputKey1").get()); } @Test(expected = RuntimeException.class, timeout = DEFAULT_TIMEOUT) public void testOperationOutputsIllegalEvaluatedExpression() { Map<String, Value> operationContext = prepareOperationContext(); Map<String, Value> actionReturnValues = new HashMap<>(); List<Output> outputs = singletonList(createExpressionOutput("actionOutputKey1", "${ None + 'str' }")); outputsBinding.bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); } @Test(timeout = DEFAULT_TIMEOUT) public void testOperationOutputsExpression() { Map<String, Value> operationContext = prepareOperationContext(); Map<String, Value> actionReturnValues = prepareActionReturnValues(); List<Output> outputs = singletonList( createExpressionOutput("hostFromExpression", "${ 'http://' + hostExpr + ':' + str(port) }")); Map<String, Value> result = outputsBinding .bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); Map<String, Value> expectedOutputs = new HashMap<>(); expectedOutputs.put("hostFromExpression", ValueFactory.create("http://hostExpr:9999")); Assert.assertEquals("Binding results are not as expected", expectedOutputs, result); } @Test(timeout = DEFAULT_TIMEOUT) public void testOutputsRetainOrder() { Map<String, Value> operationContext = prepareOperationContext(); Map<String, Value> actionReturnValues = prepareActionReturnValues(); List<Output> outputs = Lists.newArrayList( createExpressionOutput("output1", "1"), createExpressionOutput("output2", "2"), createExpressionOutput("output3", "3") ); Map<String, Value> result = outputsBinding .bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); List<String> actualInputNames = Lists.newArrayList(result.keySet()); List<String> expectedInputNames = Lists.newArrayList("output1", "output2", "output3"); Assert.assertEquals("Binding results are not as expected", expectedInputNames, actualInputNames); } @Test(expected = RuntimeException.class, timeout = DEFAULT_TIMEOUT) public void testOperationOutputsInvalidExpression() { Map<String, Value> operationContext = prepareOperationContext(); Map<String, Value> actionReturnValues = prepareActionReturnValues(); List<Output> outputs = singletonList( createExpressionOutput("hostFromExpression", "${ 'http://' + hostExpr + ':' + str(self[SHOULD_BE_STRING]) }")); outputsBinding.bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); } @Test(timeout = DEFAULT_TIMEOUT) public void testOperationOutputsMixed() { Map<String, Value> operationContext = prepareOperationContext(); Map<String, Value> actionReturnValues = prepareActionReturnValues(); List<Output> outputs = Arrays.asList( createNoExpressionOutput("host1"), createExpressionOutput("hostFromExpression", "${ 'http://' + hostExpr + ':' + str(port) }")); Map<String, Value> result = outputsBinding .bindOutputs(operationContext, actionReturnValues, EMPTY_SET, outputs); Map<String, Value> expectedOutputs = new HashMap<>(); expectedOutputs.put("hostFromExpression", ValueFactory.create("http://hostExpr:9999")); expectedOutputs.put("host1", ValueFactory.create("valueHost1")); Assert.assertEquals("Binding results are not as expected", expectedOutputs, result); } private Map<String, Value> prepareOperationContext() { Map<String, Value> operationContext = new HashMap<>(); operationContext.put("operationContextKey1", ValueFactory.create("opContextValue1")); operationContext.put("host1", ValueFactory.create("host1")); operationContext.put("host", ValueFactory.create("host")); operationContext.put("port", ValueFactory.create(9999)); return operationContext; } private Map<String, Value> prepareActionReturnValues() { Map<String, Value> returnValues = new HashMap<>(); returnValues.put("host1", ValueFactory.create("valueHost1")); returnValues.put("host2", ValueFactory.create("valueHost2")); returnValues.put("hostExpr", ValueFactory.create("hostExpr")); returnValues.put("port", ValueFactory.create(9999)); return returnValues; } private Output createNoExpressionOutput(String key) { return createExpressionOutput(key, "${ " + key + " }"); } private Output createExpressionOutput(String key, String value) { return new Output(key, ValueFactory.create(value)); } @Configuration static class Config { @Bean public OutputsBinding outputsBinding() { return new OutputsBinding(); } @Bean public ScriptEvaluator scriptEvaluator() { return new ScriptEvaluator(); } @Bean public DependencyService mavenRepositoryService() { return new DependencyServiceImpl(); } @Bean public MavenConfig mavenConfig() { return new MavenConfigImpl(); } @Bean public PythonRuntimeService pythonRuntimeService() { return new PythonRuntimeServiceImpl(); } @Bean public PythonExecutionEngine pythonExecutionEngine() { return new PythonExecutionCachedEngine(); } @Bean public EventBus eventBus() { return new EventBusImpl(); } } }