提交 7ba6e1b1 编写于 作者: J jglick

[FIXED HUDSON-6516] Make stdio trimming optional.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@31016 71c3de6d-444a-0410-be80-ed276b4c234a
上级 876e8975
......@@ -93,7 +93,7 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul
return 0.0f;
}
CaseResult(SuiteResult parent, Element testCase, String testClassName) {
CaseResult(SuiteResult parent, Element testCase, String testClassName, boolean keepLongStdio) {
// schema for JUnit report XML format is not available in Ant,
// so I don't know for sure what means what.
// reports in http://www.nabble.com/difference-in-junit-publisher-and-ant-junitreport-tf4308604.html#a12265700
......@@ -125,15 +125,18 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul
skipped = isMarkedAsSkipped(testCase);
@SuppressWarnings("LeakingThisInConstructor")
Collection<CaseResult> _this = Collections.singleton(this);
stdout = possiblyTrimStdio(_this, testCase.elementText("system-out"));
stderr = possiblyTrimStdio(_this, testCase.elementText("system-err"));
stdout = possiblyTrimStdio(_this, keepLongStdio, testCase.elementText("system-out"));
stderr = possiblyTrimStdio(_this, keepLongStdio, testCase.elementText("system-err"));
}
private static final int HALF_MAX_SIZE = 500;
static String possiblyTrimStdio(Collection<CaseResult> results, String stdio) { // HUDSON-6516
static String possiblyTrimStdio(Collection<CaseResult> results, boolean keepLongStdio, String stdio) { // HUDSON-6516
if (stdio == null) {
return null;
}
if (keepLongStdio) {
return stdio;
}
for (CaseResult result : results) {
if (result.errorStackTrace != null) {
return stdio;
......
......@@ -41,6 +41,23 @@ import org.apache.tools.ant.DirectoryScanner;
*/
@Extension
public class JUnitParser extends TestResultParser {
private final boolean keepLongStdio;
/** XXX TestResultParser.all does not seem to ever be called so why must this be an Extension? */
@Deprecated
public JUnitParser() {
this(false);
}
/**
* @param keepLongStdio if true, retain a suite's complete stdout/stderr even if this is huge and the suite passed
* @since 1.358
*/
public JUnitParser(boolean keepLongStdio) {
this.keepLongStdio = keepLongStdio;
}
@Override
public String getDisplayName() {
return "JUnit Parser";
......@@ -63,7 +80,7 @@ public class JUnitParser extends TestResultParser {
// [BUG 3123310] TODO - Test Result Refactor: review and fix TestDataPublisher/TestAction subsystem]
// also get code that deals with testDataPublishers from JUnitResultArchiver.perform
TestResult testResult = build.getWorkspace().act( new ParseResultCallable(testResultLocations, buildTime, timeOnMaster));
TestResult testResult = build.getWorkspace().act( new ParseResultCallable(testResultLocations, buildTime, timeOnMaster, keepLongStdio));
return testResult;
}
......@@ -72,11 +89,13 @@ public class JUnitParser extends TestResultParser {
private final long buildTime;
private final String testResults;
private final long nowMaster;
private final boolean keepLongStdio;
private ParseResultCallable(String testResults, long buildTime, long nowMaster) {
private ParseResultCallable(String testResults, long buildTime, long nowMaster, boolean keepLongStdio) {
this.buildTime = buildTime;
this.testResults = testResults;
this.nowMaster = nowMaster;
this.keepLongStdio = keepLongStdio;
}
public TestResult invoke(File ws, VirtualChannel channel) throws IOException {
......@@ -92,7 +111,7 @@ public class JUnitParser extends TestResultParser {
throw new AbortException(Messages.JUnitResultArchiver_NoTestReportFound());
}
TestResult result = new TestResult(buildTime + (nowSlave - nowMaster), ds);
TestResult result = new TestResult(buildTime + (nowSlave - nowMaster), ds, keepLongStdio);
result.tally();
return result;
}
......
......@@ -75,6 +75,12 @@ public class JUnitResultArchiver extends Recorder implements Serializable,
*/
private final String testResults;
/**
* If true, retain a suite's complete stdout/stderr even if this is huge and the suite passed.
* @since 1.358
*/
private final boolean keepLongStdio;
/**
* {@link TestDataPublisher}s configured for this archiver, to process the recorded data.
* For compatibility reasons, can be null.
......@@ -88,14 +94,22 @@ public class JUnitResultArchiver extends Recorder implements Serializable,
*/
@Deprecated
public JUnitResultArchiver(String testResults) {
this(testResults, null);
this(testResults, false, null);
}
@Deprecated
public JUnitResultArchiver(String testResults,
DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers) {
this(testResults, false, testDataPublishers);
}
@DataBoundConstructor
public JUnitResultArchiver(
String testResults,
boolean keepLongStdio,
DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers) {
this.testResults = testResults;
this.keepLongStdio = keepLongStdio;
this.testDataPublishers = testDataPublishers;
}
......@@ -105,8 +119,7 @@ public class JUnitResultArchiver extends Recorder implements Serializable,
protected TestResult parse(String expandedTestResults, AbstractBuild build, Launcher launcher, BuildListener listener)
throws IOException, InterruptedException
{
TestResult result = (new JUnitParser()).parse(expandedTestResults, build, launcher, listener);
return result;
return new JUnitParser(keepLongStdio).parse(expandedTestResults, build, launcher, listener);
}
public boolean perform(AbstractBuild build, Launcher launcher,
......@@ -226,6 +239,7 @@ public class JUnitResultArchiver extends Recorder implements Serializable,
public Publisher newInstance(StaplerRequest req, JSONObject formData)
throws hudson.model.Descriptor.FormException {
String testResults = formData.getString("testResults");
boolean keepLongStdio = formData.getBoolean("keepLongStdio");
DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers = new DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>>(
new Saveable() {
public void save() throws IOException {
......@@ -234,7 +248,7 @@ public class JUnitResultArchiver extends Recorder implements Serializable,
});
testDataPublishers.rebuild(req, formData, TestDataPublisher.all());
return new JUnitResultArchiver(testResults, testDataPublishers);
return new JUnitResultArchiver(testResults, keepLongStdio, testDataPublishers);
}
/**
......
......@@ -82,7 +82,7 @@ public final class SuiteResult implements Serializable {
* This method returns a collection, as a single XML may have multiple &lt;testsuite>
* elements wrapped into the top-level &lt;testsuites>.
*/
static List<SuiteResult> parse(File xmlReport) throws DocumentException {
static List<SuiteResult> parse(File xmlReport, boolean keepLongStdio) throws DocumentException {
List<SuiteResult> r = new ArrayList<SuiteResult>();
// parse into DOM
......@@ -97,16 +97,16 @@ public final class SuiteResult implements Serializable {
if(root.getName().equals("testsuites")) {
// multi-suite file
for (Element suite : (List<Element>)root.elements("testsuite"))
r.add(new SuiteResult(xmlReport,suite));
r.add(new SuiteResult(xmlReport, suite, keepLongStdio));
} else {
// single suite file
r.add(new SuiteResult(xmlReport,root));
r.add(new SuiteResult(xmlReport, root, keepLongStdio));
}
return r;
}
private SuiteResult(File xmlReport, Element suite) throws DocumentException {
private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio) throws DocumentException {
this.file = xmlReport.getAbsolutePath();
String name = suite.attributeValue("name");
if(name==null)
......@@ -123,7 +123,7 @@ public final class SuiteResult implements Serializable {
Element ex = suite.element("error");
if(ex!=null) {
// according to junit-noframes.xsl l.229, this happens when the test class failed to load
addCase(new CaseResult(this,suite,"<init>"));
addCase(new CaseResult(this, suite, "<init>", keepLongStdio));
}
for (Element e : (List<Element>)suite.elements("testcase")) {
......@@ -146,11 +146,11 @@ public final class SuiteResult implements Serializable {
// one wants to use @name from <testsuite>,
// the other wants to use @classname from <testcase>.
addCase(new CaseResult(this, e, classname));
addCase(new CaseResult(this, e, classname, keepLongStdio));
}
stdout = CaseResult.possiblyTrimStdio(cases, suite.elementText("system-out"));
stderr = CaseResult.possiblyTrimStdio(cases, suite.elementText("system-err"));
stdout = CaseResult.possiblyTrimStdio(cases, keepLongStdio, suite.elementText("system-out"));
stderr = CaseResult.possiblyTrimStdio(cases, keepLongStdio, suite.elementText("system-err"));
}
/*package*/ void addCase(CaseResult cr) {
......
......@@ -86,19 +86,29 @@ public final class TestResult extends MetaTabulatedResult {
* Number of failed/error tests.
*/
private transient List<CaseResult> failedTests;
private final boolean keepLongStdio;
/**
* Creates an empty result.
*/
public TestResult() {
keepLongStdio = false;
}
@Deprecated
public TestResult(long buildTime, DirectoryScanner results) throws IOException {
this(buildTime, results, false);
}
/**
* Collect reports from the given {@link DirectoryScanner}, while
* filtering out all files that were created before the given time.
* @param keepLongStdio if true, retain a suite's complete stdout/stderr even if this is huge and the suite passed
* @since 1.358
*/
public TestResult(long buildTime, DirectoryScanner results) throws IOException {
this();
public TestResult(long buildTime, DirectoryScanner results, boolean keepLongStdio) throws IOException {
this.keepLongStdio = keepLongStdio;
parse(buildTime, results);
}
......@@ -180,7 +190,7 @@ public final class TestResult extends MetaTabulatedResult {
*/
public void parse(File reportFile) throws IOException {
try {
for( SuiteResult suiteResult : SuiteResult.parse(reportFile) )
for (SuiteResult suiteResult : SuiteResult.parse(reportFile, keepLongStdio))
add(suiteResult);
} catch (RuntimeException e) {
throw new IOException2("Failed to read "+reportFile,e);
......
......@@ -28,6 +28,10 @@ THE SOFTWARE.
field="testResults">
<f:textbox />
</f:entry>
<f:entry field="keepLongStdio" title="">
<f:checkbox/>
<label class="attach-previous">${%Retain long standard output/error}</label>
</f:entry>
<j:invokeStatic var="testDataPublisherDescriptors"
className="hudson.tasks.junit.TestDataPublisher" method="all" />
<j:if test="${testDataPublisherDescriptors.size() > 0}">
......
<div>
If checked, any standard output or error from a test suite will be retained
in the test results after the build completes. (This refers only to additional
messages printed to console, not to a failure stack trace.) Such output is
always kept if the test failed, but by default lengthy output from passing
tests is truncated to save space. Check this option if you need to see every
log message from even passing tests, but beware that Hudson's memory consumption
can substantially increase as a result, even if you never look at the test results!
</div>
......@@ -49,7 +49,7 @@ public class SuiteResultTest extends TestCase {
}
private SuiteResult parseOne(File file) throws DocumentException {
List<SuiteResult> results = SuiteResult.parse(file);
List<SuiteResult> results = SuiteResult.parse(file, false);
assertEquals(1,results.size());
return results.get(0);
}
......@@ -94,7 +94,7 @@ public class SuiteResultTest extends TestCase {
* https://hudson.dev.java.net/issues/show_bug.cgi?id=1472
*/
public void testIssue1472() throws Exception {
List<SuiteResult> results = SuiteResult.parse(getDataFile("junit-report-1472.xml"));
List<SuiteResult> results = SuiteResult.parse(getDataFile("junit-report-1472.xml"), false);
assertTrue(results.size()>20); // lots of data here
SuiteResult sr0 = results.get(0);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册