8236282: [macos] Find permanent solution to macOS test timeout problem JDK-8235738
Reviewed-by: herrick, asemenyuk
This commit is contained in:
parent
71d646a160
commit
976c469305
src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -25,8 +25,10 @@
|
||||
package jdk.incubator.jpackage.internal;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
@ -48,8 +50,8 @@ final public class Executor {
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor setWaitBeforeOutput(boolean v) {
|
||||
waitBeforeOutput = v;
|
||||
Executor setWriteOutputToFile(boolean v) {
|
||||
writeOutputToFile = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -80,8 +82,13 @@ final public class Executor {
|
||||
output = null;
|
||||
|
||||
boolean needProcessOutput = outputConsumer != null || Log.isVerbose() || saveOutput;
|
||||
File outputFile = null;
|
||||
if (needProcessOutput) {
|
||||
pb.redirectErrorStream(true);
|
||||
if (writeOutputToFile) {
|
||||
outputFile = File.createTempFile("jpackageOutputTempFile", ".tmp");
|
||||
pb.redirectOutput(outputFile);
|
||||
}
|
||||
} else {
|
||||
// We are not going to read process output, so need to notify
|
||||
// ProcessBuilder about this. Otherwise some processes might just
|
||||
@ -94,7 +101,7 @@ final public class Executor {
|
||||
Process p = pb.start();
|
||||
|
||||
int code = 0;
|
||||
if (waitBeforeOutput) {
|
||||
if (writeOutputToFile) {
|
||||
try {
|
||||
code = p.waitFor();
|
||||
} catch (InterruptedException ex) {
|
||||
@ -104,25 +111,17 @@ final public class Executor {
|
||||
}
|
||||
|
||||
if (needProcessOutput) {
|
||||
try (var br = new BufferedReader(new InputStreamReader(
|
||||
p.getInputStream()))) {
|
||||
final List<String> savedOutput;
|
||||
// Need to save output if explicitely requested (saveOutput=true) or
|
||||
// if will be used used by multiple consumers
|
||||
if ((outputConsumer != null && Log.isVerbose()) || saveOutput) {
|
||||
savedOutput = br.lines().collect(Collectors.toList());
|
||||
if (saveOutput) {
|
||||
output = savedOutput;
|
||||
}
|
||||
} else {
|
||||
savedOutput = null;
|
||||
}
|
||||
final List<String> savedOutput;
|
||||
Supplier<Stream<String>> outputStream;
|
||||
|
||||
Supplier<Stream<String>> outputStream = () -> {
|
||||
if (writeOutputToFile) {
|
||||
savedOutput = Files.readAllLines(outputFile.toPath());
|
||||
outputFile.delete();
|
||||
outputStream = () -> {
|
||||
if (savedOutput != null) {
|
||||
return savedOutput.stream();
|
||||
}
|
||||
return br.lines();
|
||||
return null;
|
||||
};
|
||||
|
||||
if (Log.isVerbose()) {
|
||||
@ -132,21 +131,50 @@ final public class Executor {
|
||||
if (outputConsumer != null) {
|
||||
outputConsumer.accept(outputStream.get());
|
||||
}
|
||||
} else {
|
||||
try (var br = new BufferedReader(new InputStreamReader(
|
||||
p.getInputStream()))) {
|
||||
// Need to save output if explicitely requested (saveOutput=true) or
|
||||
// if will be used used by multiple consumers
|
||||
if ((outputConsumer != null && Log.isVerbose()) || saveOutput) {
|
||||
savedOutput = br.lines().collect(Collectors.toList());
|
||||
if (saveOutput) {
|
||||
output = savedOutput;
|
||||
}
|
||||
} else {
|
||||
savedOutput = null;
|
||||
}
|
||||
|
||||
if (savedOutput == null) {
|
||||
// For some processes on Linux if the output stream
|
||||
// of the process is opened but not consumed, the process
|
||||
// would exit with code 141.
|
||||
// It turned out that reading just a single line of process
|
||||
// output fixes the problem, but let's process
|
||||
// all of the output, just in case.
|
||||
br.lines().forEach(x -> {});
|
||||
outputStream = () -> {
|
||||
if (savedOutput != null) {
|
||||
return savedOutput.stream();
|
||||
}
|
||||
return br.lines();
|
||||
};
|
||||
|
||||
if (Log.isVerbose()) {
|
||||
outputStream.get().forEach(Log::verbose);
|
||||
}
|
||||
|
||||
if (outputConsumer != null) {
|
||||
outputConsumer.accept(outputStream.get());
|
||||
}
|
||||
|
||||
if (savedOutput == null) {
|
||||
// For some processes on Linux if the output stream
|
||||
// of the process is opened but not consumed, the process
|
||||
// would exit with code 141.
|
||||
// It turned out that reading just a single line of process
|
||||
// output fixes the problem, but let's process
|
||||
// all of the output, just in case.
|
||||
br.lines().forEach(x -> {});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!waitBeforeOutput) {
|
||||
if (!writeOutputToFile) {
|
||||
code = p.waitFor();
|
||||
}
|
||||
return code;
|
||||
@ -175,7 +203,7 @@ final public class Executor {
|
||||
|
||||
private ProcessBuilder pb;
|
||||
private boolean saveOutput;
|
||||
private boolean waitBeforeOutput;
|
||||
private boolean writeOutputToFile;
|
||||
private List<String> output;
|
||||
private Consumer<Stream<String>> outputConsumer;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, 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
|
||||
@ -29,7 +29,6 @@ import java.io.*;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -136,12 +135,14 @@ public class IOUtils {
|
||||
exec(pb, false, null, false);
|
||||
}
|
||||
|
||||
// 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)
|
||||
// See JDK-8236282
|
||||
// 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 redirect the output to a temp file and then
|
||||
// read this file back.
|
||||
public static void exec(ProcessBuilder pb, boolean writeOutputToFile)
|
||||
throws IOException {
|
||||
exec(pb, false, null, waitBeforeOutput);
|
||||
exec(pb, false, null, writeOutputToFile);
|
||||
}
|
||||
|
||||
static void exec(ProcessBuilder pb, boolean testForPresenceOnly,
|
||||
@ -150,9 +151,10 @@ public class IOUtils {
|
||||
}
|
||||
|
||||
static void exec(ProcessBuilder pb, boolean testForPresenceOnly,
|
||||
PrintStream consumer, boolean waitBeforeOutput) throws IOException {
|
||||
PrintStream consumer, boolean writeOutputToFile) throws IOException {
|
||||
List<String> output = new ArrayList<>();
|
||||
Executor exec = Executor.of(pb).setWaitBeforeOutput(waitBeforeOutput).setOutputConsumer(lines -> {
|
||||
Executor exec = Executor.of(pb).setWriteOutputToFile(writeOutputToFile)
|
||||
.setOutputConsumer(lines -> {
|
||||
lines.forEach(output::add);
|
||||
if (consumer != null) {
|
||||
output.forEach(consumer::println);
|
||||
|
Loading…
x
Reference in New Issue
Block a user