/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.inputprovider.execution; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.easymock.EasyMock; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import de.rcenvironment.components.inputprovider.common.InputProviderComponentConstants; import de.rcenvironment.core.component.api.ComponentException; import de.rcenvironment.core.component.datamanagement.api.ComponentDataManagementService; import de.rcenvironment.core.component.execution.api.Component; 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.TypedDatumFactory; import de.rcenvironment.core.datamodel.api.TypedDatumService; import de.rcenvironment.core.datamodel.types.api.DirectoryReferenceTD; import de.rcenvironment.core.datamodel.types.api.FileReferenceTD; import de.rcenvironment.core.utils.common.StringUtils; import de.rcenvironment.core.utils.common.TempFileService; import de.rcenvironment.core.utils.common.TempFileServiceAccess; /** * * Integration test for {@link InputProviderComponent}. * * @author Marc Stammerjohann */ public class InputProviderComponentTest { private static final String WORKFLOWSTART_PLACEHOLDER = "${%s}"; private static final String WORKFLOW_START = "WorkflowStart"; private static final String EMPTY_VARIABLE = "Empty Variable"; private static final String SHORTTEXT_VARIABLE = "Short Text"; private static final String FLOAT_VARIABLE = "Float"; private static final String BOOLEAN_VARIABLE = "Boolean"; private static final String INT_VARIABLE = "Integer"; private static final String FILE_VARIABLE = "newFile"; private static final String DIR_VARIABLE = "newDir"; private static final String OUTPUT_FILENAME = "outputFile.file"; private static final String OUTPUT_DIR = "rceDir"; /** * Expected exception if data type is not supported. */ @Rule public ExpectedException dataException = ExpectedException.none(); private ComponentTestWrapper component; private ComponentContextMock context; private TypedDatumFactory typedDatumFactory; private TempFileService tempFileService; private ComponentDataManagementService componentDataManagementServiceMock; /** * * Set up input provider test. * * @throws Exception e */ @Before public void setUp() throws Exception { context = new ComponentContextMock(); component = new ComponentTestWrapper(new InputProviderComponent(), context); typedDatumFactory = context.getService(TypedDatumService.class).getFactory(); // Setup root directory for testing TempFileServiceAccess.setupUnitTestEnvironment(); tempFileService = TempFileServiceAccess.getInstance(); componentDataManagementServiceMock = EasyMock.createMock(ComponentDataManagementService.class); context.addService(ComponentDataManagementService.class, componentDataManagementServiceMock); } /** * Common cleanup. */ @After public void tearDown() { component.tearDown(Component.FinalComponentState.FINISHED); component.dispose(); } /** * @throws ComponentException ce * */ @Test public void testWorkflowStartConfiguration() throws ComponentException { String booleanValue = "false"; String placeholder = StringUtils.format(WORKFLOWSTART_PLACEHOLDER, WORKFLOW_START); context.addSimulatedOutput(WORKFLOW_START, "", DataType.Boolean, false, generateInputProviderMetadata(placeholder)); context.setConfigurationValue(WORKFLOW_START, booleanValue); component.start(); assertEquals(typedDatumFactory.createBoolean(Boolean.parseBoolean(booleanValue)), context.getCapturedOutput(WORKFLOW_START).get(0)); } /** * @throws ComponentException ce * */ @Test public void testNotSupportedDataType() throws ComponentException { DataType type = DataType.Empty; context.addSimulatedOutput(EMPTY_VARIABLE, "", type, false, null); dataException.expect(ComponentException.class); dataException.expectMessage("Given data type is not supported: " + type); component.start(); } /** * Test with three outputs. * * @throws ComponentException ce */ @Test public void testMultipleOutputs() throws ComponentException { String booleanValue = "true"; String shorttext = "RCE Test"; String floatValue = "7.6"; context.addSimulatedOutput(BOOLEAN_VARIABLE, "", DataType.Boolean, false, generateInputProviderMetadata(booleanValue)); context.addSimulatedOutput(SHORTTEXT_VARIABLE, "", DataType.ShortText, false, generateInputProviderMetadata(shorttext)); context.addSimulatedOutput(FLOAT_VARIABLE, "", DataType.Float, false, generateInputProviderMetadata(floatValue)); component.start(); assertEquals(typedDatumFactory.createBoolean(Boolean.parseBoolean(booleanValue)), context.getCapturedOutput(BOOLEAN_VARIABLE) .get(0)); assertEquals(typedDatumFactory.createShortText(shorttext), context.getCapturedOutput(SHORTTEXT_VARIABLE) .get(0)); assertEquals(typedDatumFactory.createFloat(Double.parseDouble(floatValue)), context.getCapturedOutput(FLOAT_VARIABLE) .get(0)); } /** * Test with one output. * * @throws ComponentException ce */ @Test public void testShortTextOutput() throws ComponentException { String value = "RCE Next Generation"; Map<String, String> metaData = generateInputProviderMetadata(value); context.addSimulatedOutput(SHORTTEXT_VARIABLE, "", DataType.ShortText, false, metaData); component.start(); assertEquals(typedDatumFactory.createShortText(value), context.getCapturedOutput(SHORTTEXT_VARIABLE).get(0)); } /** * Test with one output. * * @throws ComponentException ce */ @Test public void testBooleanOutput() throws ComponentException { String value = "false"; Map<String, String> metaData = generateInputProviderMetadata(value); context.addSimulatedOutput(BOOLEAN_VARIABLE, "", DataType.Boolean, false, metaData); component.start(); assertEquals(typedDatumFactory.createBoolean(Boolean.parseBoolean(value)), context.getCapturedOutput(BOOLEAN_VARIABLE).get(0)); } /** * Test with one output. * * @throws ComponentException ce */ @Test public void testFloatOutput() throws ComponentException { String value = "5.0"; Map<String, String> metaData = generateInputProviderMetadata(value); context.addSimulatedOutput(FLOAT_VARIABLE, "", DataType.Float, false, metaData); component.start(); assertEquals(typedDatumFactory.createFloat(Double.parseDouble(value)), context.getCapturedOutput(FLOAT_VARIABLE).get(0)); } /** * Test with one output. * * @throws ComponentException ce */ @Test public void testIntegerOutput() throws ComponentException { String value = "10"; Map<String, String> metaData = generateInputProviderMetadata(value); context.addSimulatedOutput(INT_VARIABLE, "", DataType.Integer, false, metaData); component.start(); assertEquals(typedDatumFactory.createInteger(Integer.parseInt(value)), context.getCapturedOutput(INT_VARIABLE).get(0)); } /** * Test with one output. * * @throws ComponentException ce * @throws IOException ioe */ @Test public void testFileOutput() throws ComponentException, IOException { File createTempDir = createTempDir(); File testFile = createAndVerifyFile(createTempDir, OUTPUT_FILENAME); FileReferenceTD dummyFileReference = typedDatumFactory.createFileReference(testFile.getAbsolutePath(), OUTPUT_FILENAME); EasyMock.reset(componentDataManagementServiceMock); EasyMock.expect(componentDataManagementServiceMock.createFileReferenceTDFromLocalFile(context, testFile, testFile.getName())) .andReturn(dummyFileReference); EasyMock.replay(componentDataManagementServiceMock); Map<String, String> metaData = generateInputProviderMetadata(testFile.getAbsolutePath()); context.addSimulatedOutput(FILE_VARIABLE, "", DataType.FileReference, false, metaData); component.start(); assertEquals(dummyFileReference, context.getCapturedOutput(FILE_VARIABLE).get(0)); removeTempDirOrFile(createTempDir); } /** * Test with one output with an empty value. * * @throws ComponentException ce */ @Test public void testFileIsNull() throws ComponentException { String value = ""; Map<String, String> metaData = generateInputProviderMetadata(value); context.addSimulatedOutput(FILE_VARIABLE, "", DataType.FileReference, false, metaData); dataException.expect(ComponentException.class); dataException.expectMessage(StringUtils.format("Internal error: No file given for output '%s'", FILE_VARIABLE)); component.start(); } /** * Test with one output with an not existing file value. * * @throws ComponentException ce * @throws IOException on unexpected error */ @Test public void testFileNotExist() throws ComponentException, IOException { File emptyTempDir = tempFileService.createManagedTempDir(); Map<String, String> metaData = generatedMetaDataForNonExistentFileOrDir(emptyTempDir); context.addSimulatedOutput(FILE_VARIABLE, "", DataType.FileReference, false, metaData); dataException.expect(ComponentException.class); component.start(); removeTempDirOrFile(emptyTempDir); } private Map<String, String> generatedMetaDataForNonExistentFileOrDir(File emptyTempDir) { String value = new File(emptyTempDir, "not_existent").getAbsolutePath(); Map<String, String> metaData = generateInputProviderMetadata(value); return metaData; } /** * Test with one output. * * @throws ComponentException ce * @throws IOException ioe */ @Test public void testDirOutput() throws ComponentException, IOException { File createTempDir = createTempDir(OUTPUT_DIR); DirectoryReferenceTD createDirectoryReference = typedDatumFactory.createDirectoryReference(createTempDir.getAbsolutePath(), OUTPUT_DIR); EasyMock.reset(componentDataManagementServiceMock); EasyMock.expect(componentDataManagementServiceMock.createDirectoryReferenceTDFromLocalDirectory(context, createTempDir, createTempDir.getName())).andReturn(createDirectoryReference); EasyMock.replay(componentDataManagementServiceMock); Map<String, String> metaData = generateInputProviderMetadata(createTempDir.getAbsolutePath()); context.addSimulatedOutput(DIR_VARIABLE, "", DataType.DirectoryReference, false, metaData); component.start(); assertEquals(createDirectoryReference, context.getCapturedOutput(DIR_VARIABLE).get(0)); removeTempDirOrFile(createTempDir); } /** * Test with one output with an empty value. * * @throws ComponentException ce */ @Test public void testDirIsNull() throws ComponentException { String value = ""; Map<String, String> metaData = generateInputProviderMetadata(value); context.addSimulatedOutput(DIR_VARIABLE, "", DataType.DirectoryReference, false, metaData); dataException.expect(ComponentException.class); component.start(); } /** * Test with one output with an not existing file value. * * @throws ComponentException ce * @throws IOException on unexpected error */ @Test public void testDirNotExist() throws ComponentException, IOException { File emptyTempDir = tempFileService.createManagedTempDir(); Map<String, String> metaData = generatedMetaDataForNonExistentFileOrDir(emptyTempDir); context.addSimulatedOutput(DIR_VARIABLE, "", DataType.DirectoryReference, false, metaData); dataException.expect(ComponentException.class); component.start(); removeTempDirOrFile(emptyTempDir); } /** * Test with one output. Simulated output from type directory, but it is actually a file. * * @throws ComponentException ce * @throws IOException ioe */ @Test public void testDirOutputWithFile() throws ComponentException, IOException { File createTempDir = createTempDir(); File testFile = createAndVerifyFile(createTempDir, OUTPUT_FILENAME); FileReferenceTD dummyFileReference = typedDatumFactory.createFileReference(testFile.getAbsolutePath(), OUTPUT_FILENAME); EasyMock.reset(componentDataManagementServiceMock); EasyMock.expect(componentDataManagementServiceMock.createFileReferenceTDFromLocalFile(context, testFile, testFile.getName())) .andReturn(dummyFileReference); EasyMock.replay(componentDataManagementServiceMock); Map<String, String> metaData = generateInputProviderMetadata(testFile.getAbsolutePath()); context.addSimulatedOutput(DIR_VARIABLE, "", DataType.DirectoryReference, false, metaData); dataException.expect(ComponentException.class); try { component.start(); } finally { removeTempDirOrFile(createTempDir); } } private Map<String, String> generateInputProviderMetadata(String value) { Map<String, String> metadata = new HashMap<>(); metadata.put(InputProviderComponentConstants.META_VALUE, value); return metadata; } /** * Creates a new temporary directory. * * @return The File object of the directory. */ private File createTempDir() { try { return tempFileService.createManagedTempDir(); } catch (IOException e) { throw new IllegalStateException("Failed to create test temp dir", e); } } /** * Creates a new temporary directory. * * @return The File object of the directory. */ private File createTempDir(String infoText) { try { return tempFileService.createManagedTempDir(infoText); } catch (IOException e) { throw new IllegalStateException("Failed to create test temp dir", e); } } /** * Recursively removes a temporary directory. * * @param file The File object of the directory. */ private void removeTempDirOrFile(File file) { try { tempFileService.disposeManagedTempDirOrFile(file); } catch (IOException e) { throw new RuntimeException(e); } } private File createAndVerifyFile(File parentDir, String name) throws IOException { File file = new File(parentDir, name); file.createNewFile(); assertTrue(file.isFile() && file.canRead()); return file; } }