Here is the part of message from Stefan about investigating the failure of
test/jdk/sun/tools/jstatd/JstatdTest.java test.
If we instead look at the ProcessTool and ProcessThread in our test library:
public static Process startProcess(String name,
ProcessBuilder processBuilder,
final Predicate<String> linePredicate,
long timeout,
TimeUnit unit)
This function starts a process and waits for the process to output lines that linePredicate accepts. That could be positive outcomes like:
"jstatd started"
or negative like:
"port already used"
Either of those are fine and control will be handed back to the test program that called startProcess.
However, if your process fail for any other kind of problems / bugs, then those lines will not be printed. What happens then is that startProcess just hangs until the test times out. And the resulting output is not flushed, and we can't see what really happened.
I experimented a bit to show that this really was the case.
1) Make the jstatd command invalid
diff --git a/test/jdk/sun/tools/jstatd/JstatdTest.java b/test/jdk/sun/tools/jstatd/JstatdTest.java
index 81180b6a993..c814bc415c2 100644
--- a/test/jdk/sun/tools/jstatd/JstatdTest.java
+++ b/test/jdk/sun/tools/jstatd/JstatdTest.java
@@ -252,6 +252,7 @@ public final class JstatdTest {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstatd");
launcher.addVMArgs(Utils.getTestJavaOpts());
launcher.addVMArg("-XX:+UsePerfData");
+ launcher.addVMArg("-XX:+UseGris");
String testSrc = System.getProperty("test.src");
if (port != null) {
addToolArg(launcher,"-p", port);
The test will now hang and timeout.
2) With the following hack we quickly abort if the started process failed too early:
diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java
index 33be681c97c..7edb9f2a454 100644
--- a/test/lib/jdk/test/lib/process/ProcessTools.java
+++ b/test/lib/jdk/test/lib/process/ProcessTools.java
@@ -217,7 +217,19 @@ public final class ProcessTools {
try {
if (timeout > -1) {
if (timeout == 0) {
- latch.await();
+ // Requested to wait forever, but if the process got an
+ // error this will lead to timeouts that are hard to
+ // debug. Poll every second to ensure that the process
+ // has not died
+ while (!latch.await(1, TimeUnit.SECONDS)) {
+ if (!p.isAlive()) {
+ System.err.println("Process died");
+
+ // Release waiting thread
+ latch.countDown();
+ throw new RuntimeException("Started process failed to start");
+ }
+ }
} else {
if (!latch.await(Utils.adjustTimeout(timeout), unit)) {
throw new TimeoutException();
diff --git a/test/lib/jdk/test/lib/thread/ProcessThread.java b/test/lib/jdk/test/lib/thread/ProcessThread.java
index ff4b56fd459..95dd1c0bde8 100644
--- a/test/lib/jdk/test/lib/thread/ProcessThread.java
+++ b/test/lib/jdk/test/lib/thread/ProcessThread.java
@@ -150,9 +150,16 @@ public class ProcessThread extends TestThread {
*/
@Override
public void xrun() throws Throwable {
+ try {
this.process = ProcessTools.startProcess(name, processBuilder, waitfor);
+ } catch (Throwable t) {
+ String name = Thread.currentThread().getName();
+ System.out.println(String.format("ProcessThread[%s] failed: %s", name, t.toString()));
+ throw t;
+ } finally {
// Release when process is started
latch.countDown();
+ }
// Will block...
try {
There also seems to be some waitFor/OutputAnalyzer problems in ProcessTools as well.
test/jdk/sun/tools/jstatd/JstatdTest.java test.
If we instead look at the ProcessTool and ProcessThread in our test library:
public static Process startProcess(String name,
ProcessBuilder processBuilder,
final Predicate<String> linePredicate,
long timeout,
TimeUnit unit)
This function starts a process and waits for the process to output lines that linePredicate accepts. That could be positive outcomes like:
"jstatd started"
or negative like:
"port already used"
Either of those are fine and control will be handed back to the test program that called startProcess.
However, if your process fail for any other kind of problems / bugs, then those lines will not be printed. What happens then is that startProcess just hangs until the test times out. And the resulting output is not flushed, and we can't see what really happened.
I experimented a bit to show that this really was the case.
1) Make the jstatd command invalid
diff --git a/test/jdk/sun/tools/jstatd/JstatdTest.java b/test/jdk/sun/tools/jstatd/JstatdTest.java
index 81180b6a993..c814bc415c2 100644
--- a/test/jdk/sun/tools/jstatd/JstatdTest.java
+++ b/test/jdk/sun/tools/jstatd/JstatdTest.java
@@ -252,6 +252,7 @@ public final class JstatdTest {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstatd");
launcher.addVMArgs(Utils.getTestJavaOpts());
launcher.addVMArg("-XX:+UsePerfData");
+ launcher.addVMArg("-XX:+UseGris");
String testSrc = System.getProperty("test.src");
if (port != null) {
addToolArg(launcher,"-p", port);
The test will now hang and timeout.
2) With the following hack we quickly abort if the started process failed too early:
diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java
index 33be681c97c..7edb9f2a454 100644
--- a/test/lib/jdk/test/lib/process/ProcessTools.java
+++ b/test/lib/jdk/test/lib/process/ProcessTools.java
@@ -217,7 +217,19 @@ public final class ProcessTools {
try {
if (timeout > -1) {
if (timeout == 0) {
- latch.await();
+ // Requested to wait forever, but if the process got an
+ // error this will lead to timeouts that are hard to
+ // debug. Poll every second to ensure that the process
+ // has not died
+ while (!latch.await(1, TimeUnit.SECONDS)) {
+ if (!p.isAlive()) {
+ System.err.println("Process died");
+
+ // Release waiting thread
+ latch.countDown();
+ throw new RuntimeException("Started process failed to start");
+ }
+ }
} else {
if (!latch.await(Utils.adjustTimeout(timeout), unit)) {
throw new TimeoutException();
diff --git a/test/lib/jdk/test/lib/thread/ProcessThread.java b/test/lib/jdk/test/lib/thread/ProcessThread.java
index ff4b56fd459..95dd1c0bde8 100644
--- a/test/lib/jdk/test/lib/thread/ProcessThread.java
+++ b/test/lib/jdk/test/lib/thread/ProcessThread.java
@@ -150,9 +150,16 @@ public class ProcessThread extends TestThread {
*/
@Override
public void xrun() throws Throwable {
+ try {
this.process = ProcessTools.startProcess(name, processBuilder, waitfor);
+ } catch (Throwable t) {
+ String name = Thread.currentThread().getName();
+ System.out.println(String.format("ProcessThread[%s] failed: %s", name, t.toString()));
+ throw t;
+ } finally {
// Release when process is started
latch.countDown();
+ }
// Will block...
try {
There also seems to be some waitFor/OutputAnalyzer problems in ProcessTools as well.
- is cloned by
-
JDK-8303486 [REDO] Update ProcessTools.startProcess(...) to exit early if process exit before linePredicate is printed.
-
- Resolved
-
- relates to
-
JDK-8303421 [BACKOUT] 8303133: Update ProcessTools.startProcess(...) to exit early if process exit before linePredicate is printed.
-
- Resolved
-