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]