mirror of https://github.com/apache/kafka.git
MINOR: Save failed test output to build output directory
Author: Ewen Cheslack-Postava <me@ewencp.org> Reviewers: Colin Patrick McCabe <colin@cmccabe.xyz> Closes #6234 from ewencp/test-logs
This commit is contained in:
parent
3656ad93bc
commit
ed3071231a
66
build.gradle
66
build.gradle
|
@ -15,6 +15,8 @@
|
|||
|
||||
import org.ajoberstar.grgit.Grgit
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -139,6 +141,7 @@ if (file('.git').exists()) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'java'
|
||||
// apply the eclipse plugin only to subprojects that hold code. 'connect' is just a folder.
|
||||
|
@ -204,6 +207,65 @@ subprojects {
|
|||
def testLoggingEvents = ["passed", "skipped", "failed"]
|
||||
def testShowStandardStreams = false
|
||||
def testExceptionFormat = 'full'
|
||||
// Gradle built-in logging only supports sending test output to stdout, which generates a lot
|
||||
// of noise, especially for passing tests. We really only want output for failed tests. This
|
||||
// hooks into the output and logs it (so we don't have to buffer it all in memory) and only
|
||||
// saves the output for failing tests. Directory and filenames are such that you can, e.g.,
|
||||
// create a Jenkins rule to collect failed test output.
|
||||
def logTestStdout = {
|
||||
def testId = { TestDescriptor descriptor ->
|
||||
"${descriptor.className}.${descriptor.name}".toString()
|
||||
}
|
||||
|
||||
def logFiles = new HashMap<String, File>()
|
||||
def logStreams = new HashMap<String, FileOutputStream>()
|
||||
beforeTest { TestDescriptor td ->
|
||||
def tid = testId(td)
|
||||
def logFile = new File(
|
||||
"${projectDir}/build/reports/testOutput/${tid}.test.stdout")
|
||||
logFile.parentFile.mkdirs()
|
||||
logFiles.put(tid, logFile)
|
||||
logStreams.put(tid, new FileOutputStream(logFile))
|
||||
}
|
||||
onOutput { TestDescriptor td, TestOutputEvent toe ->
|
||||
def tid = testId(td)
|
||||
// Some output can happen outside the context of a specific test (e.g. at the class level)
|
||||
// and beforeTest/afterTest seems to not be invoked for these cases (and similarly, there's
|
||||
// a TestDescriptor hierarchy that includes the thread executing the test, Gradle tasks,
|
||||
// etc). We see some of these in practice and it seems like something buggy in the Gradle
|
||||
// test runner since we see it *before* any tests and it is frequently not related to any
|
||||
// code in the test (best guess is that it is tail output from last test). We won't have
|
||||
// an output file for these, so simply ignore them. If they become critical for debugging,
|
||||
// they can be seen with showStandardStreams.
|
||||
if (td.name == td.className) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
logStreams.get(tid).write(toe.message.getBytes(StandardCharsets.UTF_8))
|
||||
} catch (Exception e) {
|
||||
println "ERROR: Failed to write output for test ${tid}"
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
afterTest { TestDescriptor td, TestResult tr ->
|
||||
def tid = testId(td)
|
||||
try {
|
||||
logStreams.get(tid).close()
|
||||
if (tr.resultType != TestResult.ResultType.FAILURE) {
|
||||
logFiles.get(tid).delete()
|
||||
} else {
|
||||
def file = logFiles.get(tid)
|
||||
println "${tid} failed, log available in ${file}"
|
||||
}
|
||||
} catch (Exception e) {
|
||||
println "ERROR: Failed to close stdout file for ${tid}"
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
logFiles.remove(tid)
|
||||
logStreams.remove(tid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
maxParallelForks = userMaxForks ?: Runtime.runtime.availableProcessors()
|
||||
|
@ -216,7 +278,7 @@ subprojects {
|
|||
showStandardStreams = userShowStandardStreams ?: testShowStandardStreams
|
||||
exceptionFormat = testExceptionFormat
|
||||
}
|
||||
|
||||
logTestStdout.rehydrate(delegate, owner, this)()
|
||||
}
|
||||
|
||||
task integrationTest(type: Test, dependsOn: compileJava) {
|
||||
|
@ -230,6 +292,7 @@ subprojects {
|
|||
showStandardStreams = userShowStandardStreams ?: testShowStandardStreams
|
||||
exceptionFormat = testExceptionFormat
|
||||
}
|
||||
logTestStdout.rehydrate(delegate, owner, this)()
|
||||
|
||||
useJUnit {
|
||||
includeCategories 'org.apache.kafka.test.IntegrationTest'
|
||||
|
@ -248,6 +311,7 @@ subprojects {
|
|||
showStandardStreams = userShowStandardStreams ?: testShowStandardStreams
|
||||
exceptionFormat = testExceptionFormat
|
||||
}
|
||||
logTestStdout.rehydrate(delegate, owner, this)()
|
||||
|
||||
if (it.project.name != 'generator') {
|
||||
useJUnit {
|
||||
|
|
Loading…
Reference in New Issue