mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
8306946: jdk/test/lib/process/ProcessToolsStartProcessTest.java fails with "wrong number of lines in OutputAnalyzer output"
Reviewed-by: dholmes
This commit is contained in:
@@ -38,21 +38,21 @@ import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
public class ProcessToolsStartProcessTest {
|
||||
static final int NUM_LINES = 50;
|
||||
static String output = "";
|
||||
|
||||
private static Consumer<String> outputConsumer = s -> {
|
||||
output += s + "\n";
|
||||
};
|
||||
|
||||
static boolean testStartProcess(boolean withConsumer) throws Exception {
|
||||
static boolean testStartProcess(int numOfLines, boolean withConsumer) throws Exception {
|
||||
boolean success = true;
|
||||
output = "";
|
||||
Process p;
|
||||
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
|
||||
launcher.addToolArg("-cp");
|
||||
launcher.addToolArg(Utils.TEST_CLASSES);
|
||||
launcher.addToolArg("ProcessToolsStartProcessTest");
|
||||
launcher.addToolArg("test"); // This one argument triggers producing the output
|
||||
launcher.addToolArg(Integer.toString(numOfLines));
|
||||
ProcessBuilder pb = new ProcessBuilder();
|
||||
pb.command(launcher.getCommand());
|
||||
|
||||
@@ -73,49 +73,40 @@ public class ProcessToolsStartProcessTest {
|
||||
|
||||
if (withConsumer) {
|
||||
int numLines = output.split("\n").length;
|
||||
if (numLines != NUM_LINES ) {
|
||||
if (numLines != numOfLines) {
|
||||
System.out.print("FAILED: wrong number of lines in Consumer output\n");
|
||||
success = false;
|
||||
System.out.print(output);
|
||||
}
|
||||
System.out.println("DEBUG: Consumer output: got " + numLines + " lines , expected "
|
||||
+ NUM_LINES + ". Output follow:");
|
||||
System.out.print(output);
|
||||
System.out.println("DEBUG: done with Consumer output.");
|
||||
}
|
||||
|
||||
int numLinesOut = out.getStdout().split("\n").length;
|
||||
if (numLinesOut != NUM_LINES) {
|
||||
if (numLinesOut != numOfLines) {
|
||||
System.out.print("FAILED: wrong number of lines in OutputAnalyzer output\n");
|
||||
System.out.print(out.getStdout());
|
||||
success = false;
|
||||
}
|
||||
System.out.println("DEBUG: OutputAnalyzer output: got " + numLinesOut + " lines, expected "
|
||||
+ NUM_LINES + ". Output follows:");
|
||||
System.out.print(out.getStdout());
|
||||
System.out.println("DEBUG: done with OutputAnalyzer stdout.");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0) {
|
||||
for (int i = 0; i < NUM_LINES; i++) {
|
||||
System.out.println("A line on stdout " + i);
|
||||
int iter = Integer.parseInt(args[0]);
|
||||
for (int i = 0; i < iter; i++) {
|
||||
System.out.println("A line on stdout: " + i + " " + ".".repeat(i));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
boolean test1Result = testStartProcess(false);
|
||||
boolean test2Result = testStartProcess(true);
|
||||
if (!test1Result || !test2Result) {
|
||||
throw new RuntimeException("One or more tests failed. See output for details.");
|
||||
for (int i = 1; i < 5; i++) {
|
||||
System.out.println("ITERATION " + i);
|
||||
boolean test1Result = testStartProcess(i * 10 + i, false);
|
||||
if (!test1Result) {
|
||||
throw new RuntimeException("First test (no consumer) failed. See output for details.");
|
||||
}
|
||||
boolean test2Result = testStartProcess(i * 10 + i, true);
|
||||
if (!test2Result) {
|
||||
throw new RuntimeException("Second test (with consumer) failed. See output for details.");
|
||||
}
|
||||
} catch (RuntimeException re) {
|
||||
re.printStackTrace();
|
||||
System.out.println("Test ERROR");
|
||||
throw re;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.out.println("Test ERROR");
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
@@ -116,7 +117,7 @@ public final class ProcessTools {
|
||||
throws IOException {
|
||||
try {
|
||||
return startProcess(name, processBuilder, consumer, null, -1, TimeUnit.NANOSECONDS);
|
||||
} catch (InterruptedException | TimeoutException e) {
|
||||
} catch (InterruptedException | TimeoutException | CancellationException e) {
|
||||
// will never happen
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -158,23 +159,38 @@ public final class ProcessTools {
|
||||
BufferOutputStream and BufferInputStream allow to re-use p.getInputStream() amd p.getOutputStream() of
|
||||
processes started with ProcessTools.startProcess(...).
|
||||
Implementation cashes ALL process output and allow to read it through InputStream.
|
||||
The stream uses Future<Void> task from StreamPumper.process() to check if output is complete.
|
||||
*/
|
||||
private static class BufferOutputStream extends ByteArrayOutputStream {
|
||||
private int current = 0;
|
||||
final private Process p;
|
||||
|
||||
private Future<Void> task;
|
||||
|
||||
public BufferOutputStream(Process p) {
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
synchronized void setTask(Future<Void> task) {
|
||||
this.task = task;
|
||||
}
|
||||
synchronized int readNext() {
|
||||
if (current > count) {
|
||||
throw new RuntimeException("Shouldn't ever happen. start: "
|
||||
+ current + " count: " + count + " buffer: " + this);
|
||||
}
|
||||
while (current == count) {
|
||||
if (!p.isAlive()) {
|
||||
return -1;
|
||||
if (!p.isAlive() && (task != null)) {
|
||||
try {
|
||||
task.get(10, TimeUnit.MILLISECONDS);
|
||||
if (current == count) {
|
||||
return -1;
|
||||
}
|
||||
} catch (TimeoutException e) {
|
||||
// continue execution, so wait() give a chance to write
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
try {
|
||||
wait(1);
|
||||
@@ -194,7 +210,7 @@ public final class ProcessTools {
|
||||
buffer = new BufferOutputStream(p);
|
||||
}
|
||||
|
||||
OutputStream getOutputStream() {
|
||||
BufferOutputStream getOutputStream() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -242,6 +258,8 @@ public final class ProcessTools {
|
||||
|
||||
stdout.addPump(new LineForwarder(name, System.out));
|
||||
stderr.addPump(new LineForwarder(name, System.err));
|
||||
|
||||
|
||||
BufferInputStream stdOut = new BufferInputStream(p);
|
||||
BufferInputStream stdErr = new BufferInputStream(p);
|
||||
|
||||
@@ -259,7 +277,6 @@ public final class ProcessTools {
|
||||
stderr.addPump(pump);
|
||||
}
|
||||
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
if (linePredicate != null) {
|
||||
StreamPumper.LinePump pump = new StreamPumper.LinePump() {
|
||||
@@ -282,6 +299,9 @@ public final class ProcessTools {
|
||||
final Future<Void> stdoutTask = stdout.process();
|
||||
final Future<Void> stderrTask = stderr.process();
|
||||
|
||||
stdOut.getOutputStream().setTask(stdoutTask);
|
||||
stdErr.getOutputStream().setTask(stderrTask);
|
||||
|
||||
try {
|
||||
if (timeout > -1) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user