Author: ngn
Date: Sun Jul  9 13:32:36 2006
New Revision: 420347

URL: http://svn.apache.org/viewvc?rev=420347&view=rev
Log:
Implemented async execution
Added unit tests, including tests for scripts returning error exit values

Added:
    jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.bat   (with props)
    jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.sh   (with props)
Modified:
    
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java
    
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java
    
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/DefaultProcessingEnvironment.java
    
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/CommandLineTest.java
    
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
    
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java
    
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/TestUtil.java

Modified: 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java?rev=420347&r1=420346&r2=420347&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java
 (original)
+++ 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java
 Sun Jul  9 13:32:36 2006
@@ -79,6 +79,13 @@
         setExecutable(executable);
     }
 
+    /**
+     * Create a command line without any arguments.
+     */
+    public CommandLine(File executable) {
+        setExecutable(executable.getAbsolutePath());
+    }
+
     private void setExecutable(final String executable) {
         if (executable == null) {
             throw new IllegalArgumentException("Executable can not be null");

Modified: 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java?rev=420347&r1=420346&r2=420347&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java
 (original)
+++ 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java
 Sun Jul  9 13:32:36 2006
@@ -101,30 +101,20 @@
         return execute(command, (Map) null);
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.apache.commons.exec.Executor#execute(java.lang.String[],
-     *      java.util.Map)
-     */
-    public int execute(final CommandLine command, Map environment)
-            throws ExecuteException, IOException {
+    private int executeInternal(final CommandLine command, final Map 
environment, 
+            final File dir, final ExecuteStreamHandler streams) throws 
IOException {
 
-        if (workingDirectory != null && !workingDirectory.exists()) {
-            throw new IOException(workingDirectory + " doesn't exist.");
-        }
-
-        final Process process = launch(command, environment, workingDirectory);
+        final Process process = launch(command, environment, dir);
 
         try {
-            streamHandler.setProcessInputStream(process.getOutputStream());
-            streamHandler.setProcessOutputStream(process.getInputStream());
-            streamHandler.setProcessErrorStream(process.getErrorStream());
+            streams.setProcessInputStream(process.getOutputStream());
+            streams.setProcessOutputStream(process.getInputStream());
+            streams.setProcessErrorStream(process.getErrorStream());
         } catch (IOException e) {
             process.destroy();
             throw e;
         }
-        streamHandler.start();
+        streams.start();
 
         try {
             // add the process to the list of those to destroy if the VM exits
@@ -144,7 +134,7 @@
             if (watchdog != null) {
                 watchdog.stop();
             }
-            streamHandler.stop();
+            streams.stop();
             closeStreams(process);
 
             if (watchdog != null) {
@@ -157,7 +147,10 @@
 
             }
 
-            // TODO check exitValue and throw if not OK
+            if(isFailure(exitValue)) {
+                throw new ExecuteException("Process exited with an error: " + 
exitValue, exitValue);
+            }
+            
             return exitValue;
         } finally {
             // remove the process to the list of those to destroy if the VM
@@ -165,6 +158,25 @@
             //
             // processDestroyer.remove(process);
         }
+
+        
+    }
+    
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.commons.exec.Executor#execute(java.lang.String[],
+     *      java.util.Map)
+     */
+    public int execute(final CommandLine command, Map environment)
+            throws ExecuteException, IOException {
+
+        if (workingDirectory != null && !workingDirectory.exists()) {
+            throw new IOException(workingDirectory + " doesn't exist.");
+        }
+        
+        return executeInternal(command, environment, workingDirectory, 
streamHandler);
+
     }
 
     /**
@@ -203,7 +215,7 @@
      */
     public void execute(final CommandLine command, ExecuteResultHandler 
handler)
             throws ExecuteException, IOException {
-        // TODO Auto-generated method stub
+        execute(command, null, handler);
 
     }
 
@@ -215,8 +227,35 @@
      */
     public void execute(final CommandLine command, final Map environment,
             final ExecuteResultHandler handler) throws ExecuteException, 
IOException {
-        // TODO Auto-generated method stub
+        if (workingDirectory != null && !workingDirectory.exists()) {
+            throw new IOException(workingDirectory + " doesn't exist.");
+        }
 
+        new Thread() {
+
+            /* (non-Javadoc)
+             * @see java.lang.Thread#run()
+             */
+            public void run() {
+                int exitValue = Executor.INVALID_EXITVALUE;
+                try {
+                    
+                    exitValue = executeInternal(command, environment, 
workingDirectory, streamHandler);
+
+                    // TODO check exitValue and throw if not OK
+                    handler.onProcessComplete(exitValue);
+                } catch (ExecuteException e) {
+                    handler.onProcessFailed(e);
+                } catch(Exception e) {
+                    handler.onProcessFailed(new ExecuteException("Execution 
failed", exitValue, e));
+                } finally {
+                    // remove the process to the list of those to destroy if 
the VM
+                    // exits
+                    //
+                    // processDestroyer.remove(process);
+                }
+            }
+        }.start();
     }
 
     /**
@@ -240,6 +279,32 @@
             process.getErrorStream().close();
         } catch (IOException eyeOhEx) {
             // ignore error
+        }
+    }
+    
+    /**
+     * Checks whether <code>exitValue</code> signals a failure on the current
+     * system (OS specific).
+     * <p>
+     * <b>Note</b> that this method relies on the conventions of the OS, it
+     * will return false results if the application you are running doesn't
+     * follow these conventions. One notable exception is the Java VM provided
+     * by HP for OpenVMS - it will return 0 if successful (like on any other
+     * platform), but this signals a failure on OpenVMS. So if you execute a 
new
+     * Java VM on OpenVMS, you cannot trust this method.
+     * </p>
+     * 
+     * @param exitValue
+     *            the exit value (return code) to be checked
+     * @return <code>true</code> if <code>exitValue</code> signals a failure
+     */
+    public static boolean isFailure(final int exitValue) {
+        if (OS.isFamilyOpenVms()) {
+            // even exit value signals failure
+            return (exitValue % 2) == 0;
+        } else {
+            // non zero exit value signals failure
+            return exitValue != 0;
         }
     }
 }

Modified: 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/DefaultProcessingEnvironment.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/DefaultProcessingEnvironment.java?rev=420347&r1=420346&r2=420347&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/DefaultProcessingEnvironment.java
 (original)
+++ 
jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/DefaultProcessingEnvironment.java
 Sun Jul  9 13:32:36 2006
@@ -28,7 +28,8 @@
 import java.util.Map;
 
 import org.apache.commons.exec.CommandLine;
-import org.apache.commons.exec.Execute;
+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.logging.Log;
@@ -104,11 +105,10 @@
      */
     protected BufferedReader runProcEnvCommand() throws IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        Execute exe = new Execute(new PumpStreamHandler(out));
-        exe.setCommandline(getProcEnvCommand());
-        // Make sure we do not recurse forever
-        exe.setNewEnvironment(true);
-        int retval = exe.execute();
+        Executor exe = new DefaultExecutor();
+        exe.setStreamHandler(new PumpStreamHandler(out));
+
+        int retval = exe.execute(getProcEnvCommand(), new HashMap());
         if (retval != 0) {
             // Just try to use what we got
         }

Modified: 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/CommandLineTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/CommandLineTest.java?rev=420347&r1=420346&r2=420347&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/CommandLineTest.java
 (original)
+++ 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/CommandLineTest.java
 Sun Jul  9 13:32:36 2006
@@ -56,7 +56,7 @@
 
     public void testNullExecutable() {
         try {
-            CommandLine cmdl = new CommandLine(null);
+            CommandLine cmdl = new CommandLine((String)null);
             fail("Must throw IllegalArgumentException");
         } catch (IllegalArgumentException e) {
             // Expected

Modified: 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java?rev=420347&r1=420346&r2=420347&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
 (original)
+++ 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
 Sun Jul  9 13:32:36 2006
@@ -26,29 +26,38 @@
 
 public class DefaultExecutorTest extends TestCase {
 
-    private String testDir = "src/test/scripts";
+    
+    private Executor exec = new DefaultExecutor();
+    private File testDir = new File("src/test/scripts");
     private ByteArrayOutputStream baos;
-    private String testScript = TestUtil.resolveScriptForOS(testDir + "/test");
+    private File testScript = TestUtil.resolveScriptForOS(testDir + "/test");
+    private File errorTestScript = TestUtil.resolveScriptForOS(testDir + 
"/error");
 
     protected void setUp() throws Exception {
         baos = new ByteArrayOutputStream();
+        exec.setStreamHandler(new PumpStreamHandler(baos, baos));
     }
 
     public void testExecute() throws Exception {
-        Executor exec = new DefaultExecutor();
-        exec.setStreamHandler(new PumpStreamHandler(baos, baos));
-
-        CommandLine cl = new CommandLine(new 
File(testScript).getAbsolutePath());
+        CommandLine cl = new CommandLine(testScript);
 
         int exitValue = exec.execute(cl);
         assertEquals("FOO..", baos.toString().trim());
         assertEquals(0, exitValue);
     }
 
-    public void testExecuteWithArg() throws Exception {
-        Executor exec = new DefaultExecutor();
-        exec.setStreamHandler(new PumpStreamHandler(baos, baos));
+    public void testExecuteWithError() throws Exception {
+        CommandLine cl = new CommandLine(errorTestScript);
+        
+        try{
+            exec.execute(cl);
+            fail("Must throw ExecuteException");
+        } catch(ExecuteException e) {
+            assertEquals(1, e.getExitValue());
+        }
+    }
 
+    public void testExecuteWithArg() throws Exception {
         CommandLine cl = new CommandLine(testScript);
         cl.addArgument("BAR");
         int exitValue = exec.execute(cl);
@@ -58,9 +67,6 @@
     }
 
     public void testExecuteWithEnv() throws Exception {
-        Executor exec = new DefaultExecutor();
-        exec.setStreamHandler(new PumpStreamHandler(baos, baos));
-       
        Map env = new HashMap();
         env.put("TEST_ENV_VAR", "XYZ");
 
@@ -72,10 +78,7 @@
         assertEquals(0, exitValue);
     }
 
-    public void disabledtestExecuteAsync() throws Exception {
-        Executor exec = new DefaultExecutor();
-        exec.setStreamHandler(new PumpStreamHandler(baos, baos));
-        
+    public void testExecuteAsync() throws Exception {
         CommandLine cl = new CommandLine(testScript);
         
         MockExecuteResultHandler handler = new MockExecuteResultHandler();
@@ -83,10 +86,25 @@
         exec.execute(cl, handler);
         
         // wait for script to run
-        Thread.sleep(1000);
+        Thread.sleep(2000);
         
-        assertEquals("FOO..", baos.toString().trim());
         assertEquals(0, handler.getExitValue());
+        assertEquals("FOO..", baos.toString().trim());
+    }
+
+    public void testExecuteAsyncWithError() throws Exception {
+        CommandLine cl = new CommandLine(errorTestScript);
+        
+        MockExecuteResultHandler handler = new MockExecuteResultHandler();
+        
+        exec.execute(cl, handler);
+        
+        // wait for script to run
+        Thread.sleep(2000);
+        
+        assertEquals(1, handler.getExitValue());
+        assertTrue(handler.getException() instanceof ExecuteException);
+        assertEquals("FOO..", baos.toString().trim());
     }
     
     

Modified: 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java?rev=420347&r1=420346&r2=420347&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java
 (original)
+++ 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java
 Sun Jul  9 13:32:36 2006
@@ -34,6 +34,7 @@
      */
     public void onProcessFailed(ExecuteException e) {
         this.exception = e;
+        exitValue = e.getExitValue();
     }
 
     /**

Modified: 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/TestUtil.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/TestUtil.java?rev=420347&r1=420346&r2=420347&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/TestUtil.java
 (original)
+++ 
jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/TestUtil.java
 Sun Jul  9 13:32:36 2006
@@ -17,6 +17,7 @@
 
 package org.apache.commons.exec;
 
+import java.io.File;
 import java.util.Arrays;
 
 import junit.framework.AssertionFailedError;
@@ -27,11 +28,11 @@
     private TestUtil() {
     }
 
-    public static String resolveScriptForOS(String script) {
+    public static File resolveScriptForOS(String script) {
         if (OS.isFamilyWindows()) {
-            return script + ".bat";
+            return new File(script + ".bat");
         } else if (OS.isFamilyUnix()) {
-            return script + ".sh";
+            return new File(script + ".sh");
         } else {
             throw new AssertionFailedError("Test not supported for this OS");
         }

Added: jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.bat
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.bat?rev=420347&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.bat (added)
+++ jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.bat Sun Jul  9 
13:32:36 2006
@@ -0,0 +1,23 @@
[EMAIL PROTECTED] off
+REM
+REM Copyright  2001-2002,2004 The Apache Software Foundation
+REM
+REM  Licensed under the Apache License, Version 2.0 (the "License");
+REM  you may not use this file except in compliance with the License.
+REM  You may obtain a copy of the License at
+REM
+REM      http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM  Unless required by applicable law or agreed to in writing, software
+REM  distributed under the License is distributed on an "AS IS" BASIS,
+REM  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM  See the License for the specific language governing permissions and
+REM  limitations under the License.
+REM
+REM
+
+REM This test script will return an error exit code
+
[EMAIL PROTECTED] FOO.%TEST_ENV_VAR%.%1
+
+EXIT 1

Propchange: jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.bat
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.sh
URL: 
http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.sh?rev=420347&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.sh (added)
+++ jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.sh Sun Jul  9 
13:32:36 2006
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+#
+#  Copyright  2001-2002,2004 The Apache Software Foundation
+# 
+#   Licensed 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.
+# 
+#
+
+echo FOO.$TEST_ENV_VAR.$1
+
+exit 1

Propchange: jakarta/commons/sandbox/exec/trunk/src/test/scripts/error.sh
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to