Skip to content

Commit

Permalink
Merge pull request #857 from kgeilmann/fix_mess_on_stdout_stderr
Browse files Browse the repository at this point in the history
Pass data from stdout and stderr of spawned processes line by line to…
  • Loading branch information
hcoles authored Jan 18, 2021
2 parents ee02ad2 + b684173 commit eee3165
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import java.util.Collection;
import java.util.function.Consumer;

import static org.pitest.functional.prelude.Prelude.printWith;
import static org.pitest.functional.prelude.Prelude.printlnWith;

public class WorkerFactory {

Expand Down Expand Up @@ -58,7 +58,7 @@ public MutationTestProcess createWorker(
final ProcessArgs args = ProcessArgs.withClassPath(this.classPath)
.andLaunchOptions(this.config.getLaunchOptions())
.andBaseDir(this.baseDir).andStdout(captureStdOutIfVerbose())
.andStderr(printWith("stderr "));
.andStderr(printlnWith("stderr "));

final SocketFinder sf = new SocketFinder();
return new MutationTestProcess(
Expand All @@ -67,7 +67,7 @@ public MutationTestProcess createWorker(

private Consumer<String> captureStdOutIfVerbose() {
if (this.verbose) {
return Prelude.printWith("stdout ");
return printlnWith("stdout ");
} else {
return Prelude.noSideEffect(String.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
*/
package org.pitest.process;

import static org.pitest.functional.prelude.Prelude.print;
import static org.pitest.functional.prelude.Prelude.printTo;
import static org.pitest.functional.prelude.Prelude.println;
import static org.pitest.functional.prelude.Prelude.printlnTo;

import java.io.File;
import java.util.Collections;
Expand All @@ -28,8 +28,8 @@
public final class ProcessArgs {

private final String launchClassPath;
private Consumer<String> stdout = print(String.class);
private Consumer<String> stdErr = printTo(String.class, System.err);
private Consumer<String> stdout = println(String.class);
private Consumer<String> stdErr = printlnTo(String.class, System.err);
private List<String> jvmArgs = Collections.emptyList();
private JavaAgent javaAgentFinder;
private File workingDir = null;
Expand Down
21 changes: 14 additions & 7 deletions pitest-entry/src/main/java/org/pitest/util/StreamMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,25 @@
*/
package org.pitest.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.function.Consumer;
import java.util.logging.Logger;

public class StreamMonitor extends Thread implements Monitor {
private static final Logger LOG = Log.getLogger();

private final byte[] buf = new byte[256];
private final InputStream in;
private final Consumer<String> inputHandler;

/**
* Constructor.
* @param in stream to read from
* @param inputHandler all characters read from {@code in} will be forwarded
* line by line (without the newline) to this handler.
*/
public StreamMonitor(final InputStream in,
final Consumer<String> inputHandler) {
super("PIT Stream Monitor");
Expand All @@ -41,25 +48,25 @@ public void requestStart() {

@Override
public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(this.in));
while (!this.isInterrupted()) {
readFromStream();
readFromStream(reader);
}
}

private void readFromStream() {
private void readFromStream(final BufferedReader reader) {
try {

// If child JVM crashes reading stdout/stderr seems to sometimes
// block and consume 100% cpu, so check stream is available first.
// May still be an issue if child crashes during later read . . .
if (this.in.available() == 0) {
if (!reader.ready()) {
Thread.sleep(100);
return;
}

int i;
while ((i = this.in.read(this.buf, 0, this.buf.length)) != -1) {
final String output = new String(this.buf, 0, i);
String output;
while ( ( output = reader.readLine() ) != null ) {
this.inputHandler.accept(output);
}

Expand Down
20 changes: 10 additions & 10 deletions pitest/src/main/java/org/pitest/functional/prelude/Prelude.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,25 +73,25 @@ public static final <A> Function<A, A> id(final Class<A> type) {
return id();
}

public static final <T> Consumer<T> print() {
return printTo(System.out);
public static final <T> Consumer<T> println() {
return printlnTo(System.out);
}

public static final <T> Consumer<T> print(final Class<T> type) {
return print();
public static final <T> Consumer<T> println(final Class<T> type) {
return println();
}

public static final <T> Consumer<T> printTo(final Class<T> type,
public static final <T> Consumer<T> printlnTo(final Class<T> type,
final PrintStream stream) {
return printTo(stream);
return printlnTo(stream);
}

public static final <T> Consumer<T> printTo(final PrintStream stream) {
return a -> stream.print(a);
public static final <T> Consumer<T> printlnTo(final PrintStream stream) {
return a -> stream.println(a);
}

public static <T> Consumer<T> printWith(final T t) {
return a -> System.out.print(t + " : " + a);
public static <T> Consumer<T> printlnWith(final T t) {
return a -> System.out.println(t + " : " + a);
}

public static <T extends Number> Predicate<T> isGreaterThan(final T value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public class PreludeTest {
public void printToShouldPrintValueToStream() {
final Integer i = Integer.valueOf(42);
final PrintStream stream = Mockito.mock(PrintStream.class);
Prelude.printTo(stream).accept(i);
verify(stream).print(i);
Prelude.printlnTo(stream).accept(i);
verify(stream).println(i);
}

}

0 comments on commit eee3165

Please sign in to comment.