From ae8730fd62b382564cda8749763b939aa2939225 Mon Sep 17 00:00:00 2001
From: Leonid Mesnik <lmesnik@openjdk.org>
Date: Mon, 6 Mar 2023 15:32:01 +0000
Subject: [PATCH] 8303486: [REDO] Update ProcessTools.startProcess(...) to exit
 early if process exit before linePredicate is printed.

Reviewed-by: dholmes
---
 .../jdk/test/lib/process/ProcessTools.java    | 20 ++++++++++++----
 .../jdk/test/lib/thread/ProcessThread.java    | 23 +++++++++++--------
 2 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java
index 4af8006882b..aa0957725fc 100644
--- a/test/lib/jdk/test/lib/process/ProcessTools.java
+++ b/test/lib/jdk/test/lib/process/ProcessTools.java
@@ -217,15 +217,25 @@ public final class ProcessTools {
 
         try {
             if (timeout > -1) {
-                if (timeout == 0) {
-                    latch.await();
-                } else {
-                    if (!latch.await(Utils.adjustTimeout(timeout), unit)) {
+
+                long timeoutMs = timeout == 0 ? -1: unit.toMillis(Utils.adjustTimeout(timeout));
+                // Every second check if line is printed and if process is still alive
+                Utils.waitForCondition(() -> latch.getCount() == 0 || !p.isAlive(),
+                       timeoutMs , 1000);
+
+                if (latch.getCount() > 0) {
+                    if (!p.isAlive()) {
+                        // Give some extra time for the StreamPumper to run after the process completed
+                        Thread.sleep(1000);
+                        if (latch.getCount() > 0) {
+                            throw new RuntimeException("Started process " + name + " terminated before producing the expected output.");
+                        }
+                    } else {
                         throw new TimeoutException();
                     }
                 }
             }
-        } catch (TimeoutException | InterruptedException e) {
+        } catch (TimeoutException | RuntimeException | InterruptedException e) {
             System.err.println("Failed to start a process (thread dump follows)");
             for (Map.Entry<Thread, StackTraceElement[]> s : Thread.getAllStackTraces().entrySet()) {
                 printStack(s.getKey(), s.getValue());
diff --git a/test/lib/jdk/test/lib/thread/ProcessThread.java b/test/lib/jdk/test/lib/thread/ProcessThread.java
index ff4b56fd459..75fd76a7a04 100644
--- a/test/lib/jdk/test/lib/thread/ProcessThread.java
+++ b/test/lib/jdk/test/lib/thread/ProcessThread.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -150,16 +150,21 @@ public class ProcessThread extends TestThread {
          */
         @Override
         public void xrun() throws Throwable {
-            this.process = ProcessTools.startProcess(name, processBuilder, waitfor);
-            // Release when process is started
-            latch.countDown();
-
-            // Will block...
             try {
-                this.process.waitFor();
-                output = new OutputAnalyzer(this.process);
+                this.process = ProcessTools.startProcess(name, processBuilder, waitfor);
+            } catch (Throwable t) {
+                System.out.println(String.format("ProcessThread[%s] failed: %s", name, t.toString()));
+                throw t;
+            } finally {
+                // Release when process is started or failed
+                latch.countDown();
+            }
+
+            try {
+                output = new OutputAnalyzer(this.process);
+                // Will block...
+                this.process.waitFor();
             } catch (Throwable t) {
-                String name = Thread.currentThread().getName();
                 System.out.println(String.format("ProcessThread[%s] failed: %s", name, t.toString()));
                 throw t;
             } finally {