public final class SpawnedProcess
extends java.lang.Object
There are three main aspects handled by this class:
Implementation notes: Active waiting is employed when waiting for
the process to complete. This is considered acceptable since the expected
usage pattern is to spawn the process, execute a set of tests, and then
finally asking the process to shut down. Waiting for the process to
complete is the last step, and a process typically lives only for a short
period of time anyway (often only for seconds, seldom more than a few
minutes).
Forcibly destroying processes that live too long makes the test run
continue even when facing inter-process communication hangs. The prime
example is when both the client and the server are waiting for the other
party to send data. Since the timeout is very high this feature is intended
to avoid automated test runs from hanging indefinitely, for instance due to
environmental issues affecting the process.
Modifier and Type | Class and Description |
---|---|
private static class |
SpawnedProcess.ProcessKillerTask
A task that will kill the specified process.
|
private static class |
SpawnedProcess.StreamSaver
Class holding references to a stream that receives the output from a
process and a thread that reads the process output and passes it on
to the stream.
|
Modifier and Type | Field and Description |
---|---|
private SpawnedProcess.StreamSaver |
errSaver |
private java.lang.Process |
javaProcess |
private static long |
KILL_THRESHOLD
The maximum allowed time for a process to live.
|
private static long |
KILL_THRESHOLD_DEFAULT |
private static java.lang.String |
KILL_THRESHOLD_PROPERTY
Property allowing the kill threshold to be overridden.
|
private static java.util.Timer |
KILL_TIMER |
private java.util.TimerTask |
killTask |
private java.lang.String |
name |
private SpawnedProcess.StreamSaver |
outSaver |
(package private) int |
stdOutReadOffset
Position offset for getNextServerOutput().
|
private boolean |
suppressOutput |
private static java.lang.String |
TAG |
Constructor and Description |
---|
SpawnedProcess(java.lang.Process javaProcess,
java.lang.String name)
Creates a new wrapper to handle the given process.
|
Modifier and Type | Method and Description |
---|---|
private void |
cleanupProcess()
Cleans up the process, explicitly closing the streams associated with it.
|
private void |
closeStream(java.lang.Object stream)
Closes the specified stream, ignoring any exceptions.
|
int |
complete()
Waits for the process to terminate.
|
int |
complete(long timeout)
Waits for the process to terminate, forcibly terminating it if it
takes longer than the specified timeout.
|
java.lang.String |
getFailMessage(java.lang.String reason)
Get a fail message that is the passed in reason plus
the stderr and stdout for any output written.
|
java.lang.String |
getFullServerError()
Get the full server error output (stderr) as a string using the default
encoding which is assumed is how it was originally written.
|
java.lang.String |
getFullServerOutput()
Get the full server output (stdout) as a string using the default
encoding which is assumed is how it was originally written.
|
java.lang.String |
getNextServerOutput()
Get the next set of server output (stdout) as a string using the default
encoding which is assumed is how it was originally
written.
|
int |
getPid()
Return the pid if on Unixen, or -1 on Windows (can't be obtained).
|
java.lang.Process |
getProcess()
Get the Java Process object
|
private void |
joinWith(java.lang.Thread t)
Joins up with the specified thread.
|
java.lang.String |
jstack()
Return the jstack(1) dump of the process if possible.
|
private void |
printDiagnostics(int exitCode)
Prints diagnostics to stdout/stderr if the process failed.
|
private java.util.TimerTask |
scheduleKill(java.lang.Process process,
java.lang.String name)
Schedules a task to kill/terminate the task after a predefined timeout.
|
private static void |
sleep(long ms) |
private SpawnedProcess.StreamSaver |
startStreamSaver(java.io.InputStream in,
java.lang.String name)
Creates and starts a stream saver that reads the specified input stream
in a separate stream.
|
void |
suppressOutputOnComplete()
Causes output obtained from the process to be suppressed when
executing the
complete -methods. |
boolean |
waitForExit(long patience,
long sleepInterval)
Return
true if the subprocess p has exited within patience milliseconds. |
private static final java.lang.String TAG
private static java.util.Timer KILL_TIMER
private static final java.lang.String KILL_THRESHOLD_PROPERTY
Interprets the numeric value as milliseconds, ignored if non-numeric. Overriding this value may be required if the test machine is extremely slow, or you want to kill hung processes earlier for some reason.
private static final long KILL_THRESHOLD_DEFAULT
private static final long KILL_THRESHOLD
private final java.lang.String name
private final java.lang.Process javaProcess
private final SpawnedProcess.StreamSaver errSaver
private final SpawnedProcess.StreamSaver outSaver
private boolean suppressOutput
private final java.util.TimerTask killTask
int stdOutReadOffset
public SpawnedProcess(java.lang.Process javaProcess, java.lang.String name)
javaProcess
- a (running) processname
- name to associate with the processprivate static void sleep(long ms)
private java.util.TimerTask scheduleKill(java.lang.Process process, java.lang.String name)
name
- name of the processprocess
- the processpublic void suppressOutputOnComplete()
complete
-methods.public java.lang.Process getProcess()
public java.lang.String getFullServerOutput() throws java.lang.InterruptedException
Get the full server output (stdout) as a string using the default encoding which is assumed is how it was originally written.
This method should only be called after the process has completed.
That is, complete()
or complete(long)
should be called first.
java.lang.InterruptedException
public java.lang.String getFullServerError() throws java.lang.InterruptedException
This method should only be called after the process has completed.
That is, complete()
or complete(long)
should be called first.
java.lang.InterruptedException
public java.lang.String getNextServerOutput()
public java.lang.String getFailMessage(java.lang.String reason)
public int complete() throws java.io.IOException
This call will block until one of the following conditions are met:
java.io.IOException
- if printing diagnostics failspublic int complete(long timeout) throws java.io.IOException
This call will block until one of the following conditions are met:
timeout
- the number of milliseconds to wait for the process
to terminate normally before destroying itjava.io.IOException
- if printing diagnostics failsprivate void cleanupProcess()
private void printDiagnostics(int exitCode) throws java.io.IOException
exitCode
- the exit code of the spawned processjava.io.IOException
- if writing to an output stream failssuppressOutput
private void joinWith(java.lang.Thread t)
private void closeStream(java.lang.Object stream)
stream
- stream to close (may be null
)private SpawnedProcess.StreamSaver startStreamSaver(java.io.InputStream in, java.lang.String name)
in
- input stream to read fromname
- name of the threadStreamSaver
object.public boolean waitForExit(long patience, long sleepInterval) throws java.lang.InterruptedException
true
if the subprocess p
has exited within patience
milliseconds. Sleep sleepInterval
between each check}.
Note: you still need to call one of the complete()
overloads even
if using this method (which is optional). It can be used before trying
a jstack()
call.patience
- the maximum milliseconds we want to wait forsleepInterval
- sleep for this amount of milliseconds before trying
testing again if not already exited the first time
we check. If patience <= sleepInterval we only
check once.java.lang.InterruptedException
public java.lang.String jstack() throws java.security.PrivilegedActionException, java.lang.InterruptedException
java.security.PrivilegedActionException
java.lang.InterruptedException
public int getPid() throws java.security.PrivilegedActionException
java.security.PrivilegedActionException
Apache Derby V10.13 Internals - Copyright © 2004,2016 The Apache Software Foundation. All Rights Reserved.