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:
parent
b31ed6a75c
commit
ee802ad63c
|
@ -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('=========================================')
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue