Skip to content

Commit 4297208

Browse files
authored
Add a "keepProperties" option (#546)
1 parent 4340188 commit 4297208

File tree

11 files changed

+153
-54
lines changed

11 files changed

+153
-54
lines changed

src/main/java/hudson/tasks/junit/CaseResult.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public CaseResult(
161161
this.properties = Collections.emptyMap();
162162
}
163163

164-
CaseResult(SuiteResult parent, Element testCase, String testClassName, boolean keepLongStdio) {
164+
CaseResult(SuiteResult parent, Element testCase, String testClassName, boolean keepLongStdio, boolean keepProperties) {
165165
// schema for JUnit report XML format is not available in Ant,
166166
// so I don't know for sure what means what.
167167
// reports in http://www.nabble.com/difference-in-junit-publisher-and-ant-junitreport-tf4308604.html#a12265700
@@ -199,15 +199,17 @@ public CaseResult(
199199

200200
// parse properties
201201
Map<String, String> properties = new HashMap<String, String>();
202-
Element properties_element = testCase.element("properties");
203-
if (properties_element != null) {
204-
List<Element> property_elements = properties_element.elements("property");
205-
for (Element prop : property_elements){
206-
if (prop.attributeValue("name") != null) {
207-
if (prop.attributeValue("value") != null)
208-
properties.put(prop.attributeValue("name"), prop.attributeValue("value"));
209-
else
210-
properties.put(prop.attributeValue("name"), prop.getText());
202+
if (keepProperties) {
203+
Element properties_element = testCase.element("properties");
204+
if (properties_element != null) {
205+
List<Element> property_elements = properties_element.elements("property");
206+
for (Element prop : property_elements){
207+
if (prop.attributeValue("name") != null) {
208+
if (prop.attributeValue("value") != null)
209+
properties.put(prop.attributeValue("name"), prop.attributeValue("value"));
210+
else
211+
properties.put(prop.attributeValue("name"), prop.getText());
212+
}
211213
}
212214
}
213215
}

src/main/java/hudson/tasks/junit/JUnitParser.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public class JUnitParser extends TestResultParser {
5353
private static final Logger LOGGER = Logger.getLogger(JUnitParser.class.getName());
5454

5555
private final boolean keepLongStdio;
56+
private final boolean keepProperties;
5657
private final boolean allowEmptyResults;
5758

5859
private final boolean skipOldReports;
@@ -69,7 +70,7 @@ public JUnitParser() {
6970
*/
7071
@Deprecated
7172
public JUnitParser(boolean keepLongStdio) {
72-
this(keepLongStdio , false, false);
73+
this(keepLongStdio , false, false, false);
7374
}
7475

7576
/**
@@ -79,11 +80,12 @@ public JUnitParser(boolean keepLongStdio) {
7980
*/
8081
@Deprecated
8182
public JUnitParser(boolean keepLongStdio, boolean allowEmptyResults) {
82-
this(keepLongStdio , allowEmptyResults, false);
83+
this(keepLongStdio, false, allowEmptyResults, false);
8384
}
8485

85-
public JUnitParser(boolean keepLongStdio, boolean allowEmptyResults, boolean skipOldReports) {
86+
public JUnitParser(boolean keepLongStdio, boolean keepProperties, boolean allowEmptyResults, boolean skipOldReports) {
8687
this.keepLongStdio = keepLongStdio;
88+
this.keepProperties = keepProperties;
8789
this.allowEmptyResults = allowEmptyResults;
8890
this.skipOldReports = skipOldReports;
8991
}
@@ -115,14 +117,14 @@ public TestResult parseResult(String testResultLocations, Run<?,?> build, FilePa
115117
public TestResult parseResult(String testResultLocations, Run<?,?> build, PipelineTestDetails pipelineTestDetails,
116118
FilePath workspace, Launcher launcher, TaskListener listener)
117119
throws InterruptedException, IOException {
118-
return workspace.act(new DirectParseResultCallable(testResultLocations, build, keepLongStdio, allowEmptyResults,
120+
return workspace.act(new DirectParseResultCallable(testResultLocations, build, keepLongStdio, keepProperties, allowEmptyResults,
119121
pipelineTestDetails, listener, skipOldReports));
120122
}
121123

122124
public TestResultSummary summarizeResult(String testResultLocations, Run<?,?> build, PipelineTestDetails pipelineTestDetails,
123125
FilePath workspace, Launcher launcher, TaskListener listener, JunitTestResultStorage storage)
124126
throws InterruptedException, IOException {
125-
return workspace.act(new StorageParseResultCallable(testResultLocations, build, keepLongStdio, allowEmptyResults,
127+
return workspace.act(new StorageParseResultCallable(testResultLocations, build, keepLongStdio, keepProperties, allowEmptyResults,
126128
pipelineTestDetails, listener, storage.createRemotePublisher(build), skipOldReports));
127129
}
128130

@@ -136,21 +138,23 @@ private static abstract class ParseResultCallable<T> extends MasterToSlaveFileCa
136138
private final String testResults;
137139
private final long nowMaster;
138140
private final boolean keepLongStdio;
141+
private final boolean keepProperties;
139142
private final boolean allowEmptyResults;
140143
private final PipelineTestDetails pipelineTestDetails;
141144
private final TaskListener listener;
142145

143146
private boolean skipOldReports;
144147

145148
private ParseResultCallable(String testResults, Run<?,?> build,
146-
boolean keepLongStdio, boolean allowEmptyResults,
149+
boolean keepLongStdio, boolean keepProperties, boolean allowEmptyResults,
147150
PipelineTestDetails pipelineTestDetails, TaskListener listener,
148151
boolean skipOldReports) {
149152
this.buildStartTimeInMillis = build.getStartTimeInMillis();
150153
this.buildTimeInMillis = build.getTimeInMillis();
151154
this.testResults = testResults;
152155
this.nowMaster = System.currentTimeMillis();
153156
this.keepLongStdio = keepLongStdio;
157+
this.keepProperties = keepProperties;
154158
this.allowEmptyResults = allowEmptyResults;
155159
this.pipelineTestDetails = pipelineTestDetails;
156160
this.listener = listener;
@@ -173,7 +177,7 @@ public T invoke(File ws, VirtualChannel channel) throws IOException {
173177
+ ",buildTimeInMillis:" + buildTimeInMillis + ",filesTimestamp:" + filesTimestamp + ",nowSlave:"
174178
+ nowSlave + ",nowMaster:" + nowMaster);
175179
}
176-
result = new TestResult(filesTimestamp, ds, keepLongStdio, pipelineTestDetails, skipOldReports);
180+
result = new TestResult(filesTimestamp, ds, keepLongStdio, keepProperties, pipelineTestDetails, skipOldReports);
177181
result.tally();
178182
} else {
179183
if (this.allowEmptyResults) {
@@ -193,9 +197,9 @@ public T invoke(File ws, VirtualChannel channel) throws IOException {
193197

194198
private static final class DirectParseResultCallable extends ParseResultCallable<TestResult> {
195199

196-
DirectParseResultCallable(String testResults, Run<?,?> build, boolean keepLongStdio, boolean allowEmptyResults,
200+
DirectParseResultCallable(String testResults, Run<?,?> build, boolean keepLongStdio, boolean keepProperties, boolean allowEmptyResults,
197201
PipelineTestDetails pipelineTestDetails, TaskListener listener, boolean skipOldReports) {
198-
super(testResults, build, keepLongStdio, allowEmptyResults, pipelineTestDetails, listener, skipOldReports);
202+
super(testResults, build, keepLongStdio, keepProperties, allowEmptyResults, pipelineTestDetails, listener, skipOldReports);
199203
}
200204

201205
@Override
@@ -209,9 +213,9 @@ private static final class StorageParseResultCallable extends ParseResultCallabl
209213

210214
private final RemotePublisher publisher;
211215

212-
StorageParseResultCallable(String testResults, Run<?,?> build, boolean keepLongStdio, boolean allowEmptyResults,
216+
StorageParseResultCallable(String testResults, Run<?,?> build, boolean keepLongStdio, boolean keepProperties, boolean allowEmptyResults,
213217
PipelineTestDetails pipelineTestDetails, TaskListener listener, RemotePublisher publisher, boolean skipOldReports) {
214-
super(testResults, build, keepLongStdio, allowEmptyResults, pipelineTestDetails, listener, skipOldReports);
218+
super(testResults, build, keepLongStdio, keepProperties, allowEmptyResults, pipelineTestDetails, listener, skipOldReports);
215219
this.publisher = publisher;
216220
}
217221

src/main/java/hudson/tasks/junit/JUnitResultArchiver.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public class JUnitResultArchiver extends Recorder implements SimpleBuildStep, JU
8585
*/
8686
private boolean keepLongStdio;
8787

88+
private boolean keepProperties;
8889
/**
8990
* {@link TestDataPublisher}s configured for this archiver, to process the recorded data.
9091
* For compatibility reasons, can be null.
@@ -125,17 +126,19 @@ public JUnitResultArchiver(
125126
String testResults,
126127
boolean keepLongStdio,
127128
DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers) {
128-
this(testResults, keepLongStdio, testDataPublishers, 1.0);
129+
this(testResults, keepLongStdio, false, testDataPublishers, 1.0);
129130
}
130131

131132
@Deprecated
132133
public JUnitResultArchiver(
133134
String testResults,
134135
boolean keepLongStdio,
136+
boolean keepProperties,
135137
DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers,
136138
double healthScaleFactor) {
137139
this.testResults = testResults;
138140
setKeepLongStdio(keepLongStdio);
141+
setKeepProperties(keepProperties);
139142
setTestDataPublishers(testDataPublishers == null ? Collections.emptyList() : testDataPublishers);
140143
setHealthScaleFactor(healthScaleFactor);
141144
setAllowEmptyResults(false);
@@ -153,7 +156,7 @@ private static TestResult parse(@NonNull JUnitTask task, PipelineTestDetails pip
153156
String expandedTestResults, Run<?,?> run, @NonNull FilePath workspace,
154157
Launcher launcher, TaskListener listener)
155158
throws IOException, InterruptedException {
156-
return new JUnitParser(task.isKeepLongStdio(), task.isAllowEmptyResults(), task.isSkipOldReports())
159+
return new JUnitParser(task.isKeepLongStdio(), task.isKeepProperties(), task.isAllowEmptyResults(), task.isSkipOldReports())
157160
.parseResult(expandedTestResults, run, pipelineTestDetails, workspace, launcher, listener);
158161
}
159162

@@ -252,7 +255,7 @@ public static TestResultSummary parseAndSummarize(@NonNull JUnitTask task, Pipel
252255
summary = null; // see below
253256
} else {
254257
result = new TestResult(storage.load(build.getParent().getFullName(), build.getNumber())); // irrelevant
255-
summary = new JUnitParser(task.isKeepLongStdio(), task.isAllowEmptyResults(), task.isSkipOldReports())
258+
summary = new JUnitParser(task.isKeepLongStdio(), task.isKeepProperties(), task.isAllowEmptyResults(), task.isSkipOldReports())
256259
.summarizeResult(testResults, build, pipelineTestDetails, workspace, launcher, listener, storage);
257260
}
258261

@@ -395,6 +398,18 @@ public boolean isKeepLongStdio() {
395398
this.keepLongStdio = keepLongStdio;
396399
}
397400

401+
/**
402+
* @return the keepProperties.
403+
*/
404+
@Override
405+
public boolean isKeepProperties() {
406+
return keepProperties;
407+
}
408+
409+
@DataBoundSetter public final void setKeepProperties(boolean keepProperties) {
410+
this.keepProperties = keepProperties;
411+
}
412+
398413
/**
399414
*
400415
* @return the allowEmptyResults
@@ -406,8 +421,8 @@ public boolean isAllowEmptyResults() {
406421

407422
/**
408423
* Should we skip publishing checks to the checks API plugin.
409-
*
410-
* @return if publishing checks should be skipped, {@code false} otherwise
424+
*
425+
* @return if publishing checks should be skipped, {@code false} otherwise
411426
*/
412427
@Override
413428
public boolean isSkipPublishingChecks() {

src/main/java/hudson/tasks/junit/JUnitTask.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public interface JUnitTask {
1111

1212
boolean isKeepLongStdio();
1313

14+
boolean isKeepProperties();
15+
1416
boolean isAllowEmptyResults();
1517

1618
boolean isSkipPublishingChecks();

src/main/java/hudson/tasks/junit/SuiteResult.java

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,24 @@ public static class SuiteResultParserConfigurationContext {
155155
}
156156
}
157157

158+
@Deprecated
159+
static List<SuiteResult> parse(File xmlReport, boolean keepLongStdio, PipelineTestDetails pipelineTestDetails)
160+
throws DocumentException, IOException, InterruptedException {
161+
return parse(xmlReport, keepLongStdio, false, pipelineTestDetails);
162+
}
163+
158164
/**
159165
* Parses the JUnit XML file into {@link SuiteResult}s.
160166
* This method returns a collection, as a single XML may have multiple &lt;testsuite>
161167
* elements wrapped into the top-level &lt;testsuites>.
162168
*/
163-
static List<SuiteResult> parse(File xmlReport, boolean keepLongStdio, PipelineTestDetails pipelineTestDetails)
169+
static List<SuiteResult> parse(File xmlReport, boolean keepLongStdio, boolean keepProperties, PipelineTestDetails pipelineTestDetails)
164170
throws DocumentException, IOException, InterruptedException {
165171
List<SuiteResult> r = new ArrayList<>();
166172

167173
// parse into DOM
168174
SAXReader saxReader = new SAXReader();
169-
175+
170176
//source: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet => SAXReader
171177
// setFeatureQuietly(saxReader, "http://apache.org/xml/features/disallow-doctype-decl", true);
172178
// setFeatureQuietly(saxReader, "http://xml.org/sax/features/external-parameter-entities", false);
@@ -180,7 +186,7 @@ static List<SuiteResult> parse(File xmlReport, boolean keepLongStdio, PipelineTe
180186
Document result = saxReader.read(xmlReportStream);
181187
Element root = result.getRootElement();
182188

183-
parseSuite(xmlReport, keepLongStdio, r, root, pipelineTestDetails);
189+
parseSuite(xmlReport, keepLongStdio, keepProperties, r, root, pipelineTestDetails);
184190
}
185191

186192
return r;
@@ -195,24 +201,28 @@ private static void setFeatureQuietly(SAXReader reader, String feature, boolean
195201
}
196202
}
197203

198-
private static void parseSuite(File xmlReport, boolean keepLongStdio, List<SuiteResult> r, Element root,
204+
private static void parseSuite(File xmlReport, boolean keepLongStdio, boolean keepProperties, List<SuiteResult> r, Element root,
199205
PipelineTestDetails pipelineTestDetails) throws DocumentException, IOException {
200206
// nested test suites
201207
List<Element> testSuites = root.elements("testsuite");
202208
for (Element suite : testSuites)
203-
parseSuite(xmlReport, keepLongStdio, r, suite, pipelineTestDetails);
209+
parseSuite(xmlReport, keepLongStdio, keepProperties, r, suite, pipelineTestDetails);
204210

205211
// child test cases
206212
// FIXME: do this also if no testcases!
207213
if (root.element("testcase") != null || root.element("error") != null)
208-
r.add(new SuiteResult(xmlReport, root, keepLongStdio, pipelineTestDetails));
214+
r.add(new SuiteResult(xmlReport, root, keepLongStdio, keepProperties, pipelineTestDetails));
209215
}
210216

217+
private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio, @CheckForNull PipelineTestDetails pipelineTestDetails)
218+
throws DocumentException, IOException {
219+
this(xmlReport, suite, keepLongStdio, false, pipelineTestDetails);
220+
}
211221
/**
212222
* @param xmlReport A JUnit XML report file whose top level element is 'testsuite'.
213223
* @param suite The parsed result of {@code xmlReport}
214224
*/
215-
private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio, @CheckForNull PipelineTestDetails pipelineTestDetails)
225+
private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio, boolean keepProperties, @CheckForNull PipelineTestDetails pipelineTestDetails)
216226
throws DocumentException, IOException {
217227
this.file = xmlReport.getAbsolutePath();
218228
String name = suite.attributeValue("name");
@@ -241,7 +251,7 @@ private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio, @Check
241251
Element ex = suite.element("error");
242252
if (ex != null) {
243253
// according to junit-noframes.xsl l.229, this happens when the test class failed to load
244-
addCase(new CaseResult(this, suite, "<init>", keepLongStdio));
254+
addCase(new CaseResult(this, suite, "<init>", keepLongStdio, keepProperties));
245255
}
246256

247257
List<Element> testCases = suite.elements("testcase");
@@ -265,7 +275,7 @@ private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio, @Check
265275
// one wants to use @name from <testsuite>,
266276
// the other wants to use @classname from <testcase>.
267277

268-
addCase(new CaseResult(this, e, classname, keepLongStdio));
278+
addCase(new CaseResult(this, e, classname, keepLongStdio, keepProperties));
269279
}
270280

271281
String stdout = CaseResult.possiblyTrimStdio(cases, keepLongStdio, suite.elementText("system-out"));
@@ -291,19 +301,20 @@ private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio, @Check
291301

292302
// parse properties
293303
Map<String, String> properties = new HashMap<String, String>();
294-
Element properties_element = suite.element("properties");
295-
if (properties_element != null) {
296-
List<Element> property_elements = properties_element.elements("property");
297-
for (Element prop : property_elements){
298-
if (prop.attributeValue("name") != null) {
299-
if (prop.attributeValue("value") != null)
300-
properties.put(prop.attributeValue("name"), prop.attributeValue("value"));
301-
else
302-
properties.put(prop.attributeValue("name"), prop.getText());
304+
if (keepProperties) {
305+
Element properties_element = suite.element("properties");
306+
if (properties_element != null) {
307+
List<Element> property_elements = properties_element.elements("property");
308+
for (Element prop : property_elements){
309+
if (prop.attributeValue("name") != null) {
310+
if (prop.attributeValue("value") != null)
311+
properties.put(prop.attributeValue("name"), prop.attributeValue("value"));
312+
else
313+
properties.put(prop.attributeValue("name"), prop.getText());
314+
}
303315
}
304316
}
305317
}
306-
307318
this.properties = properties;
308319
}
309320

0 commit comments

Comments
 (0)