You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by br...@apache.org on 2014/01/10 15:23:40 UTC
svn commit: r1557130 - in
/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec: ./ issues/
Author: britter
Date: Fri Jan 10 14:23:40 2014
New Revision: 1557130
URL: http://svn.apache.org/r1557130
Log:
Move issue specific tests into own package, away from general test code
Added:
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec33Test.java (with props)
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec34Test.java (with props)
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec36Test.java (with props)
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec41Test.java (with props)
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec44Test.java (with props)
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec49Test.java (with props)
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java (with props)
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec60Test.java (with props)
Modified:
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
Modified: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java?rev=1557130&r1=1557129&r2=1557130&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java (original)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java Fri Jan 10 14:23:40 2014
@@ -33,8 +33,6 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
import java.util.HashMap;
import java.util.Map;
@@ -63,7 +61,6 @@ public class DefaultExecutorTest {
private final File foreverTestScript = TestUtil.resolveScriptForOS(testDir + "/forever");
private final File nonExistingTestScript = TestUtil.resolveScriptForOS(testDir + "/grmpffffff");
private final File redirectScript = TestUtil.resolveScriptForOS(testDir + "/redirect");
- private final File pingScript = TestUtil.resolveScriptForOS(testDir + "/ping");
private final File printArgsScript = TestUtil.resolveScriptForOS(testDir + "/printargs");
// private final File acroRd32Script = TestUtil.resolveScriptForOS(testDir + "/acrord32");
private final File stdinSript = TestUtil.resolveScriptForOS(testDir + "/stdin");
@@ -700,486 +697,6 @@ public class DefaultExecutorTest {
}
// ======================================================================
- // === Testing bug fixes
- // ======================================================================
-
- /**
- * Test the patch for EXEC-33 (https://issues.apache.org/jira/browse/EXEC-33)
- *
- * PumpStreamHandler hangs if System.in is redirect to process input stream .
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec33() throws Exception {
- final CommandLine cl = new CommandLine(testScript);
- final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err, System.in);
- final DefaultExecutor executor = new DefaultExecutor();
- executor.setStreamHandler(pumpStreamHandler);
- final int exitValue = executor.execute(cl);
- assertFalse(exec.isFailure(exitValue));
- }
-
- /**
- * EXEC-34 https://issues.apache.org/jira/browse/EXEC-34
- *
- * Race condition prevent watchdog working using ExecuteStreamHandler.
- * The test fails because when watchdog.destroyProcess() is invoked the
- * external process is not bound to the watchdog yet.
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec34_1() throws Exception {
-
- final CommandLine cmdLine = new CommandLine(pingScript);
- cmdLine.addArgument("10"); // sleep 10 secs
-
- final ExecuteWatchdog watchdog = new ExecuteWatchdog(Integer.MAX_VALUE);
- final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
- exec.setWatchdog(watchdog);
- exec.execute(cmdLine, handler);
- assertTrue(watchdog.isWatching());
- watchdog.destroyProcess();
- assertTrue("Watchdog should have killed the process",watchdog.killedProcess());
- assertFalse("Watchdog is no longer watching the process",watchdog.isWatching());
- }
-
- /**
- * EXEC-34 https://issues.apache.org/jira/browse/EXEC-34
- *
- * Some user waited for an asynchronous process using watchdog.isWatching() which
- * is now properly implemented using <code>DefaultExecuteResultHandler</code>.
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec34_2() throws Exception {
-
- final CommandLine cmdLine = new CommandLine(pingScript);
- cmdLine.addArgument("10"); // sleep 10 secs
-
- final ExecuteWatchdog watchdog = new ExecuteWatchdog(5000);
- final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
- exec.setWatchdog(watchdog);
- exec.execute(cmdLine, handler);
- handler.waitFor();
- assertTrue("Process has exited", handler.hasResult());
- assertNotNull("Process was aborted", handler.getException());
- assertTrue("Watchdog should have killed the process", watchdog.killedProcess());
- assertFalse("Watchdog is no longer watching the process", watchdog.isWatching());
- }
-
- /**
- * Test EXEC-36 see https://issues.apache.org/jira/browse/EXEC-36
- *
- * Original example from Kai Hu which only can be tested on Unix
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec36_1() throws Exception {
-
- if (OS.isFamilyUnix()) {
-
- CommandLine cmdl;
-
- /**
- * ./script/jrake cruise:publish_installers INSTALLER_VERSION=unstable_2_1 \
- * INSTALLER_PATH="/var/lib/ cruise-agent/installers" INSTALLER_DOWNLOAD_SERVER='something' WITHOUT_HELP_DOC=true
- */
-
- final String expected = "./script/jrake\n" +
- "cruise:publish_installers\n" +
- "INSTALLER_VERSION=unstable_2_1\n" +
- "INSTALLER_PATH=\"/var/lib/ cruise-agent/installers\"\n" +
- "INSTALLER_DOWNLOAD_SERVER='something'\n" +
- "WITHOUT_HELP_DOC=true";
-
- cmdl = new CommandLine(printArgsScript);
- cmdl.addArgument("./script/jrake", false);
- cmdl.addArgument("cruise:publish_installers", false);
- cmdl.addArgument("INSTALLER_VERSION=unstable_2_1", false);
- cmdl.addArgument("INSTALLER_PATH=\"/var/lib/ cruise-agent/installers\"", false);
- cmdl.addArgument("INSTALLER_DOWNLOAD_SERVER='something'", false);
- cmdl.addArgument("WITHOUT_HELP_DOC=true", false);
-
- final int exitValue = exec.execute(cmdl);
- final String result = baos.toString().trim();
- assertFalse(exec.isFailure(exitValue));
- assertEquals(expected, result);
- }
- else {
- System.err.println("The test 'testExec36_1' does not support the following OS : " + System.getProperty("os.name"));
- return;
- }
- }
-
- /**
- * Test EXEC-36 see https://issues.apache.org/jira/browse/EXEC-36
- *
- * Test a complex real example found at
- * http://blogs.msdn.com/b/astebner/archive/2005/12/13/503471.aspx
- *
- * The command line is so weird that it even falls apart under Windows
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec36_2() throws Exception {
-
- String expected;
-
- // the original command line
- // dotnetfx.exe /q:a /c:"install.exe /l ""\Documents and Settings\myusername\Local Settings\Temp\netfx.log"" /q"
-
- if (OS.isFamilyWindows()) {
- expected = "dotnetfx.exe\n" +
- "/q:a\n" +
- "/c:\"install.exe /l \"\"\\Documents and Settings\\myusername\\Local Settings\\Temp\\netfx.log\"\" /q\"";
- }
- else if (OS.isFamilyUnix()) {
- expected = "dotnetfx.exe\n" +
- "/q:a\n" +
- "/c:\"install.exe /l \"\"/Documents and Settings/myusername/Local Settings/Temp/netfx.log\"\" /q\"";
- }
- else {
- System.err.println("The test 'testExec36_3' does not support the following OS : " + System.getProperty("os.name"));
- return;
- }
-
- CommandLine cmdl;
- final File file = new File("/Documents and Settings/myusername/Local Settings/Temp/netfx.log");
- final Map map = new HashMap();
- map.put("FILE", file);
-
- cmdl = new CommandLine(printArgsScript);
- cmdl.setSubstitutionMap(map);
- cmdl.addArgument("dotnetfx.exe", false);
- cmdl.addArgument("/q:a", false);
- cmdl.addArgument("/c:\"install.exe /l \"\"${FILE}\"\" /q\"", false);
-
- final int exitValue = exec.execute(cmdl);
- final String result = baos.toString().trim();
- assertFalse(exec.isFailure(exitValue));
-
- if (OS.isFamilyUnix()) {
- // the parameters fall literally apart under Windows - need to disable the check for Win32
- assertEquals(expected, result);
- }
- }
-
- /**
- * Test the patch for EXEC-41 (https://issues.apache.org/jira/browse/EXEC-41).
- *
- * When a process runs longer than allowed by a configured watchdog's
- * timeout, the watchdog tries to destroy it and then DefaultExecutor
- * tries to clean up by joining with all installed pump stream threads.
- * Problem is, that sometimes the native process doesn't die and thus
- * streams aren't closed and the stream threads do not complete.
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec41WithStreams() throws Exception {
-
- CommandLine cmdLine;
-
- if (OS.isFamilyWindows()) {
- cmdLine = CommandLine.parse("ping.exe -n 10 -w 1000 127.0.0.1");
- } else if ("HP-UX".equals(System.getProperty("os.name"))) {
- // see EXEC-52 - option must appear after the hostname!
- cmdLine = CommandLine.parse("ping 127.0.0.1 -n 10");
- } else if (OS.isFamilyUnix()) {
- cmdLine = CommandLine.parse("ping -c 10 127.0.0.1");
- } else {
- System.err.println("The test 'testExec41WithStreams' does not support the following OS : "
- + System.getProperty("os.name"));
- return;
- }
-
- final DefaultExecutor executor = new DefaultExecutor();
- final ExecuteWatchdog watchdog = new ExecuteWatchdog(2 * 1000); // allow process no more than 2 secs
- final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err);
- // this method was part of the patch I reverted
- // pumpStreamHandler.setAlwaysWaitForStreamThreads(false);
-
- executor.setWatchdog(watchdog);
- executor.setStreamHandler(pumpStreamHandler);
-
- final long startTime = System.currentTimeMillis();
-
- try {
- executor.execute(cmdLine);
- } catch (final ExecuteException e) {
- // nothing to do
- }
-
- final long duration = System.currentTimeMillis() - startTime;
-
- System.out.println("Process completed in " + duration + " millis; below is its output");
-
- if (watchdog.killedProcess()) {
- System.out.println("Process timed out and was killed by watchdog.");
- }
-
- assertTrue("The process was killed by the watchdog", watchdog.killedProcess());
- assertTrue("Skipping the Thread.join() did not work", duration < 9000);
- }
-
- /**
- * Test EXEC-41 with a disabled PumpStreamHandler to check if we could return
- * immediately after killing the process (no streams implies no blocking
- * stream pumper threads). But you have to be 100% sure that the subprocess
- * is not writing to 'stdout' and 'stderr'.
- *
- * For this test we are using the batch file - under Windows the 'ping'
- * process can't be killed (not supported by Win32) and will happily
- * run the given time (e.g. 10 seconds) even hwen the batch file is already
- * killed.
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec41WithoutStreams() throws Exception {
-
- final CommandLine cmdLine = new CommandLine(pingScript);
- cmdLine.addArgument("10"); // sleep 10 secs
- final DefaultExecutor executor = new DefaultExecutor();
- final ExecuteWatchdog watchdog = new ExecuteWatchdog(2*1000); // allow process no more than 2 secs
-
- // create a custom "PumpStreamHandler" doing no pumping at all
- final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(null, null, null);
-
- executor.setWatchdog(watchdog);
- executor.setStreamHandler(pumpStreamHandler);
-
- final long startTime = System.currentTimeMillis();
-
- try {
- executor.execute(cmdLine);
- } catch (final ExecuteException e) {
- System.out.println(e);
- }
-
- final long duration = System.currentTimeMillis() - startTime;
-
- System.out.println("Process completed in " + duration +" millis; below is its output");
-
- if (watchdog.killedProcess()) {
- System.out.println("Process timed out and was killed.");
- }
-
- assertTrue("The process was killed by the watchdog", watchdog.killedProcess());
- assertTrue("Skipping the Thread.join() did not work, duration="+duration, duration < 9000);
- }
-
- /**
- * Test EXEC-44 (https://issues.apache.org/jira/browse/EXEC-44).
- *
- * Because the ExecuteWatchdog is the only way to destroy asynchronous
- * processes, it should be possible to set it to an infinite timeout,
- * for processes which should not timeout, but manually destroyed
- * under some circumstances.
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec44() throws Exception {
-
- final CommandLine cl = new CommandLine(foreverTestScript);
- final DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
- final ExecuteWatchdog watchdog = new ExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT);
-
- exec.setWatchdog(watchdog);
- exec.execute(cl, resultHandler);
-
- // wait for script to run
- Thread.sleep(5000);
- assertTrue("The watchdog is watching the process", watchdog.isWatching());
-
- // terminate it
- watchdog.destroyProcess();
- assertTrue("The watchdog has killed the process", watchdog.killedProcess());
- assertFalse("The watchdog is no longer watching any process", watchdog.isWatching());
- }
-
- /**
- * Test EXEC-49 (https://issues.apache.org/jira/browse/EXEC-49).
- *
- * The issue was detected when trying to capture stdout/stderr with a PipedOutputStream and
- * then pass that to a PipedInputStream. The following code will produce the error.
- * The reason for the error is the PipedOutputStream is not being closed correctly,
- * causing the PipedInputStream to break.
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec49_1() throws Exception {
-
- if (OS.isFamilyUnix()) {
-
- final CommandLine cl = CommandLine.parse("/bin/ls");
- cl.addArgument("/opt");
-
- // redirect stdout/stderr to pipedOutputStream
- final PipedOutputStream pipedOutputStream = new PipedOutputStream();
- final PumpStreamHandler psh = new PumpStreamHandler(pipedOutputStream);
- exec.setStreamHandler(psh);
-
- // start an asynchronous process to enable the main thread
- System.out.println("Preparing to execute process - commandLine=" + cl.toString());
- final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
- exec.execute(cl, handler);
- System.out.println("Process spun off successfully - process=" + cl.getExecutable());
-
- int x;
- final PipedInputStream pis = new PipedInputStream(pipedOutputStream);
- while ((x = pis.read()) >= 0) {
- // System.out.println("pis.available() " + pis.available());
- // System.out.println("x " + x);
- }
- pis.close();
-
- handler.waitFor();
- }
- }
-
- /**
- * Test EXEC-49 (https://issues.apache.org/jira/browse/EXEC-49).
- *
- * The issue was detected when trying to capture stdout with a PipedOutputStream and
- * then pass that to a PipedInputStream. The following code will produce the error.
- * The reason for the error is the PipedOutputStream is not being closed correctly,
- * causing the PipedInputStream to break.
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec49_2() throws Exception {
-
- if (OS.isFamilyUnix()) {
-
- final CommandLine cl = CommandLine.parse("/bin/ls");
- cl.addArgument("/opt");
-
- // redirect only stdout to pipedOutputStream
- final PipedOutputStream pipedOutputStream = new PipedOutputStream();
- final PumpStreamHandler psh = new PumpStreamHandler(pipedOutputStream, new ByteArrayOutputStream());
- exec.setStreamHandler(psh);
-
- // start an asynchronous process to enable the main thread
- System.out.println("Preparing to execute process - commandLine=" + cl.toString());
- final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
- exec.execute(cl, handler);
- System.out.println("Process spun off successfully - process=" + cl.getExecutable());
-
- int x;
- final PipedInputStream pis = new PipedInputStream(pipedOutputStream);
- while ((x = pis.read()) >= 0) {
- // System.out.println("pis.available() " + pis.available());
- // System.out.println("x " + x);
- }
- pis.close();
-
- handler.waitFor();
- }
- }
-
- /**
- * Test EXEC-57 (https://issues.apache.org/jira/browse/EXEC-57).
- *
- * DefaultExecutor.execute() does not return even if child process terminated - in this
- * case the child process hangs because the grand children is connected to stdout & stderr
- * and is still running. As work-around a stop timeout is used for the PumpStreamHandler
- * to ensure that the caller does not block forever but if the stop timeout is exceeded
- * an ExecuteException is thrown to notify the caller.
- *
- * @throws Exception the test failed
- */
- @Test
- public void testExec_57() throws IOException {
-
- if (!OS.isFamilyUnix()) {
- System.err.println("The test 'testSyncInvocationOfBackgroundProcess' does not support the following OS : " + System.getProperty("os.name"));
- return;
- }
-
- final CommandLine cmdLine = new CommandLine("sh").addArgument("-c").addArgument(testDir + "/invoker.sh", false);
-
- final DefaultExecutor executor = new DefaultExecutor();
- final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err);
-
- // Without this timeout current thread will be blocked
- // even if command we'll invoke will terminate immediately.
- pumpStreamHandler.setStopTimeout(2000);
- executor.setStreamHandler(pumpStreamHandler);
- final long startTime = System.currentTimeMillis();
-
- System.out.println("Executing " + cmdLine);
-
- try {
- executor.execute(cmdLine);
- }
- catch (final ExecuteException e) {
- final long duration = System.currentTimeMillis() - startTime;
- System.out.println("Process completed in " + duration +" millis; above is its output");
- return;
- }
-
- fail("Expecting an ExecuteException");
- }
-
- /**
- * Test EXEC-60 (https://issues.apache.org/jira/browse/EXEC-60).
- *
- * Possible deadlock when a process is terminating at the same time its timing out. Please
- * note that a successful test is no proof that the issues was indeed fixed.
- *
- */
- @Test
- public void testExec_60() throws Exception {
-
- final int start = 0;
- final int seconds = 1;
- final int offsetMultiplier = 1;
- final int maxRetries = 180;
- int processTerminatedCounter = 0;
- int watchdogKilledProcessCounter = 0;
- final CommandLine cmdLine = new CommandLine(pingScript);
- cmdLine.addArgument(Integer.toString(seconds + 1)); // need to add "1" to wait the requested number of seconds
-
- final long startTime = System.currentTimeMillis();
- for (int offset = start; offset <= maxRetries; offset++) {
- // wait progressively longer for process to complete
- // tricky to get this test right. We want to try and catch the process while it is terminating,
- // so we increase the timeout gradually until the test terminates normally.
- // However if the increase is too gradual, we never wait long enough for any test to exit normally
- final ExecuteWatchdog watchdog = new ExecuteWatchdog(seconds * 1000 + offset * offsetMultiplier);
- exec.setWatchdog(watchdog);
- try {
- exec.execute(cmdLine);
- processTerminatedCounter++;
-// System.out.println(offset + ": process has terminated: " + watchdog.killedProcess());
- if (processTerminatedCounter > 5) {
- break;
- }
- } catch (final ExecuteException ex) {
-// System.out.println(offset + ": process was killed: " + watchdog.killedProcess());
- assertTrue("Watchdog killed the process", watchdog.killedProcess());
- watchdogKilledProcessCounter++;
- }
- }
-
- final long avg = (System.currentTimeMillis() - startTime) /
- (watchdogKilledProcessCounter+processTerminatedCounter);
- System.out.println("Processes terminated: "+processTerminatedCounter+" killed: "+watchdogKilledProcessCounter
- +" Multiplier: "+offsetMultiplier+" MaxRetries: "+maxRetries+" Elapsed (avg ms): "+avg);
- assertTrue("Not a single process terminated on its own", processTerminatedCounter > 0);
- assertTrue("Not a single process was killed by the watch dog", watchdogKilledProcessCounter > 0);
- }
-
- // ======================================================================
// === Long running tests
// ======================================================================
Added: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec33Test.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec33Test.java?rev=1557130&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec33Test.java (added)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec33Test.java Fri Jan 10 14:23:40 2014
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.exec.issues;
+
+import static org.junit.Assert.assertFalse;
+
+import java.io.File;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.exec.TestUtil;
+import org.junit.Test;
+
+/**
+ * Test the patch for EXEC-33 (https://issues.apache.org/jira/browse/EXEC-33)
+ *
+ * PumpStreamHandler hangs if System.in is redirect to process input stream .
+ *
+ * @version $Id$
+ */
+public class Exec33Test {
+
+ private final Executor exec = new DefaultExecutor();
+ private final File testDir = new File("src/test/scripts");
+ private final File testScript = TestUtil.resolveScriptForOS(testDir + "/test");
+
+ @Test
+ public void testExec33() throws Exception {
+ final CommandLine cl = new CommandLine(testScript);
+ final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err, System.in);
+ final DefaultExecutor executor = new DefaultExecutor();
+ executor.setStreamHandler(pumpStreamHandler);
+ final int exitValue = executor.execute(cl);
+ assertFalse(exec.isFailure(exitValue));
+ }
+}
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec33Test.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec33Test.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec34Test.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec34Test.java?rev=1557130&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec34Test.java (added)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec34Test.java Fri Jan 10 14:23:40 2014
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.exec.issues;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecuteResultHandler;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteWatchdog;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.TestUtil;
+import org.junit.Test;
+
+/**
+ * EXEC-34 https://issues.apache.org/jira/browse/EXEC-34
+ *
+ * @version $Id$
+ */
+public class Exec34Test {
+
+ private final Executor exec = new DefaultExecutor();
+ private final File testDir = new File("src/test/scripts");
+ private final File pingScript = TestUtil.resolveScriptForOS(testDir + "/ping");
+
+ /**
+ *
+ * Race condition prevent watchdog working using ExecuteStreamHandler.
+ * The test fails because when watchdog.destroyProcess() is invoked the
+ * external process is not bound to the watchdog yet.
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec34_1() throws Exception {
+
+ final CommandLine cmdLine = new CommandLine(pingScript);
+ cmdLine.addArgument("10"); // sleep 10 secs
+
+ final ExecuteWatchdog watchdog = new ExecuteWatchdog(Integer.MAX_VALUE);
+ final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
+ exec.setWatchdog(watchdog);
+ exec.execute(cmdLine, handler);
+ assertTrue(watchdog.isWatching());
+ watchdog.destroyProcess();
+ assertTrue("Watchdog should have killed the process",watchdog.killedProcess());
+ assertFalse("Watchdog is no longer watching the process",watchdog.isWatching());
+ }
+
+ /**
+ * Some user waited for an asynchronous process using watchdog.isWatching() which
+ * is now properly implemented using <code>DefaultExecuteResultHandler</code>.
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec34_2() throws Exception {
+
+ final CommandLine cmdLine = new CommandLine(pingScript);
+ cmdLine.addArgument("10"); // sleep 10 secs
+
+ final ExecuteWatchdog watchdog = new ExecuteWatchdog(5000);
+ final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
+ exec.setWatchdog(watchdog);
+ exec.execute(cmdLine, handler);
+ handler.waitFor();
+ assertTrue("Process has exited", handler.hasResult());
+ assertNotNull("Process was aborted", handler.getException());
+ assertTrue("Watchdog should have killed the process", watchdog.killedProcess());
+ assertFalse("Watchdog is no longer watching the process", watchdog.isWatching());
+ }
+}
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec34Test.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec34Test.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec36Test.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec36Test.java?rev=1557130&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec36Test.java (added)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec36Test.java Fri Jan 10 14:23:40 2014
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.exec.issues;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.OS;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.exec.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test EXEC-36 see https://issues.apache.org/jira/browse/EXEC-36
+ *
+ * @version $Id$
+ */
+public class Exec36Test {
+
+
+ private final Executor exec = new DefaultExecutor();
+ private final File testDir = new File("src/test/scripts");
+ private final File printArgsScript = TestUtil.resolveScriptForOS(testDir + "/printargs");
+
+ private ByteArrayOutputStream baos;
+
+ @Before
+ public void setUp() throws Exception {
+ // prepare a ready to Executor
+ this.baos = new ByteArrayOutputStream();
+ this.exec.setStreamHandler(new PumpStreamHandler(baos, baos));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ this.baos.close();
+ }
+
+ /**
+ *
+ * Original example from Kai Hu which only can be tested on Unix
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec36_1() throws Exception {
+
+ if (OS.isFamilyUnix()) {
+
+ CommandLine cmdl;
+
+ /**
+ * ./script/jrake cruise:publish_installers INSTALLER_VERSION=unstable_2_1 \
+ * INSTALLER_PATH="/var/lib/ cruise-agent/installers" INSTALLER_DOWNLOAD_SERVER='something' WITHOUT_HELP_DOC=true
+ */
+
+ final String expected = "./script/jrake\n" +
+ "cruise:publish_installers\n" +
+ "INSTALLER_VERSION=unstable_2_1\n" +
+ "INSTALLER_PATH=\"/var/lib/ cruise-agent/installers\"\n" +
+ "INSTALLER_DOWNLOAD_SERVER='something'\n" +
+ "WITHOUT_HELP_DOC=true";
+
+ cmdl = new CommandLine(printArgsScript);
+ cmdl.addArgument("./script/jrake", false);
+ cmdl.addArgument("cruise:publish_installers", false);
+ cmdl.addArgument("INSTALLER_VERSION=unstable_2_1", false);
+ cmdl.addArgument("INSTALLER_PATH=\"/var/lib/ cruise-agent/installers\"", false);
+ cmdl.addArgument("INSTALLER_DOWNLOAD_SERVER='something'", false);
+ cmdl.addArgument("WITHOUT_HELP_DOC=true", false);
+
+ final int exitValue = exec.execute(cmdl);
+ final String result = baos.toString().trim();
+ assertFalse(exec.isFailure(exitValue));
+ assertEquals(expected, result);
+ }
+ else {
+ System.err.println("The test 'testExec36_1' does not support the following OS : " + System.getProperty("os.name"));
+ return;
+ }
+ }
+
+ /**
+ * Test a complex real example found at
+ * http://blogs.msdn.com/b/astebner/archive/2005/12/13/503471.aspx
+ *
+ * The command line is so weird that it even falls apart under Windows
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec36_2() throws Exception {
+
+ String expected;
+
+ // the original command line
+ // dotnetfx.exe /q:a /c:"install.exe /l ""\Documents and Settings\myusername\Local Settings\Temp\netfx.log"" /q"
+
+ if (OS.isFamilyWindows()) {
+ expected = "dotnetfx.exe\n" +
+ "/q:a\n" +
+ "/c:\"install.exe /l \"\"\\Documents and Settings\\myusername\\Local Settings\\Temp\\netfx.log\"\" /q\"";
+ }
+ else if (OS.isFamilyUnix()) {
+ expected = "dotnetfx.exe\n" +
+ "/q:a\n" +
+ "/c:\"install.exe /l \"\"/Documents and Settings/myusername/Local Settings/Temp/netfx.log\"\" /q\"";
+ }
+ else {
+ System.err.println("The test 'testExec36_3' does not support the following OS : " + System.getProperty("os.name"));
+ return;
+ }
+
+ CommandLine cmdl;
+ final File file = new File("/Documents and Settings/myusername/Local Settings/Temp/netfx.log");
+ final Map map = new HashMap();
+ map.put("FILE", file);
+
+ cmdl = new CommandLine(printArgsScript);
+ cmdl.setSubstitutionMap(map);
+ cmdl.addArgument("dotnetfx.exe", false);
+ cmdl.addArgument("/q:a", false);
+ cmdl.addArgument("/c:\"install.exe /l \"\"${FILE}\"\" /q\"", false);
+
+ final int exitValue = exec.execute(cmdl);
+ final String result = baos.toString().trim();
+ assertFalse(exec.isFailure(exitValue));
+
+ if (OS.isFamilyUnix()) {
+ // the parameters fall literally apart under Windows - need to disable the check for Win32
+ assertEquals(expected, result);
+ }
+ }
+
+}
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec36Test.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec41Test.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec41Test.java?rev=1557130&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec41Test.java (added)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec41Test.java Fri Jan 10 14:23:40 2014
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.exec.issues;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.ExecuteWatchdog;
+import org.apache.commons.exec.OS;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.exec.TestUtil;
+import org.junit.Test;
+
+/**
+ * Test the patch for EXEC-41 (https://issues.apache.org/jira/browse/EXEC-41).
+ *
+ * @version $Id$
+ */
+public class Exec41Test {
+
+ private final File testDir = new File("src/test/scripts");
+ private final File pingScript = TestUtil.resolveScriptForOS(testDir + "/ping");
+
+ /**
+ *
+ * When a process runs longer than allowed by a configured watchdog's
+ * timeout, the watchdog tries to destroy it and then DefaultExecutor
+ * tries to clean up by joining with all installed pump stream threads.
+ * Problem is, that sometimes the native process doesn't die and thus
+ * streams aren't closed and the stream threads do not complete.
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec41WithStreams() throws Exception {
+
+ CommandLine cmdLine;
+
+ if (OS.isFamilyWindows()) {
+ cmdLine = CommandLine.parse("ping.exe -n 10 -w 1000 127.0.0.1");
+ } else if ("HP-UX".equals(System.getProperty("os.name"))) {
+ // see EXEC-52 - option must appear after the hostname!
+ cmdLine = CommandLine.parse("ping 127.0.0.1 -n 10");
+ } else if (OS.isFamilyUnix()) {
+ cmdLine = CommandLine.parse("ping -c 10 127.0.0.1");
+ } else {
+ System.err.println("The test 'testExec41WithStreams' does not support the following OS : "
+ + System.getProperty("os.name"));
+ return;
+ }
+
+ final DefaultExecutor executor = new DefaultExecutor();
+ final ExecuteWatchdog watchdog = new ExecuteWatchdog(2 * 1000); // allow process no more than 2 secs
+ final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err);
+ // this method was part of the patch I reverted
+ // pumpStreamHandler.setAlwaysWaitForStreamThreads(false);
+
+ executor.setWatchdog(watchdog);
+ executor.setStreamHandler(pumpStreamHandler);
+
+ final long startTime = System.currentTimeMillis();
+
+ try {
+ executor.execute(cmdLine);
+ } catch (final ExecuteException e) {
+ // nothing to do
+ }
+
+ final long duration = System.currentTimeMillis() - startTime;
+
+ System.out.println("Process completed in " + duration + " millis; below is its output");
+
+ if (watchdog.killedProcess()) {
+ System.out.println("Process timed out and was killed by watchdog.");
+ }
+
+ assertTrue("The process was killed by the watchdog", watchdog.killedProcess());
+ assertTrue("Skipping the Thread.join() did not work", duration < 9000);
+ }
+
+ /**
+ * Test EXEC-41 with a disabled PumpStreamHandler to check if we could return
+ * immediately after killing the process (no streams implies no blocking
+ * stream pumper threads). But you have to be 100% sure that the subprocess
+ * is not writing to 'stdout' and 'stderr'.
+ *
+ * For this test we are using the batch file - under Windows the 'ping'
+ * process can't be killed (not supported by Win32) and will happily
+ * run the given time (e.g. 10 seconds) even hwen the batch file is already
+ * killed.
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec41WithoutStreams() throws Exception {
+
+ final CommandLine cmdLine = new CommandLine(pingScript);
+ cmdLine.addArgument("10"); // sleep 10 secs
+ final DefaultExecutor executor = new DefaultExecutor();
+ final ExecuteWatchdog watchdog = new ExecuteWatchdog(2*1000); // allow process no more than 2 secs
+
+ // create a custom "PumpStreamHandler" doing no pumping at all
+ final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(null, null, null);
+
+ executor.setWatchdog(watchdog);
+ executor.setStreamHandler(pumpStreamHandler);
+
+ final long startTime = System.currentTimeMillis();
+
+ try {
+ executor.execute(cmdLine);
+ } catch (final ExecuteException e) {
+ System.out.println(e);
+ }
+
+ final long duration = System.currentTimeMillis() - startTime;
+
+ System.out.println("Process completed in " + duration +" millis; below is its output");
+
+ if (watchdog.killedProcess()) {
+ System.out.println("Process timed out and was killed.");
+ }
+
+ assertTrue("The process was killed by the watchdog", watchdog.killedProcess());
+ assertTrue("Skipping the Thread.join() did not work, duration="+duration, duration < 9000);
+ }
+}
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec41Test.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec41Test.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec44Test.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec44Test.java?rev=1557130&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec44Test.java (added)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec44Test.java Fri Jan 10 14:23:40 2014
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.exec.issues;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecuteResultHandler;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteWatchdog;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.TestUtil;
+import org.junit.Test;
+
+/**
+ * Test EXEC-44 (https://issues.apache.org/jira/browse/EXEC-44).
+ *
+ * @version $Id$
+ */
+public class Exec44Test {
+
+ private final Executor exec = new DefaultExecutor();
+ private final File testDir = new File("src/test/scripts");
+ private final File foreverTestScript = TestUtil.resolveScriptForOS(testDir + "/forever");
+
+ /**
+ *
+ * Because the ExecuteWatchdog is the only way to destroy asynchronous
+ * processes, it should be possible to set it to an infinite timeout,
+ * for processes which should not timeout, but manually destroyed
+ * under some circumstances.
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec44() throws Exception {
+
+ final CommandLine cl = new CommandLine(foreverTestScript);
+ final DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
+ final ExecuteWatchdog watchdog = new ExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT);
+
+ exec.setWatchdog(watchdog);
+ exec.execute(cl, resultHandler);
+
+ // wait for script to run
+ Thread.sleep(5000);
+ assertTrue("The watchdog is watching the process", watchdog.isWatching());
+
+ // terminate it
+ watchdog.destroyProcess();
+ assertTrue("The watchdog has killed the process", watchdog.killedProcess());
+ assertFalse("The watchdog is no longer watching any process", watchdog.isWatching());
+ }
+}
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec44Test.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec44Test.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec49Test.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec49Test.java?rev=1557130&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec49Test.java (added)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec49Test.java Fri Jan 10 14:23:40 2014
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.exec.issues;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecuteResultHandler;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.OS;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.junit.Test;
+
+/**
+ * Test EXEC-44 (https://issues.apache.org/jira/browse/EXEC-44).
+ *
+ * @version $Id$
+ */
+public class Exec49Test {
+
+ private final Executor exec = new DefaultExecutor();
+
+ /**
+ * The issue was detected when trying to capture stdout/stderr with a PipedOutputStream and
+ * then pass that to a PipedInputStream. The following code will produce the error.
+ * The reason for the error is the PipedOutputStream is not being closed correctly,
+ * causing the PipedInputStream to break.
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec49_1() throws Exception {
+
+ if (OS.isFamilyUnix()) {
+
+ final CommandLine cl = CommandLine.parse("/bin/ls");
+ cl.addArgument("/opt");
+
+ // redirect stdout/stderr to pipedOutputStream
+ final PipedOutputStream pipedOutputStream = new PipedOutputStream();
+ final PumpStreamHandler psh = new PumpStreamHandler(pipedOutputStream);
+ exec.setStreamHandler(psh);
+
+ // start an asynchronous process to enable the main thread
+ System.out.println("Preparing to execute process - commandLine=" + cl.toString());
+ final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
+ exec.execute(cl, handler);
+ System.out.println("Process spun off successfully - process=" + cl.getExecutable());
+
+ int x;
+ final PipedInputStream pis = new PipedInputStream(pipedOutputStream);
+ while ((x = pis.read()) >= 0) {
+ // System.out.println("pis.available() " + pis.available());
+ // System.out.println("x " + x);
+ }
+ pis.close();
+
+ handler.waitFor();
+ }
+ }
+
+ /**
+ * The issue was detected when trying to capture stdout with a PipedOutputStream and
+ * then pass that to a PipedInputStream. The following code will produce the error.
+ * The reason for the error is the PipedOutputStream is not being closed correctly,
+ * causing the PipedInputStream to break.
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec49_2() throws Exception {
+
+ if (OS.isFamilyUnix()) {
+
+ final CommandLine cl = CommandLine.parse("/bin/ls");
+ cl.addArgument("/opt");
+
+ // redirect only stdout to pipedOutputStream
+ final PipedOutputStream pipedOutputStream = new PipedOutputStream();
+ final PumpStreamHandler psh = new PumpStreamHandler(pipedOutputStream, new ByteArrayOutputStream());
+ exec.setStreamHandler(psh);
+
+ // start an asynchronous process to enable the main thread
+ System.out.println("Preparing to execute process - commandLine=" + cl.toString());
+ final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
+ exec.execute(cl, handler);
+ System.out.println("Process spun off successfully - process=" + cl.getExecutable());
+
+ int x;
+ final PipedInputStream pis = new PipedInputStream(pipedOutputStream);
+ while ((x = pis.read()) >= 0) {
+ // System.out.println("pis.available() " + pis.available());
+ // System.out.println("x " + x);
+ }
+ pis.close();
+
+ handler.waitFor();
+ }
+ }
+
+}
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec49Test.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec49Test.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java?rev=1557130&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java (added)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java Fri Jan 10 14:23:40 2014
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.exec.issues;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.OS;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.exec.TestUtil;
+import org.junit.Test;
+
+/**
+ * Test EXEC-57 (https://issues.apache.org/jira/browse/EXEC-57).
+ *
+ * @version $Id$
+ */
+public class Exec57Test {
+
+ private final File testDir = new File("src/test/scripts");
+
+
+ /**
+ *
+ * DefaultExecutor.execute() does not return even if child process terminated - in this
+ * case the child process hangs because the grand children is connected to stdout & stderr
+ * and is still running. As work-around a stop timeout is used for the PumpStreamHandler
+ * to ensure that the caller does not block forever but if the stop timeout is exceeded
+ * an ExecuteException is thrown to notify the caller.
+ *
+ * @throws Exception the test failed
+ */
+ @Test
+ public void testExec_57() throws IOException {
+
+ if (!OS.isFamilyUnix()) {
+ System.err.println("The test 'testSyncInvocationOfBackgroundProcess' does not support the following OS : " + System.getProperty("os.name"));
+ return;
+ }
+
+ final CommandLine cmdLine = new CommandLine("sh").addArgument("-c").addArgument(testDir + "/invoker.sh", false);
+
+ final DefaultExecutor executor = new DefaultExecutor();
+ final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err);
+
+ // Without this timeout current thread will be blocked
+ // even if command we'll invoke will terminate immediately.
+ pumpStreamHandler.setStopTimeout(2000);
+ executor.setStreamHandler(pumpStreamHandler);
+ final long startTime = System.currentTimeMillis();
+
+ System.out.println("Executing " + cmdLine);
+
+ try {
+ executor.execute(cmdLine);
+ }
+ catch (final ExecuteException e) {
+ final long duration = System.currentTimeMillis() - startTime;
+ System.out.println("Process completed in " + duration +" millis; above is its output");
+ return;
+ }
+
+ fail("Expecting an ExecuteException");
+ }
+}
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec60Test.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec60Test.java?rev=1557130&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec60Test.java (added)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec60Test.java Fri Jan 10 14:23:40 2014
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.exec.issues;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.ExecuteWatchdog;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.TestUtil;
+import org.junit.Test;
+
+/**
+ * Test EXEC-60 (https://issues.apache.org/jira/browse/EXEC-60).
+ *
+ * @version $Id$
+ */
+public class Exec60Test {
+
+ private final Executor exec = new DefaultExecutor();
+ private final File testDir = new File("src/test/scripts");
+ private final File pingScript = TestUtil.resolveScriptForOS(testDir + "/ping");
+
+ /**
+ * Possible deadlock when a process is terminating at the same time its timing out. Please
+ * note that a successful test is no proof that the issues was indeed fixed.
+ */
+ @Test
+ public void testExec_60() throws Exception {
+
+ final int start = 0;
+ final int seconds = 1;
+ final int offsetMultiplier = 1;
+ final int maxRetries = 180;
+ int processTerminatedCounter = 0;
+ int watchdogKilledProcessCounter = 0;
+ final CommandLine cmdLine = new CommandLine(pingScript);
+ cmdLine.addArgument(Integer.toString(seconds + 1)); // need to add "1" to wait the requested number of seconds
+
+ final long startTime = System.currentTimeMillis();
+ for (int offset = start; offset <= maxRetries; offset++) {
+ // wait progressively longer for process to complete
+ // tricky to get this test right. We want to try and catch the process while it is terminating,
+ // so we increase the timeout gradually until the test terminates normally.
+ // However if the increase is too gradual, we never wait long enough for any test to exit normally
+ final ExecuteWatchdog watchdog = new ExecuteWatchdog(seconds * 1000 + offset * offsetMultiplier);
+ exec.setWatchdog(watchdog);
+ try {
+ exec.execute(cmdLine);
+ processTerminatedCounter++;
+// System.out.println(offset + ": process has terminated: " + watchdog.killedProcess());
+ if (processTerminatedCounter > 5) {
+ break;
+ }
+ } catch (final ExecuteException ex) {
+// System.out.println(offset + ": process was killed: " + watchdog.killedProcess());
+ assertTrue("Watchdog killed the process", watchdog.killedProcess());
+ watchdogKilledProcessCounter++;
+ }
+ }
+
+ final long avg = (System.currentTimeMillis() - startTime) /
+ (watchdogKilledProcessCounter+processTerminatedCounter);
+ System.out.println("Processes terminated: " + processTerminatedCounter + " killed: " + watchdogKilledProcessCounter
+ + " Multiplier: " + offsetMultiplier + " MaxRetries: " + maxRetries + " Elapsed (avg ms): " + avg);
+ assertTrue("Not a single process terminated on its own", processTerminatedCounter > 0);
+ assertTrue("Not a single process was killed by the watch dog", watchdogKilledProcessCounter > 0);
+ }
+}
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec60Test.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec60Test.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL