Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8303133

Update ProcessTools.startProcess(...) to exit early if process exit before linePredicate is printed.

    XMLWordPrintable

Details

    • Enhancement
    • Resolution: Fixed
    • P4
    • 21
    • 21
    • hotspot
    • None
    • b12

    Description

      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.

      Attachments

        Issue Links

          Activity

            People

              lmesnik Leonid Mesnik
              lmesnik Leonid Mesnik
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: