changeset 57447:fb606350b732

8235738: [macos] tools/jpackage tests timeout on macOS Reviewed-by: herrick, asemenyuk
author almatvee
date Thu, 19 Dec 2019 15:20:53 -0500
parents ca3387704361
children 52485fd39fcb
files src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Executor.java src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java
diffstat 3 files changed, 38 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java	Thu Dec 19 14:19:34 2019 +0100
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java	Thu Dec 19 15:20:53 2019 -0500
@@ -289,7 +289,7 @@
                 protoDMG.getAbsolutePath(),
                 hdiUtilVerbosityFlag,
                 "-mountroot", imagesRoot.getAbsolutePath());
-        IOUtils.exec(pb);
+        IOUtils.exec(pb, false, null, true);
 
         File mountedRoot = new File(imagesRoot.getAbsolutePath(),
                     APP_NAME.fetchFrom(params));
--- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Executor.java	Thu Dec 19 14:19:34 2019 +0100
+++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Executor.java	Thu Dec 19 15:20:53 2019 -0500
@@ -48,6 +48,11 @@
         return this;
     }
 
+    Executor setWaitBeforeOutput(boolean v) {
+        waitBeforeOutput = v;
+        return this;
+    }
+
     Executor setProcessBuilder(ProcessBuilder v) {
         pb = v;
         return this;
@@ -88,6 +93,16 @@
         Log.verbose(String.format("Running %s", createLogMessage(pb)));
         Process p = pb.start();
 
+        int code = 0;
+        if (waitBeforeOutput) {
+            try {
+                code = p.waitFor();
+            } catch (InterruptedException ex) {
+                Log.verbose(ex);
+                throw new RuntimeException(ex);
+            }
+        }
+
         if (needProcessOutput) {
             try (var br = new BufferedReader(new InputStreamReader(
                     p.getInputStream()))) {
@@ -131,7 +146,10 @@
         }
 
         try {
-            return p.waitFor();
+            if (!waitBeforeOutput) {
+                code = p.waitFor();
+            }
+            return code;
         } catch (InterruptedException ex) {
             Log.verbose(ex);
             throw new RuntimeException(ex);
@@ -157,6 +175,7 @@
 
     private ProcessBuilder pb;
     private boolean saveOutput;
+    private boolean waitBeforeOutput;
     private List<String> output;
     private Consumer<Stream<String>> outputConsumer;
 }
--- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java	Thu Dec 19 14:19:34 2019 +0100
+++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java	Thu Dec 19 15:20:53 2019 -0500
@@ -147,20 +147,33 @@
 
     public static void exec(ProcessBuilder pb)
             throws IOException {
-        exec(pb, false, null);
+        exec(pb, false, null, false);
     }
 
-    static void exec(ProcessBuilder pb, boolean testForPresenseOnly,
+    // Reading output from some processes (currently known "hdiutil attach" might hang even if process already
+    // exited. Only possible workaround found in "hdiutil attach" case is to wait for process to exit before
+    // reading output.
+    public static void exec(ProcessBuilder pb, boolean waitBeforeOutput)
+            throws IOException {
+        exec(pb, false, null, waitBeforeOutput);
+    }
+
+    static void exec(ProcessBuilder pb, boolean testForPresenceOnly,
             PrintStream consumer) throws IOException {
+        exec(pb, testForPresenceOnly, consumer, false);
+    }
+
+    static void exec(ProcessBuilder pb, boolean testForPresenceOnly,
+            PrintStream consumer, boolean waitBeforeOutput) throws IOException {
         List<String> output = new ArrayList<>();
-        Executor exec = Executor.of(pb).setOutputConsumer(lines -> {
+        Executor exec = Executor.of(pb).setWaitBeforeOutput(waitBeforeOutput).setOutputConsumer(lines -> {
             lines.forEach(output::add);
             if (consumer != null) {
                 output.forEach(consumer::println);
             }
         });
 
-        if (testForPresenseOnly) {
+        if (testForPresenceOnly) {
             exec.execute();
         } else {
             exec.executeExpectSuccess();