commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sgoes...@apache.org
Subject svn commit: r949870 - in /commons/proper/exec/trunk/src: changes/changes.xml main/java/org/apache/commons/exec/ExecuteWatchdog.java test/java/org/apache/commons/exec/DefaultExecutorTest.java
Date Mon, 31 May 2010 21:33:23 GMT
Author: sgoeschl
Date: Mon May 31 21:33:22 2010
New Revision: 949870

URL: http://svn.apache.org/viewvc?rev=949870&view=rev
Log:
[EXEC-44] ExecuteWatchdog accepts now an 'INFINITE_TIMEOUT'

Modified:
    commons/proper/exec/trunk/src/changes/changes.xml
    commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java
    commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java

Modified: commons/proper/exec/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/changes/changes.xml?rev=949870&r1=949869&r2=949870&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/changes/changes.xml (original)
+++ commons/proper/exec/trunk/src/changes/changes.xml Mon May 31 21:33:22 2010
@@ -23,6 +23,13 @@
     <author email="sgoeschl@apache.org">Siegfried Goeschl</author>
   </properties>
   <body>
+    <release version="1.0.2-SNAPSHOT" date="as in SVN" description="Maintenance Release">
+      <action dev="sgoeschl" type="fix" date="2010-05-31" issue="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.
+      </action>    
+    </release>
     <release version="1.0.1" date="2009-09-28" description="Maintenance Release">
       <action dev="henrib" type="fix" date="2009-09-25" issue="EXEC-33">
         On a Mac, the unit tests never finish. Culprit is InputStreamPumper which 

