/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.parametricstudy.execution; import static org.easymock.EasyMock.anyObject; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import de.rcenvironment.components.parametricstudy.common.ParametricStudyComponentConstants; import de.rcenvironment.components.parametricstudy.common.ParametricStudyService; import de.rcenvironment.components.parametricstudy.common.StudyDataset; import de.rcenvironment.components.parametricstudy.common.StudyPublisher; import de.rcenvironment.components.parametricstudy.common.StudyStructure; import de.rcenvironment.core.component.api.ComponentException; import de.rcenvironment.core.component.api.LoopComponentConstants; import de.rcenvironment.core.component.execution.api.Component; import de.rcenvironment.core.component.execution.api.Component.FinalComponentState; import de.rcenvironment.core.component.testutils.ComponentContextMock; import de.rcenvironment.core.component.testutils.ComponentTestWrapper; import de.rcenvironment.core.datamodel.api.DataType; import de.rcenvironment.core.datamodel.api.EndpointCharacter; import de.rcenvironment.core.datamodel.api.TypedDatum; import de.rcenvironment.core.datamodel.api.TypedDatumFactory; import de.rcenvironment.core.datamodel.api.TypedDatumService; import de.rcenvironment.core.datamodel.types.api.BooleanTD; import de.rcenvironment.core.datamodel.types.api.FloatTD; import de.rcenvironment.core.datamodel.types.api.IntegerTD; import de.rcenvironment.core.toolkitbridge.transitional.ConcurrencyUtils; /** * Integration test for {@link ParametricStudyComponent}. * * @author Oliver Seebach * @author Doreen Seider * @author Jascha Riedel */ public class ParametricStudyComponentTest { private static final int FIVE_HUNDRED_INT = 500; private static final int HUNDRED_THOUSAND_INT = 100000; private static final String ONE_ONE = "1.1"; private static final String DONE = "Done"; private static final Double SOME_DOUBLE = 5.0; private static final int LARGE_NUMBER = 100000; private static final String FIT_STEP_SIZE_TO_BOUNDS = "fitStepSizeToBounds"; private static final String FIVE = "5"; private static final String TEN = "10"; private static final String ONE = "1"; private static final String TWO = "2"; private static final String MINUS = "-"; private static final String RETURN_VALUE = "ReturnValue"; private static final String RETURN_VALUE_2 = "AnotherReturnValue"; private static final String STEP_SIZE = "StepSize"; private static final String TO_VALUE = "ToValue"; private static final String FROM_VALUE = "FromValue"; private static final String DESIGN_VARIABLE = "Design variable"; private static final String N = "n"; /** Exception rule. */ @Rule public ExpectedException exception = ExpectedException.none(); /** * Context mockup for parametric study component tests. * * @author Oliver Seebach */ private final class ParametricStudyComponentContextMock extends ComponentContextMock { private static final long serialVersionUID = -6574116384120957764L; } private ComponentTestWrapper component; private ParametricStudyComponentContextMock context; private ParametricStudyService parametricStudyServiceMock; private TypedDatumFactory typedDatumFactory; /** * Set up Parametric Study tests. * * @throws Exception e */ @Before public void setUp() throws Exception { context = new ParametricStudyComponentContextMock(); component = new ComponentTestWrapper(new ParametricStudyComponent(), context); typedDatumFactory = context.getService(TypedDatumService.class).getFactory(); // Create StudyPublisher mock required by ParametricStudyService mock StudyPublisher studyPublisherMock = EasyMock.createMock(StudyPublisher.class); EasyMock.expect(studyPublisherMock.getStudy()).andReturn(null); studyPublisherMock.add(anyObject(StudyDataset.class)); EasyMock.expectLastCall().anyTimes(); studyPublisherMock.clearStudy(); EasyMock.replay(studyPublisherMock); // Create ParametricStudyService mock parametricStudyServiceMock = EasyMock.createNiceMock(ParametricStudyService.class); EasyMock.expect(parametricStudyServiceMock.createPublisher(anyObject(String.class), anyObject(String.class), anyObject(StudyStructure.class))).andReturn(studyPublisherMock).anyTimes(); EasyMock.replay(parametricStudyServiceMock); context.addService(ParametricStudyService.class, parametricStudyServiceMock); } /** * Generates meta data for parametric study test. * * @param from Start value of parametric study range * @param to End value of parametric study range * @param stepSize Step size of parametric study range * @return */ private Map<String, String> generateParametricStudyMetadata(String from, Boolean useInputAsFrom, String to, Boolean useInputAsTo, String stepSize, Boolean useInputAsStepSize, Boolean fitStepSizeToBounds) { Map<String, String> metadata = new HashMap<>(); metadata.put(FROM_VALUE, from); metadata.put(ParametricStudyComponentConstants.OUTPUT_METADATA_USE_INPUT_AS_FROM_VALUE, useInputAsFrom.toString()); metadata.put(TO_VALUE, to); metadata.put(ParametricStudyComponentConstants.OUTPUT_METADATA_USE_INPUT_AS_TO_VALUE, useInputAsTo.toString()); metadata.put(STEP_SIZE, stepSize); metadata.put(ParametricStudyComponentConstants.OUTPUT_METADATA_USE_INPUT_AS_STEPSIZE_VALUE, useInputAsStepSize.toString()); metadata.put(FIT_STEP_SIZE_TO_BOUNDS, fitStepSizeToBounds.toString()); return metadata; } /** * Test with no input and output from 1-10. * * @throws ComponentException ce */ @Test public void testNoInputsSimple() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, TEN, false, ONE, false, false); addSimulatedOutputs(metadata); component.start(); assertEquals(10, context.getCapturedOutput(DESIGN_VARIABLE).size()); final Double[] expectedValues = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 }; assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), expectedValues)); checkDoneOutputs(true); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with no input and output from 1-10. * * @throws ComponentException ce */ @Test public void testNoInputsSimpleDescending() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(TEN, false, ONE, false, ONE, false, false); addSimulatedOutputs(metadata); component.start(); assertEquals(10, context.getCapturedOutput(DESIGN_VARIABLE).size()); final Double[] expectedValues = { 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), expectedValues)); checkDoneOutputs(true); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with one input and output from 1-5. * * @throws ComponentException ce */ @Test public void test1InputSimple() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, FIVE, false, ONE, false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(RETURN_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); component.start(); checkDoneOutputs(false); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(context.getCapturedOutput(DESIGN_VARIABLE).get(0), typedDatumFactory.createFloat(1.0)); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); checkDoneOutputs(false); assertEquals(context.getCapturedOutput(DESIGN_VARIABLE).get(0), typedDatumFactory.createFloat(2.0)); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); checkDoneOutputs(false); assertEquals(context.getCapturedOutput(DESIGN_VARIABLE).get(0), typedDatumFactory.createFloat(3.0)); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); checkDoneOutputs(false); assertEquals(context.getCapturedOutput(DESIGN_VARIABLE).get(0), typedDatumFactory.createFloat(4.0)); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); checkDoneOutputs(false); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(context.getCapturedOutput(DESIGN_VARIABLE).get(0), typedDatumFactory.createFloat(5.0)); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); checkDoneOutputs(true); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with one input and output from 1-5. * * @throws ComponentException ce */ @Test public void test1InputSimpleDescending() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(FIVE, false, ONE, false, ONE, false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(RETURN_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); component.start(); checkDoneOutputs(false); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(typedDatumFactory.createFloat(5.0), context.getCapturedOutput(DESIGN_VARIABLE).get(0)); for (double i = 4; i > 0; i--) { context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); checkDoneOutputs(false); assertEquals(typedDatumFactory.createFloat(i), context.getCapturedOutput(DESIGN_VARIABLE).get(0)); } context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); checkDoneOutputs(true); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with one input and output from 1-5. * * @throws ComponentException ce */ @Test public void test2InputsSimple() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, FIVE, false, ONE, false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(RETURN_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); context.addSimulatedInput(RETURN_VALUE_2, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); component.start(); checkDoneOutputs(false); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(context.getCapturedOutput(DESIGN_VARIABLE).get(0), typedDatumFactory.createFloat(1.0)); for (double i = 2; i <= 5; i++) { context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); context.setInputValue(RETURN_VALUE_2, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); checkDoneOutputs(false); assertEquals(context.getCapturedOutput(DESIGN_VARIABLE).get(0), typedDatumFactory.createFloat(i)); } context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(SOME_DOUBLE)); context.setInputValue(RETURN_VALUE_2, typedDatumFactory.createFloat(SOME_DOUBLE)); component.processInputs(); checkDoneOutputs(true); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with no input and output from 1-10. * * @throws ComponentException ce */ @Test public void testNoInputsManyIterations() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, String.valueOf(LARGE_NUMBER), false, ONE, false, false); addSimulatedOutputs(metadata); component.start(); assertEquals(LARGE_NUMBER, context.getCapturedOutput(DESIGN_VARIABLE).size()); checkDoneOutputs(true); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with one input and output from 1-5. * * @throws ComponentException ce */ @Test public void test1InputManyIterations() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, String.valueOf(LARGE_NUMBER), false, ONE, false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(RETURN_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); component.start(); checkDoneOutputs(false); for (int i = 2; i <= LARGE_NUMBER; i++) { context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); checkDoneOutputs(false); assertEquals(typedDatumFactory.createFloat(i), context.getCapturedOutput(DESIGN_VARIABLE).get(0)); } context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); checkDoneOutputs(true); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with no input and output from 1-10. * * @throws ComponentException ce */ @Test public void testInvalidStepSize() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(TEN, false, ONE, false, "-1.1", false, true); context.addSimulatedOutput(DESIGN_VARIABLE, "", DataType.Float, false, metadata); exception.expect(ComponentException.class); component.start(); component.tearDownAndDispose(Component.FinalComponentState.FAILED); } /** * Test with one input and output from 1-5. * * @throws ComponentException ce */ @Test public void test1InputLargeNumberNonIntegerStepWidth() throws ComponentException { final double stepWidth = 0.123; Map<String, String> metadata = generateParametricStudyMetadata("0", false, String.valueOf(LARGE_NUMBER), false, String.valueOf(stepWidth), false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(RETURN_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); component.start(); for (double i = stepWidth; i <= LARGE_NUMBER; i += stepWidth) { context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); checkDoneOutputs(false); final double delta = 0.1; assertEquals(i, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), delta); } context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); checkDoneOutputs(true, true, 0); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test without input and fit to step width. * * @throws ComponentException ce */ @Test public void testNoInputsFitToStepWidth() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, TEN, false, ONE_ONE, false, true); addSimulatedOutputs(metadata); component.start(); // Component takes step size one size bigger to match the given end value // I.e. in this case 1.125 instead of 1.1 assertEquals(9, context.getCapturedOutput(DESIGN_VARIABLE).size()); final Double[] expectedValues = { 1.0, 2.125, 3.25, 4.375, 5.5, 6.625, 7.75, 8.875, 10.0 }; assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), expectedValues)); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with 1 input and fit to step width. * * @throws ComponentException ce */ @Test public void test1InputFitToStepWidth() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, TEN, false, ONE_ONE, false, true); addSimulatedOutputs(metadata); context.addSimulatedInput(RETURN_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); component.start(); // Component takes step size one size bigger to match the given end value // I.e. in this case 1.125 instead of 1.1 assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(context.getCapturedOutput(DESIGN_VARIABLE).get(0), typedDatumFactory.createFloat(1.0)); final double stepWidth = 1.125; for (double i = (1 + stepWidth); i < 10; i += stepWidth) { context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), i)); } component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Test with no inputs, fit to step width and descending values. * * @throws ComponentException ce */ @Test public void testNoInputsFitToStepWidthDescending() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(TEN, false, ONE, false, ONE_ONE, false, true); addSimulatedOutputs(metadata); component.start(); // Component takes step size one size bigger to match the given end value // I.e. in this case -1.125 instead of -1.1 assertEquals(9, context.getCapturedOutput(DESIGN_VARIABLE).size()); final Double[] expectedValues = { 10.0, 8.875, 7.75, 6.625, 5.5, 4.375, 3.25, 2.125, 1.0 }; assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), expectedValues)); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Tests if values are forwarded as expected. * * @throws ComponentException on unexpected errors */ @Test public void testForwardingValue() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, TWO, false, ONE, false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(N, LoopComponentConstants.ENDPOINT_ID_TO_FORWARD, DataType.Integer, true, null); context.addSimulatedInput(N + LoopComponentConstants.ENDPOINT_STARTVALUE_SUFFIX, LoopComponentConstants.ENDPOINT_ID_START_TO_FORWARD, DataType.Integer, true, null, EndpointCharacter.OUTER_LOOP); context.addSimulatedOutput(N, LoopComponentConstants.ENDPOINT_ID_TO_FORWARD, DataType.Integer, true, null); component.start(); assertEquals(0, context.getCapturedOutput(N).size()); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); context.setInputValue(N + LoopComponentConstants.ENDPOINT_STARTVALUE_SUFFIX, typedDatumFactory.createInteger(3)); component.processInputs(); assertEquals(1, context.getCapturedOutput(N).size()); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(1.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); assertEquals(3, ((IntegerTD) context.getCapturedOutput(N).get(0)).getIntValue()); context.setInputValue(N, typedDatumFactory.createInteger(7)); component.processInputs(); assertEquals(1, context.getCapturedOutput(N).size()); assertEquals(7, ((IntegerTD) context.getCapturedOutput(N).get(0)).getIntValue()); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(2.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); context.setInputValue(N, typedDatumFactory.createInteger(7)); component.processInputs(); assertEquals(0, context.getCapturedOutput(N).size()); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); checkDoneOutputs(true, true, 1); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Tests if values are forwarded as expected. * * @throws ComponentException on unexpected errors */ @Test public void testForwardingStartValue() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, TWO, false, ONE, false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(N, LoopComponentConstants.ENDPOINT_ID_TO_FORWARD, DataType.Integer, true, null); context.addSimulatedInput(N + LoopComponentConstants.ENDPOINT_STARTVALUE_SUFFIX, LoopComponentConstants.ENDPOINT_ID_START_TO_FORWARD, DataType.Integer, true, null, EndpointCharacter.OUTER_LOOP); context.addSimulatedOutput(N, LoopComponentConstants.ENDPOINT_ID_TO_FORWARD, DataType.Integer, true, null); component.start(); assertEquals(0, context.getCapturedOutput(N).size()); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); context.setInputValue(N + LoopComponentConstants.ENDPOINT_STARTVALUE_SUFFIX, typedDatumFactory.createInteger(5)); component.processInputs(); assertEquals(1, context.getCapturedOutput(N).size()); assertEquals(5, ((IntegerTD) context.getCapturedOutput(N).get(0)).getIntValue(), 0); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(1.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); context.setInputValue(N, typedDatumFactory.createInteger(7)); component.processInputs(); assertEquals(1, context.getCapturedOutput(N).size()); assertEquals(7, ((IntegerTD) context.getCapturedOutput(N).get(0)).getIntValue()); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(2.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); context.setInputValue(N, typedDatumFactory.createInteger(7)); component.processInputs(); assertEquals(0, context.getCapturedOutput(N).size()); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); checkDoneOutputs(true, true, 1); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } /** * Tests if values are forwarded as expected. * * @throws ComponentException on unexpected errors */ @Test public void testReset() throws ComponentException { context.setConfigurationValue(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP, String.valueOf(true)); Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, TWO, false, ONE, false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(N, LoopComponentConstants.ENDPOINT_ID_TO_FORWARD, DataType.Integer, true, null); context.addSimulatedInput(N + LoopComponentConstants.ENDPOINT_STARTVALUE_SUFFIX, LoopComponentConstants.ENDPOINT_ID_START_TO_FORWARD, DataType.Integer, true, null, EndpointCharacter.OUTER_LOOP); context.addSimulatedOutput(N, LoopComponentConstants.ENDPOINT_ID_TO_FORWARD, DataType.Integer, true, null); component.start(); testOneLoopRun(); testOneLoopRun(); } /** * Tests if values are forwarded as expected. * * @throws ComponentException on unexpected errors */ @Test public void testDataTypes() throws ComponentException { context.setConfigurationValue(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP, String.valueOf(true)); Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, TWO, false, ONE, false, false); addSimulatedOutputs(metadata); context.addSimulatedInput(RETURN_VALUE, "", DataType.Float, true, new HashMap<String, String>()); context.addSimulatedInput(RETURN_VALUE_2, "", DataType.Integer, true, new HashMap<String, String>()); final double value = 5.4; context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(value)); context.setInputValue(RETURN_VALUE_2, typedDatumFactory.createInteger(2)); component.start(); component.processInputs(); } /** * * Tests the "From Value" Input as simple test without any other Inputs. * * @throws ComponentException on unexpected errors */ @Test public void testInputFromValueOnlyParameterInputs() throws ComponentException { Map<String, String> metaData = generateParametricStudyMetadata(MINUS, true, TEN, false, ONE, false, false); addSimulatedOutputs(metaData); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); component.start(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, typedDatumFactory.createFloat(1.0)); component.processInputs(); assertEquals(10, context.getCapturedOutput(DESIGN_VARIABLE).size()); final Double[] expectedValues = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 }; assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), expectedValues)); checkDoneOutputs(true); component.tearDownAndDispose(FinalComponentState.FINISHED); } /** * * Tests the "To Value" Input as simple test without any other Inputs. * * @throws ComponentException on unexpected errors */ @Test public void testInputToValueOnlyParameterInputs() throws ComponentException { Map<String, String> metaData = generateParametricStudyMetadata(ONE, false, MINUS, true, ONE, false, false); addSimulatedOutputs(metaData); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_TO_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); component.start(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_TO_VALUE, typedDatumFactory.createFloat(10)); component.processInputs(); assertEquals(10, context.getCapturedOutput(DESIGN_VARIABLE).size()); final Double[] expectedValues = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 }; assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), expectedValues)); checkDoneOutputs(true); component.tearDownAndDispose(FinalComponentState.FINISHED); } /** * * Tests the "StepSize Value" Input as simple test without any other Inputs. * * @throws ComponentException on unexpected errors */ @Test public void testInputStepSizeValueOnlyParameterInputs() throws ComponentException { Map<String, String> metaData = generateParametricStudyMetadata(ONE, false, TEN, false, MINUS, true, false); addSimulatedOutputs(metaData); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_STEPSIZE_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); component.start(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_STEPSIZE_VALUE, typedDatumFactory.createFloat(1)); component.processInputs(); assertEquals(10, context.getCapturedOutput(DESIGN_VARIABLE).size()); final Double[] expectedValues = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 }; assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), expectedValues)); checkDoneOutputs(true); component.tearDownAndDispose(FinalComponentState.FINISHED); } /** * * Tests all input parameters in one run as simple test without any other Inputs. * * @throws ComponentException on unexpected errors */ @Test public void testAllInputParametersOnlyParameterInputs() throws ComponentException { Map<String, String> metaData = generateParametricStudyMetadata(MINUS, true, MINUS, true, MINUS, true, false); addSimulatedOutputs(metaData); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_TO_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_STEPSIZE_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); component.start(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, typedDatumFactory.createFloat(1.0)); context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_TO_VALUE, typedDatumFactory.createFloat(10)); context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_STEPSIZE_VALUE, typedDatumFactory.createFloat(1)); component.processInputs(); assertEquals(10, context.getCapturedOutput(DESIGN_VARIABLE).size()); final Double[] expectedValues = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 }; assertEquals(true, assertListsEqual(context.getCapturedOutput(DESIGN_VARIABLE), expectedValues)); checkDoneOutputs(true); component.tearDownAndDispose(FinalComponentState.FINISHED); } /** * * Test Input Parameter From Value with "waiting for evaluation result". * * @throws ComponentException on unexpected errors. */ @Test public void testInputParameterWithEvaluationResult() throws ComponentException { Map<String, String> metaData = generateParametricStudyMetadata(MINUS, true, TWO, false, ONE, false, false); addSimulatedOutputs(metaData); context.addSimulatedInput(RETURN_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); component.start(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, typedDatumFactory.createFloat(1)); component.processInputs(); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(1.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(2.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); component.processInputs(); // processes last evaluation result checkDoneOutputs(true); component.tearDownAndDispose(FinalComponentState.FINISHED); } /** * * Test one of the parameter inputs in combination with a forwarding endpoint. * * @throws ComponentException on unexpected error. */ @Test public void testInputParameterWithForwardEndpoint() throws ComponentException { Map<String, String> metaData = generateParametricStudyMetadata(MINUS, true, TWO, false, ONE, false, false); addSimulatedOutputs(metaData); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); context.addSimulatedInput(N, LoopComponentConstants.ENDPOINT_ID_TO_FORWARD, DataType.Float, true, null); context.addSimulatedInput(N + LoopComponentConstants.ENDPOINT_STARTVALUE_SUFFIX, LoopComponentConstants.ENDPOINT_ID_START_TO_FORWARD, DataType.Float, true, null, EndpointCharacter.OUTER_LOOP); context.addSimulatedOutput(N, LoopComponentConstants.ENDPOINT_ID_TO_FORWARD, DataType.Float, true, null); component.start(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(0, context.getCapturedOutput(N).size()); context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, typedDatumFactory.createFloat(1.0)); context.setInputValue(N + LoopComponentConstants.ENDPOINT_STARTVALUE_SUFFIX, typedDatumFactory.createFloat(3.0)); component.processInputs(); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(1.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); assertEquals(1, context.getCapturedOutput(N).size()); assertEquals(3.0, ((FloatTD) context.getCapturedOutput(N).get(0)).getFloatValue(), 0); context.setInputValue(N, typedDatumFactory.createFloat(4.0)); component.processInputs(); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(2.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); assertEquals(1, context.getCapturedOutput(N).size()); assertEquals(4.0, ((FloatTD) context.getCapturedOutput(N).get(0)).getFloatValue(), 0); context.setInputValue(N, typedDatumFactory.createFloat(5.0)); component.processInputs(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(0, context.getCapturedOutput(N).size()); checkDoneOutputs(true); component.tearDownAndDispose(FinalComponentState.FINISHED); } /** * * Test if input parameter originates from a driving component (i. e. nested loop) * * @throws ComponentException on unexpected error. */ @Test public void testInputParameterInNestedLoop() throws ComponentException { context.setConfigurationValue(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP, String.valueOf(true)); Map<String, String> metaData = generateParametricStudyMetadata(MINUS, true, TWO, false, ONE, false, false); addSimulatedOutputs(metaData); context.addSimulatedInput(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_STUDY_PARAMETERS, DataType.Float, true, metaData); context.addSimulatedInput(RETURN_VALUE, ParametricStudyComponentConstants.DYNAMIC_INPUT_IDENTIFIER, DataType.Float, true, null); component.start(); // context.setInputValue(LoopComponentConstants.ENDPOINT_NAME_OUTERLOOP_DONE, typedDatumFactory.createBoolean(false)); // first run context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, typedDatumFactory.createFloat(1.0)); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); component.processInputs(); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(1.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); checkDoneOutputs(false); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(2.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); component.reset(); checkDoneOutputs(true); // second run context.setInputValue(ParametricStudyComponentConstants.INPUT_NAME_FROM_VALUE, typedDatumFactory.createFloat(2.0)); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); component.processInputs(); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(2.0, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); context.setInputValue(RETURN_VALUE, typedDatumFactory.createFloat(5.0)); component.processInputs(); component.reset(); checkDoneOutputs(true); component.tearDownAndDispose(FinalComponentState.FINISHED); } /** * Test if the components cancels sending new design variables in case the component run (start) was canceled. * * @throws ComponentException on unexpected error. */ @Test(timeout = FIVE_HUNDRED_INT) public void testCancelStart() throws ComponentException { Map<String, String> metadata = generateParametricStudyMetadata(ONE, false, "100000", false, ONE, false, false); addSimulatedOutputs(metadata); ConcurrencyUtils.getAsyncTaskService().execute(new Runnable() { @Override public void run() { try { final int hundred = 100; Thread.sleep(hundred); } catch (InterruptedException e) { return; // test timeout will apply as onStartInterrupted is not called } component.onStartInterrupted(null); } }); component.start(); assertTrue(context.getCapturedOutput(DESIGN_VARIABLE).size() < HUNDRED_THOUSAND_INT); checkDoneOutputs(true); component.tearDownAndDispose(Component.FinalComponentState.FINISHED); } private void testOneLoopRun() throws ComponentException { assertEquals(0, context.getCapturedOutput(N).size()); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); context.setInputValue(N + LoopComponentConstants.ENDPOINT_STARTVALUE_SUFFIX, typedDatumFactory.createInteger(5)); component.processInputs(); assertEquals(1, context.getCapturedOutput(N).size()); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(1, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); assertEquals(0, context.getCapturedOutput(LoopComponentConstants.ENDPOINT_NAME_LOOP_DONE).size()); context.setInputValue(N, typedDatumFactory.createInteger(7)); component.processInputs(); assertEquals(1, context.getCapturedOutput(N).size()); assertEquals(1, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(2, ((FloatTD) context.getCapturedOutput(DESIGN_VARIABLE).get(0)).getFloatValue(), 0); assertEquals(0, context.getCapturedOutput(LoopComponentConstants.ENDPOINT_NAME_LOOP_DONE).size()); context.setInputValue(N, typedDatumFactory.createInteger(9)); component.processInputs(); assertEquals(0, context.getCapturedOutput(N).size()); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(0, context.getCapturedOutput(LoopComponentConstants.ENDPOINT_NAME_LOOP_DONE).size()); assertEquals(2, context.getCapturedOutputResets().size()); assertTrue(context.getCapturedOutputResets().contains(DESIGN_VARIABLE)); assertTrue(context.getCapturedOutputResets().contains(N)); component.reset(); assertEquals(0, context.getCapturedOutput(N).size()); assertEquals(0, context.getCapturedOutput(DESIGN_VARIABLE).size()); assertEquals(1, context.getCapturedOutput(LoopComponentConstants.ENDPOINT_NAME_LOOP_DONE).size()); } private void addSimulatedOutputs(Map<String, String> metadata) { context.addSimulatedOutput(DESIGN_VARIABLE, "", DataType.Float, false, metadata); context.addSimulatedOutput(LoopComponentConstants.ENDPOINT_NAME_LOOP_DONE, "", DataType.Boolean, false, null, EndpointCharacter.OUTER_LOOP); } private void checkDoneOutputs(boolean done) { checkDoneOutputs(done, false, 0); } private void checkDoneOutputs(boolean done, boolean outputsClosed, int dynOutputCount) { int countLoopDone; if (done) { countLoopDone = 1; } else { countLoopDone = 0; } assertEquals(countLoopDone, context.getCapturedOutput(DONE).size()); if (done) { assertTrue(((BooleanTD) context.getCapturedOutput(DONE).get(0)).getBooleanValue()); if (outputsClosed) { assertEquals(2 + dynOutputCount, context.getCapturedOutputClosings().size()); } } } /** * Helper method that checks lists for equality. * * @param listToCheck List of typed datums to be checked. * @param values Values to be compared with the list. * @return Whether the values are the same or not. */ private boolean assertListsEqual(List<TypedDatum> listToCheck, Double... values) { List<Double> valuesToCheck = Arrays.asList(values); if (valuesToCheck.size() != listToCheck.size()) { return false; } else { for (int i = 0; i < valuesToCheck.size(); i++) { if (valuesToCheck.get(i) != ((FloatTD) listToCheck.get(i)).getFloatValue()) { return false; } } return true; } } }