8306946: jdk/test/lib/process/ProcessToolsStartProcessTest.java fails with "wrong number of lines in OutputAnalyzer output"

Reviewed-by: dholmes
This commit is contained in:
Leonid Mesnik
2023-05-04 01:10:54 +00:00
parent 03030d47eb
commit 64ac9a05e8
2 changed files with 45 additions and 34 deletions

View File

@@ -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);
}
}
}

View File

@@ -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) {