You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2019/03/19 10:47:42 UTC
[commons-rng] branch master updated: Report exit value of stress
test subprocess programs
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git
The following commit(s) were added to refs/heads/master by this push:
new 6d08881 Report exit value of stress test subprocess programs
6d08881 is described below
commit 6d08881815ac0a7d582cd570bfc35194938ecced
Author: aherbert <ah...@apache.org>
AuthorDate: Tue Mar 19 10:47:38 2019 +0000
Report exit value of stress test subprocess programs
---
.../commons/rng/examples/stress/BridgeTester.java | 42 ++++++++++++++++-
.../rng/examples/stress/RandomStressTester.java | 52 ++++++++++++++++++++--
2 files changed, 89 insertions(+), 5 deletions(-)
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTester.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTester.java
index bbfc560..d4eef10 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTester.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTester.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
/**
* Class that can be used for testing that {@code int} values can be piped to a
@@ -48,6 +49,8 @@ public class BridgeTester {
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111",
};
+ /** The timeout to wait for a process to end (1 second in milliseconds). */
+ private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(1);
/** Command line. */
private final List<String> cmdLine;
@@ -143,7 +146,17 @@ public class BridgeTester {
}
}
- } catch (IOException e) {
+ if (waitFor(testingProcess)) {
+ final int exitValue = testingProcess.exitValue();
+ if (exitValue != 0) {
+ System.out.printf("[ERROR] %s exit code = %d%n", cmdLine.get(0), exitValue);
+ }
+ } else {
+ System.out.printf("[ERROR] %s did not exit, killing the subprocess%n", cmdLine.get(0));
+ testingProcess.destroy();
+ }
+
+ } catch (IOException | InterruptedException e) {
throw new RuntimeException("Failed to run process: " + e.getMessage());
}
}
@@ -198,8 +211,33 @@ public class BridgeTester {
private static void writeByte(BufferedWriter data,
int value) throws IOException {
// This matches the functionality of:
- // data.write(String.format("%8s", Integer.toBinaryString(value & 0xff)).replace(' ', '0'));
+ // data.write(String.format("%8s", Integer.toBinaryString(value & 0xff)).replace(' ', '0'))
data.write(BIT_REP[value >>> 4]);
data.write(BIT_REP[value & 0x0F]);
}
+
+ /**
+ * Wait until the given {@code Process} object has terminated, waiting at most for 1 second.
+ *
+ * @param process the process.
+ * @return {@code true} if the process has exited, {@code false} otherwise.
+ * @throws InterruptedException if interrupted while waiting.
+ */
+ private static boolean waitFor(Process process) throws InterruptedException {
+ // TODO - use Java 1.8 Process.waitFor(long, TimeUnit) instead
+ long startTime = System.currentTimeMillis();
+ long remaining = TIMEOUT;
+
+ while (remaining > 0) {
+ try {
+ // Poll the exit value
+ process.exitValue();
+ return true;
+ } catch (IllegalThreadStateException ex) {
+ Thread.sleep(Math.min(remaining + 1, 100));
+ }
+ remaining = TIMEOUT - (System.currentTimeMillis() - startTime);
+ }
+ return false;
+ }
}
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RandomStressTester.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RandomStressTester.java
index 2b95afe..4de2395 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RandomStressTester.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RandomStressTester.java
@@ -186,6 +186,10 @@ public class RandomStressTester {
* Pipes random numbers to the standard input of an analyzer.
*/
private class Task implements Runnable {
+ /** The timeout to wait for the process exit value in milliseconds. */
+ private final long TIMEOUT = 1000000L;
+ /** The default exit value to use when the process has not terminated. */
+ private final int DEFAULT_EXIT_VALUE = -808080;
/** Directory for reports of the tester processes. */
private final File output;
/** RNG to be tested. */
@@ -205,7 +209,7 @@ public class RandomStressTester {
/** {@inheritDoc} */
@Override
- public void run() {
+ public void run() {
try {
// Write header.
printHeader(output, rng);
@@ -213,6 +217,7 @@ public class RandomStressTester {
// Start test suite.
final ProcessBuilder builder = new ProcessBuilder(cmdLine);
builder.redirectOutput(ProcessBuilder.Redirect.appendTo(output));
+ builder.redirectErrorStream(true);
final Process testingProcess = builder.start();
final DataOutputStream sink = new DataOutputStream(
new BufferedOutputStream(testingProcess.getOutputStream()));
@@ -229,13 +234,49 @@ public class RandomStressTester {
final long endTime = System.nanoTime();
+ // Get the exit value
+ final int exitValue = getExitValue(testingProcess);
+
// Write footer.
- printFooter(output, endTime - startTime);
+ printFooter(output, endTime - startTime, exitValue);
} catch (IOException e) {
throw new RuntimeException("Failed to start task: " + e.getMessage());
}
}
+
+ /**
+ * Get the exit value from the process, waiting at most for 1 second, otherwise kill the process
+ * and return a dummy value.
+ *
+ * @param process the process.
+ * @return the exit value.
+ * @see Process#destroy()
+ */
+ private int getExitValue(Process process) {
+ long startTime = System.currentTimeMillis();
+ long remaining = TIMEOUT;
+
+ while (remaining > 0) {
+ try {
+ return process.exitValue();
+ } catch (IllegalThreadStateException ex) {
+ try {
+ Thread.sleep(Math.min(remaining + 1, 100));
+ } catch (InterruptedException e) {
+ // Reset interrupted status and stop waiting
+ Thread.currentThread().interrupt();
+ break;
+ }
+ }
+ remaining = TIMEOUT - (System.currentTimeMillis() - startTime);
+ }
+
+ // Not finished so kill it
+ process.destroy();
+
+ return DEFAULT_EXIT_VALUE;
+ }
}
/**
@@ -278,17 +319,22 @@ public class RandomStressTester {
/**
* @param output File.
* @param nanoTime Duration of the run.
+ * @param exitValue The process exit value.
* @throws IOException if there was a problem opening or writing to
* the {@code output} file.
*/
private void printFooter(File output,
- long nanoTime)
+ long nanoTime,
+ int exitValue)
throws IOException {
final StringBuilder sb = new StringBuilder();
sb.append(C).append(N);
appendDate(sb, "End");
+ sb.append(C).append("Exit value: ").append(exitValue).append(N);
+ sb.append(C).append(N);
+
final double duration = nanoTime * 1e-9 / 60;
sb.append(C).append("Test duration: ").append(duration).append(" minutes").append(N);