From 92a4ece1cd10b1be62f79b648cc3cd401872f8a3 Mon Sep 17 00:00:00 2001 From: Tim Jacomb <21194782+timja@users.noreply.github.com> Date: Tue, 21 Dec 2021 21:37:59 +0000 Subject: [PATCH] Pass task listener to JUnit parsing (#18) --- README.md | 4 +-- pom.xml | 1 - .../PipelineRealtimeTestResultAction.java | 34 +++++++++++++++++-- .../RealtimeJUnitStep.java | 20 ++++++++--- .../Messages.properties | 2 +- 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4e285e6..d2bc6c1 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ Publishes test results while tests run, rather than waiting for completion like ### Pipeline ```groovy -realtimeJUnit('target/test-results/*.xml') { - sh 'mvn verify' +realtimeJUnit('**/target/surefire-reports/TEST-*.xml') { + sh "mvn -Dmaven.test.failure.ignore=true clean package" } ``` diff --git a/pom.xml b/pom.xml index 21700f0..059c7f4 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,6 @@ org.jenkins-ci.plugins junit - 1.51 org.jenkins-ci.plugins diff --git a/src/main/java/org/jenkinsci/plugins/junitrealtimetestreporter/PipelineRealtimeTestResultAction.java b/src/main/java/org/jenkinsci/plugins/junitrealtimetestreporter/PipelineRealtimeTestResultAction.java index 483faef..40b8427 100644 --- a/src/main/java/org/jenkinsci/plugins/junitrealtimetestreporter/PipelineRealtimeTestResultAction.java +++ b/src/main/java/org/jenkinsci/plugins/junitrealtimetestreporter/PipelineRealtimeTestResultAction.java @@ -26,12 +26,22 @@ import hudson.AbortException; import hudson.FilePath; +import hudson.Launcher; +import hudson.model.TaskListener; import hudson.tasks.junit.JUnitParser; import hudson.tasks.junit.TestResult; +import hudson.tasks.junit.pipeline.JUnitResultsStepExecution; +import hudson.tasks.test.PipelineTestDetails; import java.io.IOException; +import java.util.List; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import org.jenkinsci.plugins.workflow.FilePathUtils; +import org.jenkinsci.plugins.workflow.graph.FlowNode; +import org.jenkinsci.plugins.workflow.steps.StepContext; + +import static java.util.Objects.requireNonNull; class PipelineRealtimeTestResultAction extends AbstractRealtimeTestResultAction { @@ -42,13 +52,21 @@ class PipelineRealtimeTestResultAction extends AbstractRealtimeTestResultAction private final String workspace; private final boolean keepLongStdio; private final String glob; + private final StepContext context; - PipelineRealtimeTestResultAction(String id, FilePath ws, boolean keepLongStdio, String glob) { + PipelineRealtimeTestResultAction( + String id, + FilePath ws, + boolean keepLongStdio, + String glob, + StepContext context + ) { this.id = id; node = FilePathUtils.getNodeName(ws); workspace = ws.getRemote(); this.keepLongStdio = keepLongStdio; this.glob = glob; + this.context = context; } @Override @@ -71,7 +89,19 @@ protected TestResult parse() throws IOException, InterruptedException { FilePath ws = FilePathUtils.find(node, workspace); if (ws != null && ws.isDirectory()) { LOGGER.log(Level.FINE, "parsing {0} in {1} on node {2} for {3}", new Object[] {glob, workspace, node, run}); - return new JUnitParser(keepLongStdio, true).parseResult(glob, run, ws, null, null); + + FlowNode node = context.get(FlowNode.class); + List enclosingBlocks = JUnitResultsStepExecution + .getEnclosingStagesAndParallels(requireNonNull(node)); + + PipelineTestDetails pipelineTestDetails = new PipelineTestDetails(); + pipelineTestDetails.setNodeId(id); + pipelineTestDetails.setEnclosingBlocks(JUnitResultsStepExecution.getEnclosingBlockIds(enclosingBlocks)); + pipelineTestDetails.setEnclosingBlockNames(JUnitResultsStepExecution.getEnclosingBlockNames(enclosingBlocks)); + + return new JUnitParser(keepLongStdio, true) + .parseResult(glob, run, pipelineTestDetails, ws, + context.get(Launcher.class), context.get(TaskListener.class)); } else { throw new AbortException("skipping parse in nonexistent workspace for " + run); } diff --git a/src/main/java/org/jenkinsci/plugins/junitrealtimetestreporter/RealtimeJUnitStep.java b/src/main/java/org/jenkinsci/plugins/junitrealtimetestreporter/RealtimeJUnitStep.java index e9ff26e..fdd6bab 100644 --- a/src/main/java/org/jenkinsci/plugins/junitrealtimetestreporter/RealtimeJUnitStep.java +++ b/src/main/java/org/jenkinsci/plugins/junitrealtimetestreporter/RealtimeJUnitStep.java @@ -43,6 +43,7 @@ import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -61,6 +62,8 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; +import static java.util.Objects.requireNonNull; + public class RealtimeJUnitStep extends Step { private static final Logger LOGGER = Logger.getLogger(RealtimeJUnitStep.class.getName()); @@ -151,11 +154,20 @@ static class Execution extends StepExecution { @Override public boolean start() throws Exception { - Run r = getContext().get(Run.class); - String id = getContext().get(FlowNode.class).getId(); - r.addAction(new PipelineRealtimeTestResultAction(id, getContext().get(FilePath.class), archiver.isKeepLongStdio(), archiver.getTestResults())); + StepContext context = getContext(); + Run r = context.get(Run.class); + FlowNode flowNode = context.get(FlowNode.class); + String id = requireNonNull(flowNode).getId(); + requireNonNull(r).addAction(new PipelineRealtimeTestResultAction( + id, + context.get(FilePath.class), + archiver.isKeepLongStdio(), + archiver.getTestResults(), + context + ) + ); AbstractRealtimeTestResultAction.saveBuild(r); - getContext().newBodyInvoker().withCallback(new Callback(id, archiver)).start(); + context.newBodyInvoker().withCallback(new Callback(id, archiver)).start(); return false; } diff --git a/src/main/resources/org/jenkinsci/plugins/junitrealtimetestreporter/Messages.properties b/src/main/resources/org/jenkinsci/plugins/junitrealtimetestreporter/Messages.properties index 2e5afde..a9268f1 100644 --- a/src/main/resources/org/jenkinsci/plugins/junitrealtimetestreporter/Messages.properties +++ b/src/main/resources/org/jenkinsci/plugins/junitrealtimetestreporter/Messages.properties @@ -22,4 +22,4 @@ PerJobConfiguration.visualize_test_results_in_real_time=Visualize test results in real time PipelineRealtimeTestResultAction.realtime_test_result_on_=Realtime Test Result on {0} -PipelineRealtimeTestResultAction.realtime_test_result_on_master=Realtime Test Result on Master +PipelineRealtimeTestResultAction.realtime_test_result_on_master=Realtime Test Result on Controller