Modified: commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java?rev=949870&r1=949869&r2=949870&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java (original)
+++ commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java Mon
May 31 21:33:22 2010
@@ -20,25 +20,36 @@ package org.apache.commons.exec;
 
 /**
  * Destroys a process running for too long. For example:
- * 
+ *
  * <pre>
  * ExecuteWatchdog watchdog = new ExecuteWatchdog(30000);
- * Execute exec = new Execute(myloghandler, watchdog);
+ * Executer exec = new Executer(myloghandler, watchdog);
  * exec.setCommandLine(mycmdline);
  * int exitvalue = exec.execute();
  * if (Execute.isFailure(exitvalue) &amp;&amp; watchdog.killedProcess()) {
  *     // it was killed on purpose by the watchdog
  * }
  * </pre>
- * 
+ *
+ * When starting an asynchronous process than 'ExecuteWatchdog' is the
+ * keeper of the process handle. In some cases it is useful not to define
+ * a timeout (and pass 'INFINITE_TIMEOUT') and to kill the process explicitely
+ * using 'destroyProcess()'.
+ *
  * @see org.apache.commons.exec.Executor
  * @see org.apache.commons.exec.Watchdog
  */
 public class ExecuteWatchdog implements TimeoutObserver {
 
+    /** The marker for an infinite timeout */
+    public static final long INFINITE_TIMEOUT = -1;
+    
     /** The process to execute and watch for duration. */
     private Process process;
 
+    /** Is a user-supplied timeout in use */
+    private boolean hasWatchdog;
+
     /** Say whether or not the watchdog is currently monitoring a process. */
     private boolean watch;
 
@@ -56,13 +67,19 @@ public class ExecuteWatchdog implements 
      * 
      * @param timeout
      *            the timeout for the process in milliseconds. It must be
-     *            greater than 0.
+     *            greater than 0 or 'INFINITE_TIMEOUT'
      */
     public ExecuteWatchdog(final long timeout) {
         this.killedProcess = false;
         this.watch = false;
-        this.watchdog = new Watchdog(timeout);
-        this.watchdog.addTimeoutObserver(this);
+        this.hasWatchdog = (timeout != INFINITE_TIMEOUT);
+        if(this.hasWatchdog) {
+            this.watchdog = new Watchdog(timeout);
+            this.watchdog.addTimeoutObserver(this);
+        }
+        else {
+            this.watchdog = null;
+        }
     }
 
     /**
@@ -85,7 +102,9 @@ public class ExecuteWatchdog implements 
         this.killedProcess = false;
         this.watch = true;
         this.process = process;
-        watchdog.start();
+        if(this.hasWatchdog) {
+            watchdog.start();
+        }
     }
 
     /**
@@ -93,7 +112,9 @@ public class ExecuteWatchdog implements 
      * object.
      */
     public synchronized void stop() {
-        watchdog.stop();
+        if(hasWatchdog) {
+            watchdog.stop();
+        }
         watch = false;
         process = null;
     }
@@ -102,7 +123,7 @@ public class ExecuteWatchdog implements 
      * Destroys the running process manually.
      */
     public synchronized void destroyProcess() {
-        this.timeoutOccured(new Watchdog(1));
+        this.timeoutOccured(null);
         this.stop();
     }
 

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=949870&r1=949869&r2=949870&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
Mon May 31 21:33:22 2010
@@ -153,7 +153,9 @@ public class DefaultExecutorTest extends
 
     /**
      * Start a async process and terminate it manually before the
-     * wacthdog timeout occurs. 
+     * watchdog timeout occurs.
+     *
+     * @throws Exception the test failed 
      */
     public void testExecuteAsyncWithTimelyUserTermination() throws Exception {
         CommandLine cl = new CommandLine(foreverTestScript);
@@ -163,14 +165,18 @@ public class DefaultExecutorTest extends
         exec.execute(cl, handler);
         // wait for script to run
         Thread.sleep(2000);
-        // teminate it
+        assertTrue("Watchdog should watch the process", watchdog.isWatching());
+        // terminate it
         watchdog.destroyProcess();
         assertTrue("Watchdog should have killed the process",watchdog.killedProcess());
+        assertFalse(watchdog.isWatching());
     }
 
     /**
      * Start a async process and try to terminate it manually but
      * the process was already terminated by the watchdog.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteAsyncWithTooLateUserTermination() throws Exception {
         CommandLine cl = new CommandLine(foreverTestScript);
@@ -183,11 +189,14 @@ public class DefaultExecutorTest extends
         // try to terminate the already terminated process
         watchdog.destroyProcess();
         assertTrue("Watchdog should have killed the process already",watchdog.killedProcess());
+        assertFalse(watchdog.isWatching());
     }
 
     /**
-     * Start a scipt looping forever and check if the ExecuteWatchdog
+     * Start a script looping forever and check if the ExecuteWatchdog
      * kicks in killing the run away process.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteWatchdog() throws Exception {
         long timeout = 10000;
@@ -214,6 +223,8 @@ public class DefaultExecutorTest extends
     /**
      * Try to start an non-existing application which should result
      * in an exception.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteNonExistingApplication() throws Exception {
         CommandLine cl = new CommandLine(nonExistingTestScript);
@@ -231,6 +242,8 @@ public class DefaultExecutorTest extends
     /**
      * Try to start an non-existing application asynchronously which should result
      * in an exception.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteAsyncWithNonExistingApplication() throws Exception {
         CommandLine cl = new CommandLine(nonExistingTestScript);
@@ -244,6 +257,8 @@ public class DefaultExecutorTest extends
     /**
      * Start any processes in a loop to make sure that we do
      * not leave any handles/resources open.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteStability() throws Exception {
         for(int i=0; i<1000; i++) {
@@ -260,6 +275,8 @@ public class DefaultExecutorTest extends
     /**
      * Invoke the error script but define that the ERROR_STATUS is a good
      * exit value and therefore no exception should be thrown.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteWithCustomExitValue1() throws Exception {
         exec.setExitValue(ERROR_STATUS);
@@ -270,6 +287,8 @@ public class DefaultExecutorTest extends
     /**
      * Invoke the error script but define that SUCCESS_STATUS is a bad
      * exit value and therefore an exception should be thrown.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteWithCustomExitValue2() throws Exception {
         CommandLine cl = new CommandLine(errorTestScript);
@@ -285,6 +304,8 @@ public class DefaultExecutorTest extends
 
     /**
      * Test the proper handling of ProcessDestroyer for an synchronous process.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteWithProcessDestroyer() throws Exception {
 
@@ -306,7 +327,9 @@ public class DefaultExecutorTest extends
     /**
      * Test the proper handling of ProcessDestroyer for an asynchronous process.
      * Since we do not terminate the process it will be terminated in the
-     * ShutdownHookProcessDestroyer implementation
+     * ShutdownHookProcessDestroyer implementation.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteAsyncWithProcessDestroyer() throws Exception {
 
@@ -329,7 +352,7 @@ public class DefaultExecutorTest extends
       assertEquals("Process destroyer size should be 1",1,processDestroyer.size());
       assertTrue("Process destroyer should exist as shutdown hook",processDestroyer.isAddedAsShutdownHook());
 
-      // teminate it and the process destroyer is detached
+      // terminate it and the process destroyer is detached
       watchdog.destroyProcess();
       assertTrue(watchdog.killedProcess());
       Thread.sleep(100);
@@ -356,6 +379,8 @@ public class DefaultExecutorTest extends
      * the "redirect" script reads all lines from stdin and prints
      * them on stdout. Furthermore the script prints a status
      * message on stderr.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteWithRedirectedStreams() throws Exception
     {
@@ -375,6 +400,8 @@ public class DefaultExecutorTest extends
 
     /**
      * Start a process and connect stdin, stdout and stderr (see EXEC-33).
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteWithStdin() throws Exception
     {
@@ -388,6 +415,8 @@ public class DefaultExecutorTest extends
 
      /**
       * Start a process and connect stdout and stderr.
+      *
+      * @throws Exception the test failed
       */
      public void testExecuteWithStdOutErr() throws Exception
      {
@@ -401,6 +430,8 @@ public class DefaultExecutorTest extends
 
      /**
       * Start a process and connect it to no stream.
+      *
+      * @throws Exception the test failed
       */
      public void testExecuteWithNullOutErr() throws Exception
      {
@@ -414,6 +445,8 @@ public class DefaultExecutorTest extends
 
      /**
       * Start a process and connect out and err to a file.
+      *
+      * @throws Exception the test failed
       */
      public void testExecuteWithRedirectOutErr() throws Exception
      {
@@ -444,6 +477,8 @@ public class DefaultExecutorTest extends
      * ErrorStreamHandler.stop will NOT join the stream threads and
      * DefaultExecutor will NOT attempt to close the streams, so the
      * executor's thread won't get stuck.
+     *
+     * @throws Exception the test failed
      */
     public void testExec41() throws Exception {
 
@@ -452,8 +487,6 @@ public class DefaultExecutorTest extends
 		DefaultExecutor executor = new DefaultExecutor();
 		ExecuteWatchdog watchdog = new ExecuteWatchdog(2*1000); // allow process no more than 2
secs
 		executor.setWatchdog(watchdog);
-		//ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		//executor.setStreamHandler(new PumpStreamHandler(baos));
 
 		long startTime = System.currentTimeMillis();
 
@@ -466,18 +499,19 @@ public class DefaultExecutorTest extends
         long duration = System.currentTimeMillis() - startTime;
         
 		System.out.println("Process completed in " + duration +" millis; below is its output");
-		// System.out.println(baos);
+
 		if (watchdog.killedProcess()) {
 			System.out.println("Process timed out and was killed.");
 		}
 
-        assertTrue("The process was not killed by the watchdog", watchdog.killedProcess());
       
-        // assertTrue("The process was not properly killed because it took " + duration +
" ms to execute", duration < 5*1000);
+        assertTrue("The process was not killed by the watchdog", watchdog.killedProcess());
     }
 
     /**
      * A generic test case to print the command line arguments to 'printargs' script to solve
      * even more command line puzzles.
+     *
+     * @throws Exception the test failed
      */
     public void testExecuteWithComplexArguments() throws Exception {
         CommandLine cl = new CommandLine(printArgsScript);
@@ -488,4 +522,32 @@ public class DefaultExecutorTest extends
         assertFalse(exec.isFailure(exitValue));
      }
 
+    /**
+     * 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
+     */
+    public void testExec44() throws Exception {
+
+        CommandLine cl = new CommandLine(foreverTestScript);
+        MockExecuteResultHandler handler = new MockExecuteResultHandler();
+        ExecuteWatchdog watchdog = new ExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT);
+
+        exec.setWatchdog(watchdog);
+        exec.execute(cl, handler);
+
+        // wait for script to run
+        Thread.sleep(5000);
+        assertTrue(watchdog.isWatching());
+
+        // terminate it
+        watchdog.destroyProcess();
+        assertTrue(watchdog.killedProcess());
+        assertFalse(watchdog.isWatching());
+    }
 }



Mime
View raw message