Test: Add dump of integ test cluster logs on failure (#23688)

This commit adds a build listener to the integ test runner which will
print out an excerpt of the logs from the integ test cluster if the test
run fails.  There are future improvements that can be made (for example,
to dump excerpts from dependent clusters like in tribe node tests), but
this is a start, and would help with simple rest tests failures that we
currently don't know what actually happened on the node.
This commit is contained in:
Ryan Ernst 2017-03-21 23:26:07 -07:00 committed by GitHub
parent b31ed6a75c
commit ee802ad63c
1 changed files with 62 additions and 1 deletions

View File

@ -22,10 +22,15 @@ import com.carrotsearch.gradle.junit4.RandomizedTestingTask
import org.elasticsearch.gradle.BuildPlugin import org.elasticsearch.gradle.BuildPlugin
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.execution.TaskExecutionAdapter
import org.gradle.api.internal.tasks.options.Option import org.gradle.api.internal.tasks.options.Option
import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
import org.gradle.util.ConfigureUtil import org.gradle.api.tasks.TaskState
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.util.stream.Stream
/** /**
* A wrapper task around setting up a cluster and running rest tests. * A wrapper task around setting up a cluster and running rest tests.
@ -71,6 +76,24 @@ public class RestIntegTestTask extends DefaultTask {
// both as separate sysprops // both as separate sysprops
runner.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}") runner.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}")
// dump errors and warnings from cluster log on failure
TaskExecutionAdapter logDumpListener = new TaskExecutionAdapter() {
@Override
void afterExecute(Task task, TaskState state) {
if (state.failure != null) {
for (NodeInfo nodeInfo : nodes) {
printLogExcerpt(nodeInfo)
}
}
}
}
runner.doFirst {
project.gradle.addListener(logDumpListener)
}
runner.doLast {
project.gradle.removeListener(logDumpListener)
}
// copy the rest spec/tests into the test resources // copy the rest spec/tests into the test resources
RestSpecHack.configureDependencies(project) RestSpecHack.configureDependencies(project)
project.afterEvaluate { project.afterEvaluate {
@ -126,4 +149,42 @@ public class RestIntegTestTask extends DefaultTask {
public Task mustRunAfter(Object... tasks) { public Task mustRunAfter(Object... tasks) {
clusterInit.mustRunAfter(tasks) clusterInit.mustRunAfter(tasks)
} }
/** Print out an excerpt of the log from the given node. */
protected static void printLogExcerpt(NodeInfo nodeInfo) {
File logFile = new File(nodeInfo.homeDir, "logs/${nodeInfo.clusterName}.log")
println("\nCluster ${nodeInfo.clusterName} - node ${nodeInfo.nodeNum} log excerpt:")
println("(full log at ${logFile})")
println('-----------------------------------------')
Stream<String> stream = Files.lines(logFile.toPath(), StandardCharsets.UTF_8)
try {
boolean inStartup = true
boolean inExcerpt = false
int linesSkipped = 0
for (String line : stream) {
if (line.startsWith("[")) {
inExcerpt = false // clear with the next log message
}
if (line =~ /(\[WARN\])|(\[ERROR\])/) {
inExcerpt = true // show warnings and errors
}
if (inStartup || inExcerpt) {
if (linesSkipped != 0) {
println("... SKIPPED ${linesSkipped} LINES ...")
}
println(line)
linesSkipped = 0
} else {
++linesSkipped
}
if (line =~ /recovered \[\d+\] indices into cluster_state/) {
inStartup = false
}
}
} finally {
stream.close()
}
println('=========================================')
}
} }