import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.ExecuteResultHandler;
+import org.apache.commons.exec.ExecuteStreamHandler;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.Executor;
import org.apache.commons.exec.LogOutputStream;
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.exec.ShutdownHookProcessDestroyer;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.slc.SlcException;
+import org.argeo.slc.UnsupportedException;
import org.argeo.slc.core.structure.tree.TreeSPath;
import org.argeo.slc.core.structure.tree.TreeSRelatedHelper;
import org.argeo.slc.core.test.SimpleResultPart;
private Map<String, String> osCmds = new HashMap<String, String>();
private Map<String, String> environmentVariables = new HashMap<String, String>();
+ private Boolean logCommand = false;
+ private Boolean redirectStreams = true;
+ private String osConsole = null;
+ private String generateScript = null;
+
private Long watchdogTimeout = 24 * 60 * 60 * 1000l;
private TestResult testResult;
+ // Internal use
+
public SystemCall() {
}
}
public void run() {
- // Log writers
final Writer stdOutWriter;
final Writer stdErrWriter;
if (stdOutFile != null) {
}
// Execution directory
- File dir = null;
- if (execDir != null) {
- // Replace '/' by local file separator, for portability
- execDir.replace('/', File.separatorChar);
- dir = new File(execDir).getCanonicalFile();
- }
-
- // Prepare executor
- if (dir == null)
- dir = new File(getUsedDir(dir));
+ File dir = new File(getExecDirToUse());
if (!dir.exists())
dir.mkdirs();
Executor executor = new DefaultExecutor();
executor.setWatchdog(new ExecuteWatchdog(watchdogTimeout));
- // Redirect standard streams
- PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(
- new LogOutputStream() {
- protected void processLine(String line, int level) {
- log(stdOutLogLevel, line);
- if (stdOutWriter != null)
- appendLineToFile(stdOutWriter, line);
- }
- }, new LogOutputStream() {
- protected void processLine(String line, int level) {
- log(stdErrLogLevel, line);
- if (stdErrWriter != null)
- appendLineToFile(stdErrWriter, line);
- }
- }, null);
- executor.setStreamHandler(pumpStreamHandler);
+ if (redirectStreams) {
+ // Redirect standard streams
+ executor.setStreamHandler(createExecuteStreamHandler(
+ stdOutWriter, stdErrWriter));
+ } else {
+ // Dummy stream handler (otherwise pump is used)
+ executor.setStreamHandler(new DummyexecuteStreamHandler());
+ }
+
executor.setProcessDestroyer(new ShutdownHookProcessDestroyer());
executor.setWorkingDirectory(dir);
// Command line to use
final CommandLine commandLine = createCommandLine();
+ if (logCommand)
+ log.info("Execute command:\n" + commandLine + "\n");
// Env variables
Map<String, String> environmentVariablesToUse = environmentVariables
.size() > 0 ? environmentVariables : null;
// Execute
- ExecuteResultHandler executeResultHandler = new ExecuteResultHandler() {
-
- public void onProcessComplete(int exitValue) {
- if (log.isDebugEnabled())
- log.debug("Process " + commandLine
- + " properly completed.");
- if (testResult != null) {
- forwardPath(testResult, null);
- testResult.addResultPart(new SimpleResultPart(
- TestStatus.PASSED, "Process " + commandLine
- + " properly completed."));
- }
- }
-
- public void onProcessFailed(ExecuteException e) {
- if (testResult != null) {
- forwardPath(testResult, null);
- testResult.addResultPart(new SimpleResultPart(
- TestStatus.ERROR, "Process " + commandLine
- + " failed.", e));
- } else {
- throw new SlcException("Process " + commandLine
- + " failed.", e);
- }
- }
- };
+ ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine);
if (synchronous)
try {
}
- /** Can be overridden by specific command wrapper*/
+ /** Can be overridden by specific command wrapper */
protected CommandLine createCommandLine() {
// Check if an OS specific command overrides
String osName = System.getProperty("os.name");
else
cmdToUse = cmd;
- final CommandLine commandLine;
+ CommandLine commandLine = null;
// Which command definition to use
if (commandToUse == null && cmdToUse == null)
throw new SlcException("Command line is empty.");
commandLine = new CommandLine(commandToUse.get(0).toString());
- for (int i = 1; i < commandToUse.size(); i++)
+
+ for (int i = 1; i < commandToUse.size(); i++) {
+ if (log.isTraceEnabled())
+ log.debug(commandToUse.get(i));
commandLine.addArgument(commandToUse.get(i).toString());
+ }
} else {
// all cases covered previously
- throw new UnsupportedOperationException();
+ throw new UnsupportedException();
}
+
+ if (generateScript != null) {
+ File scriptFile = new File(getExecDirToUse() + File.separator
+ + generateScript);
+ try {
+ FileUtils.writeStringToFile(scriptFile,
+ (osConsole != null ? osConsole + " " : "")
+ + commandLine.toString());
+ } catch (IOException e) {
+ throw new SlcException("Could not generate script "
+ + scriptFile, e);
+ }
+ commandLine = new CommandLine(scriptFile);
+ } else {
+ if (osConsole != null)
+ commandLine = CommandLine.parse(osConsole + " "
+ + commandLine.toString());
+ }
+
return commandLine;
}
+ protected ExecuteStreamHandler createExecuteStreamHandler(
+ final Writer stdOutWriter, final Writer stdErrWriter) {
+ // Log writers
+
+ PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(
+ new LogOutputStream() {
+ protected void processLine(String line, int level) {
+ log(stdOutLogLevel, line);
+ if (stdOutWriter != null)
+ appendLineToFile(stdOutWriter, line);
+ }
+ }, new LogOutputStream() {
+ protected void processLine(String line, int level) {
+ log(stdErrLogLevel, line);
+ if (stdErrWriter != null)
+ appendLineToFile(stdErrWriter, line);
+ }
+ }, null);
+ return pumpStreamHandler;
+ }
+
+ protected ExecuteResultHandler createExecuteResultHandler(
+ final CommandLine commandLine) {
+ return new ExecuteResultHandler() {
+
+ public void onProcessComplete(int exitValue) {
+ if (log.isDebugEnabled())
+ log
+ .debug("Process " + commandLine
+ + " properly completed.");
+ if (testResult != null) {
+ forwardPath(testResult, null);
+ testResult.addResultPart(new SimpleResultPart(
+ TestStatus.PASSED, "Process " + commandLine
+ + " properly completed."));
+ }
+ }
+
+ public void onProcessFailed(ExecuteException e) {
+ if (testResult != null) {
+ forwardPath(testResult, null);
+ testResult.addResultPart(new SimpleResultPart(
+ TestStatus.ERROR, "Process " + commandLine
+ + " failed.", e));
+ } else {
+ throw new SlcException("Process " + commandLine
+ + " failed.", e);
+ }
+ }
+ };
+ }
+
/**
- * Shortcut method returning the current exec dir if the specified one is
- * null.
+ * Shortcut method getting the execDir to use
*/
- private String getUsedDir(File dir) {
- if (dir == null)
- return System.getProperty("user.dir");
- else
- return dir.getPath();
+ protected String getExecDirToUse() {
+ try {
+ File dir = null;
+ if (execDir != null) {
+ // Replace '/' by local file separator, for portability
+ execDir.replace('/', File.separatorChar);
+ dir = new File(execDir).getCanonicalFile();
+ }
+
+ if (dir == null)
+ return System.getProperty("user.dir");
+ else
+ return dir.getPath();
+ } catch (Exception e) {
+ throw new SlcException("Cannot find exec dir", e);
+ }
}
protected void log(String logLevel, String line) {
this.testResult = testResult;
}
+ public void setLogCommand(Boolean logCommand) {
+ this.logCommand = logCommand;
+ }
+
+ public void setRedirectStreams(Boolean redirectStreams) {
+ this.redirectStreams = redirectStreams;
+ }
+
+ public void setOsConsole(String osConsole) {
+ this.osConsole = osConsole;
+ }
+
+ public void setGenerateScript(String generateScript) {
+ this.generateScript = generateScript;
+ }
+
+ private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
+
+ public void setProcessErrorStream(InputStream is) throws IOException {
+ }
+
+ public void setProcessInputStream(OutputStream os) throws IOException {
+ }
+
+ public void setProcessOutputStream(InputStream is) throws IOException {
+ }
+
+ public void start() throws IOException {
+ }
+
+ public void stop() {
+ }
+
+ }
+
}