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