|  | @@ -22,10 +22,15 @@ import com.carrotsearch.gradle.junit4.RandomizedTestingTask
 | 
	
		
			
				|  |  |  import org.elasticsearch.gradle.BuildPlugin
 | 
	
		
			
				|  |  |  import org.gradle.api.DefaultTask
 | 
	
		
			
				|  |  |  import org.gradle.api.Task
 | 
	
		
			
				|  |  | +import org.gradle.api.execution.TaskExecutionAdapter
 | 
	
		
			
				|  |  |  import org.gradle.api.internal.tasks.options.Option
 | 
	
		
			
				|  |  |  import org.gradle.api.plugins.JavaBasePlugin
 | 
	
		
			
				|  |  |  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.
 | 
	
	
		
			
				|  | @@ -71,6 +76,24 @@ public class RestIntegTestTask extends DefaultTask {
 | 
	
		
			
				|  |  |          // both as separate sysprops
 | 
	
		
			
				|  |  |          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
 | 
	
		
			
				|  |  |          RestSpecHack.configureDependencies(project)
 | 
	
		
			
				|  |  |          project.afterEvaluate {
 | 
	
	
		
			
				|  | @@ -126,4 +149,42 @@ public class RestIntegTestTask extends DefaultTask {
 | 
	
		
			
				|  |  |      public Task mustRunAfter(Object... 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('=========================================')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 |