Skip to content

Commit

Permalink
Spill output to temp files
Browse files Browse the repository at this point in the history
  • Loading branch information
madrob committed Jan 7, 2020
1 parent 28240bf commit b29c98b
Showing 1 changed file with 53 additions and 16 deletions.
69 changes: 53 additions & 16 deletions gradle/testing/defaults-tests.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -95,33 +95,28 @@ allprojects {
showStackTraces true
}

Map<String, ? extends Collection<String>> testOutput = new ConcurrentHashMap<>()
Map<String, TestOutputBuffer> testOutput = new ConcurrentHashMap<>()

onOutput { td, event ->
// This is our 'reproduce with' line, print it immediately, which will be right after the test failure message
if (event.destination == TestOutputEvent.Destination.StdErr && event.message.startsWith("NOTE: reproduce")) {
logger.error event.message
}

// TODO spill output to a file
if (event.message != null) {
if (event.destination == TestOutputEvent.Destination.StdErr && event.message.startsWith("NOTE: reproduce")) {
// This is our 'reproduce with' line, print it immediately, which will be right after the test failure message
logger.error event.message
}
String key = td.className + td.name
testOutput.computeIfAbsent(key, { k -> new ArrayList<String>() }).add(event.message)
testOutput.computeIfAbsent(key, { k -> new TestOutputBuffer(testsTmpDir, k) }).add(event)
}
}

afterTest { td, result ->
String key = td.className + td.name;
if (result.resultType == TestResult.ResultType.FAILURE) {
// This will print the test output, but not anything that comes from the suite (i.e. beforeTest or afterTest)
// Note that this output is printed before the corresponding failure trace, not sure it that is expected or not
def output = testOutput.get(key)
if (output != null) {
// need to strip trailing because unfortunately we saved the newline character earlier
output.forEach { s -> logger.error(s.stripTrailing()) }
testOutput.get(key).withCloseable { output ->
if (result.resultType == TestResult.ResultType.FAILURE) {
// This will print the test output, but not anything that comes from the suite (i.e. beforeTest or afterTest)
// Note that this output is printed before the corresponding failure trace, not sure it that is expected or not
output?.log(logger)
}
}
// Be careful with how much output we are buffering in memory - clean up!
testOutput.remove(key)
}
afterSuite { suite, result ->
Expand All @@ -142,3 +137,45 @@ allprojects {
}
}
}

class TestOutputBuffer implements Closeable {
private final File outputFile;
private final Writer writer;

TestOutputBuffer(File outputDirectory, String key) {
this.outputFile = new File(outputDirectory, key + ".out");
try {
FileOutputStream fos = new FileOutputStream(this.outputFile);
this.writer = new PrintWriter(new BufferedOutputStream(fos));
} catch (IOException e) {
throw new UncheckedIOException("Unable to create test suite output file", e);
}
}

void add(TestOutputEvent event) {
String prefix;
if (event.destination == TestOutputEvent.Destination.StdOut) {
prefix = " 1> ";
} else {
prefix = " 2> ";
}

try {
writer.write(prefix + event.message);
} catch (IOException e) {
throw new UncheckedIOException("Unable to write test suite output", e);
}
}

void log(Logger logger) {
outputFile.eachLine { line ->
logger.error(line)
}
}

@Override
void close() throws IOException {
writer.close();
outputFile.delete();
}
}

0 comments on commit b29c98b

Please sign in to comment.