@Test public void nonExistentBinaryThrowsExceptionOnInfiniteWait() throws Exception { ListeningProcessExecutor executor = new ListeningProcessExecutor(); CapturingListener listener = new CapturingListener(); ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess( ProcessExecutorParams.ofCommand("this-better-not-be-a-process-on-your-system-for-real"), listener); exception.expect(IOException.class); exception.expectMessage( "Failed to start process [this-better-not-be-a-process-on-your-system-for-real]"); executor.waitForProcess(process); }
/** Tests for {@link ListeningProcessExecutor}. */ public class ListeningProcessExecutorTest { @Rule public TemporaryPaths tmp = new TemporaryPaths(); @Rule public ExpectedException exception = ExpectedException.none(); @Test public void echoTextReceivedOnStdout() throws Exception { ListeningProcessExecutor executor = new ListeningProcessExecutor(); CapturingListener listener = new CapturingListener(); ProcessExecutorParams params; if (Platform.detect() == Platform.WINDOWS) { params = ProcessExecutorParams.ofCommand("cmd.exe", "/c", "echo", "Hello"); } else { params = ProcessExecutorParams.ofCommand("echo", "Hello"); } ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess(params, listener); int returnCode = executor.waitForProcess(process); assertThat(returnCode, equalTo(0)); assertThat(listener.capturedStdout.toString("UTF-8"), equalTo(String.format("Hello%n"))); assertThat(listener.capturedStderr.toString("UTF-8"), is(emptyString())); } @Test public void processCwdIsRespected() throws Exception { ProcessExecutorParams.Builder paramsBuilder = ProcessExecutorParams.builder(); if (Platform.detect() == Platform.WINDOWS) { paramsBuilder.addCommand("cmd.exe", "/c", "type"); } else { paramsBuilder.addCommand("cat"); } paramsBuilder.addCommand("hello-world.txt"); paramsBuilder.setDirectory(tmp.getRoot()); Path helloWorldPath = tmp.getRoot().resolve("hello-world.txt"); String fileContents = "Hello, world!"; Files.write(helloWorldPath, fileContents.getBytes(StandardCharsets.UTF_8)); ListeningProcessExecutor executor = new ListeningProcessExecutor(); CapturingListener listener = new CapturingListener(); ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess(paramsBuilder.build(), listener); int returnCode = executor.waitForProcess(process); assertThat(returnCode, equalTo(0)); assertThat(listener.capturedStdout.toString("UTF-8"), equalTo(fileContents)); assertThat(listener.capturedStderr.toString("UTF-8"), is(emptyString())); } @Test public void catTextSentToStdinReceivedOnStdout() throws Exception { ProcessExecutorParams params; if (Platform.detect() == Platform.WINDOWS) { params = ProcessExecutorParams.ofCommand( "python", "-c", "import sys, shutil; shutil.copyfileobj(sys.stdin, sys.stdout)"); } else { params = ProcessExecutorParams.ofCommand("cat"); } ListeningProcessExecutor executor = new ListeningProcessExecutor(); StdinWritingListener listener = new StdinWritingListener(String.format("Meow%n")); ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess(params, listener); process.wantWrite(); int returnCode = executor.waitForProcess(process); assertThat(returnCode, equalTo(0)); assertThat(listener.capturedStdout.toString("UTF-8"), equalTo(String.format("Meow%n"))); assertThat(listener.capturedStderr.toString("UTF-8"), is(emptyString())); } @Test public void catMoreTextThanFitsInSingleBufferReceivedOnStdout() throws Exception { ProcessExecutorParams params; if (Platform.detect() == Platform.WINDOWS) { params = ProcessExecutorParams.ofCommand( "python", "-c", "import sys, shutil; shutil.copyfileobj(sys.stdin, sys.stdout)"); } else { params = ProcessExecutorParams.ofCommand("cat"); } ListeningProcessExecutor executor = new ListeningProcessExecutor(); StringBuilder sb = new StringBuilder(); // Use a 3 byte Unicode sequence to ensure writes go across byte buffer // boundaries, and append it as many times as needed to ensure it doesn't // fit in a single I/O buffer. String threeByteUTF8 = "\u2764"; for (int i = 0; i < ListeningProcessExecutor.LaunchedProcess.BUFFER_CAPACITY + 1; i++) { sb.append(threeByteUTF8); } sb.append(String.format("%n")); String longString = sb.toString(); StdinWritingListener listener = new StdinWritingListener(longString); ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess(params, listener); process.wantWrite(); int returnCode = executor.waitForProcess(process); assertThat(returnCode, equalTo(0)); assertThat(listener.capturedStdout.toString("UTF-8"), equalTo(longString)); assertThat(listener.capturedStderr.toString("UTF-8"), is(emptyString())); } @Test public void processFailureExitCodeNotZero() throws Exception { ProcessExecutorParams params; if (Platform.detect() == Platform.WINDOWS) { params = ProcessExecutorParams.ofCommand("cmd.exe", "/c", "exit", "1"); } else { params = ProcessExecutorParams.ofCommand("false"); } ListeningProcessExecutor executor = new ListeningProcessExecutor(); CapturingListener listener = new CapturingListener(); ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess(params, listener); int returnCode = executor.waitForProcess(process); assertThat(returnCode, not(equalTo(0))); assertThat(listener.capturedStdout.toString("UTF-8"), is(emptyString())); assertThat(listener.capturedStderr.toString("UTF-8"), is(emptyString())); } @Test public void nonExistentBinaryExitCodeNotZeroOnLimitedWait() throws Exception { ListeningProcessExecutor executor = new ListeningProcessExecutor(); CapturingListener listener = new CapturingListener(); ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess( ProcessExecutorParams.ofCommand("this-better-not-be-a-process-on-your-system-for-real"), listener); int returnCode = executor.waitForProcess(process, Long.MAX_VALUE, TimeUnit.SECONDS); assertThat(returnCode, not(equalTo(0))); assertThat(listener.capturedStdout.toString("UTF-8"), is(emptyString())); assertThat(listener.capturedStderr.toString("UTF-8"), is(emptyString())); } @Test public void nonExistentBinaryThrowsExceptionOnInfiniteWait() throws Exception { ListeningProcessExecutor executor = new ListeningProcessExecutor(); CapturingListener listener = new CapturingListener(); ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess( ProcessExecutorParams.ofCommand("this-better-not-be-a-process-on-your-system-for-real"), listener); exception.expect(IOException.class); exception.expectMessage( "Failed to start process [this-better-not-be-a-process-on-your-system-for-real]"); executor.waitForProcess(process); } @Test public void waitForProcessReturnsMinIntegerOnTimeout() throws Exception { ListeningProcessExecutor executor = new ListeningProcessExecutor(); CapturingListener listener = new CapturingListener(); ProcessExecutorParams params; if (Platform.detect() == Platform.WINDOWS) { params = ProcessExecutorParams.ofCommand("python", "-c", "import time; time.sleep(50)"); } else { params = ProcessExecutorParams.ofCommand("sleep", "50"); } ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess(params, listener); int returnCode = executor.waitForProcess(process, 100, TimeUnit.MILLISECONDS); assertThat(returnCode, equalTo(Integer.MIN_VALUE)); assertThat(listener.capturedStdout.toString("UTF-8"), is(emptyString())); assertThat(listener.capturedStderr.toString("UTF-8"), is(emptyString())); executor.destroyProcess(process, /* force */ true); executor.waitForProcess(process); } @Test public void clearsEnvWhenExplicitlySet() throws Exception { ListeningProcessExecutor executor = new ListeningProcessExecutor(); CapturingListener listener = new CapturingListener(); ProcessExecutorParams params; if (Platform.detect() == Platform.WINDOWS) { params = ProcessExecutorParams.ofCommand("cmd.exe", "/c", "set"); } else { params = ProcessExecutorParams.ofCommand("env"); } params = params.withEnvironment(new HashMap<String, String>()); ListeningProcessExecutor.LaunchedProcess process = executor.launchProcess(params, listener); int returnCode = executor.waitForProcess(process); assertThat(returnCode, equalTo(0)); assertThat(listener.capturedStdout.toString("UTF-8"), is(emptyString())); assertThat(listener.capturedStderr.toString("UTF-8"), is(emptyString())); } }