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