/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.utils.executor; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Assert; import de.rcenvironment.core.toolkitbridge.transitional.TextStreamWatcherFactory; import de.rcenvironment.core.utils.common.textstream.TextStreamWatcher; import de.rcenvironment.core.utils.common.textstream.receivers.CapturingTextOutReceiver; /** * Common test setups for all {@link CommandLineExecutor} implementations to ensure consistency and * avoid code duplication. For each implementation, a subclass should provide top-level JUnit tests * that call each method of this class with a configured {@link CommandLineExecutor}. * * @author Robert Mischke * */ abstract class CommonExecutorTests { protected static final String MESSAGE_UNEXPECTED_STDOUT = "Unexpected StdOut: "; protected static final String MESSAGE_UNEXPECTED_STDERR = "Unexpected StdErr: "; protected static final String MESSAGE_LINUX_SPECIFIC_TEST_SKIPPED = "Test is only runnable on Linux; skipping"; protected static final String MESSAGE_WINDOWS_SPECIFIC_TEST_SKIPPED = "Test is only runnable on Windows; skipping"; protected static final int DEFAULT_TEST_TIMEOUT = 10000; /** * A simple holder for StdOut/StdErr strings. * */ public final class OutputHolder { private String stdout; private String stderr; OutputHolder(String stdout, String stderr) { this.stdout = stdout; this.stderr = stderr; } public String getStdout() { return stdout; } public String getStderr() { return stderr; } } protected final Log log = LogFactory.getLog(getClass()); // FIXME new tests not cross-checked on Linux yet! protected void testCrossPlatformEcho(CommandLineExecutor executor) throws IOException, InterruptedException { executor.start("echo expected test output"); OutputHolder output = waitAndCaptureOutput(executor); // check StdErr first as it may contain helpful information on failure Assert.assertEquals(MESSAGE_UNEXPECTED_STDERR, "", output.getStderr()); Assert.assertEquals(MESSAGE_UNEXPECTED_STDOUT, "expected test output\n", output.getStdout()); } protected void testCrossPlatformMultiLineEcho(CommandLineExecutor executor) throws IOException, InterruptedException { executor.startMultiLineCommand(new String[] { "echo expected line1", "echo expected line2" }); OutputHolder output = waitAndCaptureOutput(executor); // check StdErr first as it may contain helpful information on failure Assert.assertEquals(MESSAGE_UNEXPECTED_STDERR, "", output.getStderr()); Assert.assertEquals(MESSAGE_UNEXPECTED_STDOUT, "expected line1\n" + "expected line2\n", output.getStdout()); } protected void testLinuxEnvironmentSetting(CommandLineExecutor executor) throws IOException, InterruptedException { executor.setEnv("TEST1", "val1"); executor.start("echo key1=$TEST1, key2=$UNDEF"); OutputHolder output = waitAndCaptureOutput(executor); // check StdErr first as it may contain helpful information on failure Assert.assertEquals(MESSAGE_UNEXPECTED_STDERR, "", output.getStderr()); Assert.assertEquals(MESSAGE_UNEXPECTED_STDOUT, "key1=val1, key2=\n", output.getStdout()); } protected void testLinuxProvidedInputStream(CommandLineExecutor executor) throws UnsupportedEncodingException, IOException, InterruptedException { // data to be sent to STDIN final String testInputData = "test input"; ByteArrayInputStream stdinStream = new ByteArrayInputStream(testInputData.getBytes("UTF-8")); executor.start("read in; echo received: $in", stdinStream); OutputHolder output = waitAndCaptureOutput(executor); // STDERR should be empty, and the test data should have been piped to STDOUT with a prefix Assert.assertEquals(MESSAGE_UNEXPECTED_STDERR, "", output.getStderr()); Assert.assertEquals(MESSAGE_UNEXPECTED_STDOUT, "received: " + testInputData + "\n", output.getStdout()); } protected void testWindowsEnvironmentSetting(CommandLineExecutor executor) throws IOException, InterruptedException { executor.setEnv("TEST1", "val1"); executor.start("echo key1=%TEST1%, key2="); OutputHolder output = waitAndCaptureOutput(executor); // check StdErr first as it may contain helpful information on failure Assert.assertEquals(MESSAGE_UNEXPECTED_STDERR, "", output.getStderr()); Assert.assertEquals(MESSAGE_UNEXPECTED_STDOUT, "key1=val1, key2=\n", output.getStdout()); } protected void testWindowsProvidedInputStream(CommandLineExecutor executor) throws UnsupportedEncodingException, IOException, InterruptedException { // data to be sent to STDIN // final String testInputData = "test input\n"; // // ByteArrayInputStream stdinStream = new ByteArrayInputStream(testInputData.getBytes("UTF-8")); // executor.start("SET /P tmpVar= && echo %tmpVar%", stdinStream); // executor.start("echo %tmpVar%"); // // OutputHolder output = waitAndCaptureOutput(executor); // // STDERR should be empty, and the test data should have been piped to STDOUT with a prefix // Assert.assertEquals(MESSAGE_UNEXPECTED_STDERR, "", output.getStderr()); // Assert.assertEquals(MESSAGE_UNEXPECTED_STDOUT, "received: " + testInputData + "\n", output.getStdout()); } /** * Common utility method. */ protected void waitAndGatherOutput(CommandLineExecutor executor, final CapturingTextOutReceiver outReceiver, final CapturingTextOutReceiver errReceiver) throws IOException, InterruptedException { final TextStreamWatcher stdoutWatcher = TextStreamWatcherFactory.create(executor.getStdout(), outReceiver).start(); final TextStreamWatcher stderrWatcher = TextStreamWatcherFactory.create(executor.getStderr(), errReceiver).start(); executor.waitForTermination(); stdoutWatcher.waitForTermination(); stderrWatcher.waitForTermination(); } /** * Common utility method. */ protected OutputHolder waitAndCaptureOutput(CommandLineExecutor executor) throws IOException, InterruptedException { // execute final CapturingTextOutReceiver outReceiver = new CapturingTextOutReceiver(""); final CapturingTextOutReceiver errReceiver = new CapturingTextOutReceiver(""); waitAndGatherOutput(executor, outReceiver, errReceiver); // wrap & return output return new OutputHolder(outReceiver.getBufferedOutput(), errReceiver.getBufferedOutput()); } }