Skip to content

Commit

Permalink
Add support for 'properties' (#541)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjhiblot authored Jun 21, 2023
1 parent af5d6b5 commit a2f9db3
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/main/java/hudson/tasks/junit/CaseResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
Expand Down Expand Up @@ -78,6 +80,7 @@ public class CaseResult extends TestResult implements Comparable<CaseResult> {
private final String skippedMessage;
private final String errorStackTrace;
private final String errorDetails;
private final Map<String, String> properties;
@SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = "Specific method to restore it")
private transient SuiteResult parent;

Expand Down Expand Up @@ -129,6 +132,7 @@ public CaseResult(SuiteResult parent, String testName, String errorStackTrace, S
this.duration = 0.0f;
this.skipped = false;
this.skippedMessage = null;
this.properties = Collections.emptyMap();
}

@Restricted(Beta.class)
Expand All @@ -154,6 +158,7 @@ public CaseResult(

this.skipped = skippedMessage != null;
this.skippedMessage = skippedMessage;
this.properties = Collections.emptyMap();
}

CaseResult(SuiteResult parent, Element testCase, String testClassName, boolean keepLongStdio) {
Expand Down Expand Up @@ -191,6 +196,22 @@ public CaseResult(
Collection<CaseResult> _this = Collections.singleton(this);
stdout = fixNULs(possiblyTrimStdio(_this, keepLongStdio, testCase.elementText("system-out")));
stderr = fixNULs(possiblyTrimStdio(_this, keepLongStdio, testCase.elementText("system-err")));

// parse properties
Map<String, String> properties = new HashMap<String, String>();
Element properties_element = testCase.element("properties");
if (properties_element != null) {
List<Element> property_elements = properties_element.elements("property");
for (Element prop : property_elements){
if (prop.attributeValue("name") != null) {
if (prop.attributeValue("value") != null)
properties.put(prop.attributeValue("name"), prop.attributeValue("value"));
else
properties.put(prop.attributeValue("name"), prop.getText());
}
}
}
this.properties = properties;
}

static String possiblyTrimStdio(Collection<CaseResult> results, boolean keepLongStdio, String stdio) { // HUDSON-6516
Expand Down Expand Up @@ -613,6 +634,12 @@ public String getErrorDetails() {
return errorDetails;
}

@Exported
@Override
public Map<String, String> getProperties() {
return properties;
}

/**
* @return true if the test was not skipped and did not fail, false otherwise.
*/
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/hudson/tasks/junit/SuiteResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public final class SuiteResult implements Serializable {
private final String stdout;
private final String stderr;
private float duration;
private final Map<String, String> properties;

/**
* The 'timestamp' attribute of the test suite.
* AFAICT, this is not a required attribute in XML, so the value may be null.
Expand Down Expand Up @@ -125,6 +127,7 @@ public SuiteResult(String name, String stdout, String stderr, @CheckForNull Pipe
this.nodeId = null;
}
this.file = null;
this.properties = Collections.emptyMap();
}

private synchronized Map<String, CaseResult> casesByName() {
Expand Down Expand Up @@ -285,6 +288,23 @@ private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio, @Check

this.stdout = CaseResult.fixNULs(stdout);
this.stderr = CaseResult.fixNULs(stderr);

// parse properties
Map<String, String> properties = new HashMap<String, String>();
Element properties_element = suite.element("properties");
if (properties_element != null) {
List<Element> property_elements = properties_element.elements("property");
for (Element prop : property_elements){
if (prop.attributeValue("name") != null) {
if (prop.attributeValue("value") != null)
properties.put(prop.attributeValue("name"), prop.attributeValue("value"));
else
properties.put(prop.attributeValue("name"), prop.getText());
}
}
}

this.properties = properties;
}

public void addCase(CaseResult cr) {
Expand Down Expand Up @@ -379,6 +399,16 @@ public String getStderr() {
return stderr;
}

/**
* The properties of this test.
*
* @return the properties of this test.
*/
@Exported
public Map<String, String> getProperties() {
return properties;
}

/**
* The absolute path to the original test report. OS-dependent.
*
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/hudson/tasks/junit/TestResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,11 @@ public String getStderr() {
return sb.toString();
}

@Override
public Map<String, String> getProperties() {
return Collections.emptyMap();
}

/**
* If there was an error or a failure, this is the stack trace, or otherwise null.
*/
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/hudson/tasks/test/TestResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import hudson.model.Result;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;

import static java.util.Collections.emptyList;

Expand Down Expand Up @@ -249,6 +251,10 @@ public String getErrorDetails() {
return "";
}

public Map<String, String> getProperties() {
return Collections.emptyMap();
}

/**
* @return true if the test was not skipped and did not fail, false otherwise.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/hudson/tasks/junit/CaseResult/index.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ THE SOFTWARE.
</j:forEach>
</table>

<j:forEach var="p" items="${it.properties}">
<h3>${p.key}</h3>
<pre><j:out value="${p.value}"/></pre>
</j:forEach>

<j:if test="${!empty(it.skippedMessage)}">
<h3>${%Skip Message}</h3>
<pre><j:out value="${it.annotate(it.skippedMessage)}"/></pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ THE SOFTWARE.
<j:set var="id" value="${h.generateId()}"/>

<local:item id="${id}" name="error" title="${%Error Details}" value="${it.errorDetails}" opened="true"/>
<j:forEach var="p" items="${it.properties}">
<local:item id="${id}" name="${p.key}" title="${p.key}" value="${p.value}"/>
</j:forEach>
<local:item id="${id}" name="stacktrace" title="${%Stack Trace}" value="${it.errorStackTrace}"/>
<local:item id="${id}" name="stdout" title="${%Standard Output}" value="${it.stdout}"/>
<local:item id="${id}" name="stderr" title="${%Standard Error}" value="${it.stderr}"/>
Expand Down
40 changes: 40 additions & 0 deletions src/test/java/hudson/tasks/junit/CaseResultTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -340,6 +341,45 @@ public void emptyName() throws Exception {
rule.buildAndAssertSuccess(p);
}

@Test
public void testProperties() throws Exception {
String projectName = "properties-test";
String testResultResourceFile = "junit-report-with-properties.xml";

FreeStyleProject p = rule.createFreeStyleProject(projectName);
p.getPublishersList().add(new JUnitResultArchiver("*.xml"));
p.getBuildersList().add(new TestBuilder() {
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
FilePath junitFile = build.getWorkspace().child("junit.xml");
junitFile.copyFrom(getClass().getResource(testResultResourceFile));
// sadly this can be flaky for 1ms.... (but hey changing to nano even in core might complicated :))
junitFile.touch(System.currentTimeMillis()+1L);
return true;
}
});
FreeStyleBuild b = rule.assertBuildStatus(Result.UNSTABLE, p.scheduleBuild2(0).get());

TestResult tr = b.getAction(TestResultAction.class).getResult();

assertEquals(1, tr.getSuites().size());

SuiteResult sr = tr.getSuite("io.jenkins.example.with.properties");
Map<String,String> props = sr.getProperties();
assertEquals(props.get("prop1"), "value1");
String[] lines = props.get("multiline").split("\n");
assertEquals("", lines[0]);
assertEquals(" Config line 1", lines[1]);
assertEquals(" Config line 2", lines[2]);
assertEquals(" Config line 3", lines[3]);

assertEquals(2, sr.getCases().size());
CaseResult cr;
cr = sr.getCase("io.jenkins.example.with.properties.testCaseA");
assertEquals("description of test testCaseA", cr.getProperties().get("description"));
cr = sr.getCase("io.jenkins.example.with.properties.testCaseZ");
assertEquals(0, cr.getProperties().size());
}

private String composeXPath(String[] fields) throws Exception {
StringBuilder tmp = new StringBuilder(100);
for ( String f : fields ) {
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/hudson/tasks/junit/SuiteResultTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.net.URISyntaxException;
import org.apache.commons.io.FileUtils;

Expand Down Expand Up @@ -352,4 +353,23 @@ public void testTestSuiteTimeAttribute() throws Exception {
assertEquals(40.0f, results.get(2).getDuration(), 2); //testsuit time
assertEquals(20.0f, results.get(3).getDuration(), 2); //sum of test cases time
}

@Test
public void testProperties() throws Exception {
SuiteResult sr = parseOne(getDataFile("junit-report-with-properties.xml"));
Map<String,String> props = sr.getProperties();
assertEquals(props.get("prop1"), "value1");
String[] lines = props.get("multiline").split("\n");
assertEquals("", lines[0]);
assertEquals(" Config line 1", lines[1]);
assertEquals(" Config line 2", lines[2]);
assertEquals(" Config line 3", lines[3]);

assertEquals(2, sr.getCases().size());
CaseResult cr;
cr = sr.getCase("io.jenkins.example.with.properties.testCaseA");
assertEquals("description of test testCaseA", cr.getProperties().get("description"));
cr = sr.getCase("io.jenkins.example.with.properties.testCaseZ");
assertEquals(0, cr.getProperties().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<testsuites>
<testsuite name="io.jenkins.example.with.properties" time="2.000" tests="2" errors="0" skipped="0" failures="1">
<properties>
<property name="prop1" value="value1" />
<property name="multiline">
Config line 1
Config line 2
Config line 3
</property>
</properties>
<testcase name="testCaseA" classname="io.jenkins.example.with.properties" time="1.000">
<failure message="expected: [a] but was: [b]" type="org.junit.ComparisonFailure">
org.junit.ComparisonFailure: expected: [a] but was: [b]
</failure>
<properties>
<property name="description">description of test testCaseA</property>
</properties>
</testcase>
<testcase name="testCaseZ" classname="io.jenkins.example.with.properties" time="1.000" />
</testsuite>
</testsuites>

0 comments on commit a2f9db3

Please sign in to comment.