Skip to content
Snippets Groups Projects
Commit 9e91aa28 authored by tpylak's avatar tpylak
Browse files

DMV-22 bugfix: if process was terminated during waiting for the result, the...

DMV-22 bugfix: if process was terminated during waiting for the result, the execution status was "COMPLETE"

SVN: 6559
parent 57688759
No related branches found
No related tags found
No related merge requests found
...@@ -332,7 +332,7 @@ public final class ProcessExecutionHelper ...@@ -332,7 +332,7 @@ public final class ProcessExecutionHelper
{ {
processWrapper.set(process); processWrapper.set(process);
final int exitValue = process.waitFor(); final int exitValue = process.waitFor();
if (processWrapper.getAndSet(null) == null) if (processWrapper.getAndSet(null) == null)
{ {
// Value is irrelevant, the ProcessKiller got us. // Value is irrelevant, the ProcessKiller got us.
return null; return null;
...@@ -475,6 +475,9 @@ public final class ProcessExecutionHelper ...@@ -475,6 +475,9 @@ public final class ProcessExecutionHelper
private ProcessResult getProcessResult(final boolean stopOnInterrupt, private ProcessResult getProcessResult(final boolean stopOnInterrupt,
final Future<ProcessResult> runnerFuture) final Future<ProcessResult> runnerFuture)
{ {
// when runUnblocking is used it is possible that we are hanging here while other thread
// runs the killer. We will get COMPLETE status and null as the ProcessResult. We have to
// change that status.
ExecutionResult<ProcessResult> executionResult = getExecutionResult(runnerFuture); ExecutionResult<ProcessResult> executionResult = getExecutionResult(runnerFuture);
if (executionResult.getStatus() != ExecutionStatus.COMPLETE) if (executionResult.getStatus() != ExecutionStatus.COMPLETE)
{ {
...@@ -496,7 +499,13 @@ public final class ProcessExecutionHelper ...@@ -496,7 +499,13 @@ public final class ProcessExecutionHelper
return result; return result;
} else } else
{ {
return new ProcessResult(commandLine, processNumber, executionResult.getStatus(), ExecutionStatus status = executionResult.getStatus();
if (status == ExecutionStatus.COMPLETE)
{
// see the note above about termination from other thread
status = ExecutionStatus.INTERRUPTED;
}
return new ProcessResult(commandLine, processNumber, status,
tryGetStartupFailureMessage(executionResult.tryGetException()), tryGetStartupFailureMessage(executionResult.tryGetException()),
ProcessResult.NO_EXIT_VALUE, null, operationLog, machineLog); ProcessResult.NO_EXIT_VALUE, null, operationLog, machineLog);
} }
......
...@@ -25,6 +25,7 @@ import java.io.IOException; ...@@ -25,6 +25,7 @@ import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
...@@ -37,6 +38,7 @@ import ch.systemsx.cisd.common.exceptions.StopException; ...@@ -37,6 +38,7 @@ import ch.systemsx.cisd.common.exceptions.StopException;
import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogCategory;
import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.logging.LogFactory;
import ch.systemsx.cisd.common.logging.LogInitializer; import ch.systemsx.cisd.common.logging.LogInitializer;
import ch.systemsx.cisd.common.process.ProcessExecutionHelper.IProcessHandler;
import ch.systemsx.cisd.common.process.ProcessExecutionHelper.OutputReadingStrategy; import ch.systemsx.cisd.common.process.ProcessExecutionHelper.OutputReadingStrategy;
/** /**
...@@ -273,4 +275,32 @@ public class ProcessExecutionHelperTest ...@@ -273,4 +275,32 @@ public class ProcessExecutionHelperTest
"some_non_existent_executable") >= 0); "some_non_existent_executable") >= 0);
} }
@Test(groups =
{ "requires_unix", "slow" })
public void testSleepyExecutionWithTermination() throws Exception
{
final File dummyExec = createSleepingExecutable("sleep.sh", 2 * WATCHDOG_WAIT_MILLIS);
final IProcessHandler handler =
ProcessExecutionHelper.runUnblocking(Arrays.asList(dummyExec.getAbsolutePath()),
operationLog, machineLog, WATCHDOG_WAIT_MILLIS);
final AtomicReference<ProcessResult> result = new AtomicReference<ProcessResult>(null);
final Runnable resultGetter = new Runnable()
{
public void run()
{
result.set(handler.getResult());
}
};
new Thread(resultGetter).start();
Thread.sleep(WATCHDOG_WAIT_MILLIS / 2);
boolean terminated = handler.terminate();
assertTrue(terminated);
Thread.sleep(WATCHDOG_WAIT_MILLIS / 20);
// Now resultGetter should be done with obtaining the result.
ProcessResult processResult = result.get();
assertTrue(processResult != null);
assert processResult != null; // avoid compiler warnings
assertFalse(processResult.isOK()); // process terminated unsuccessfully
assertTrue(processResult.isInterruped() || processResult.isTerminated());
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment