From 7ba6e1b1347208bfb20cd84e83dc9369f66174d9 Mon Sep 17 00:00:00 2001 From: jglick Date: Thu, 13 May 2010 17:38:04 +0000 Subject: [PATCH] [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 --- .../java/hudson/tasks/junit/CaseResult.java | 11 +++++--- .../java/hudson/tasks/junit/JUnitParser.java | 25 ++++++++++++++++--- .../tasks/junit/JUnitResultArchiver.java | 22 +++++++++++++--- .../java/hudson/tasks/junit/SuiteResult.java | 16 ++++++------ .../java/hudson/tasks/junit/TestResult.java | 16 +++++++++--- .../junit/JUnitResultArchiver/config.jelly | 4 +++ .../help-keepLongStdio.html | 9 +++++++ .../hudson/tasks/junit/SuiteResultTest.java | 4 +-- 8 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 core/src/main/resources/hudson/tasks/junit/JUnitResultArchiver/help-keepLongStdio.html diff --git a/core/src/main/java/hudson/tasks/junit/CaseResult.java b/core/src/main/java/hudson/tasks/junit/CaseResult.java index efd0e8103a..e005011824 100644 --- a/core/src/main/java/hudson/tasks/junit/CaseResult.java +++ b/core/src/main/java/hudson/tasks/junit/CaseResult.java @@ -93,7 +93,7 @@ public final class CaseResult extends TestResult implements Comparable _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 results, String stdio) { // HUDSON-6516 + static String possiblyTrimStdio(Collection 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; diff --git a/core/src/main/java/hudson/tasks/junit/JUnitParser.java b/core/src/main/java/hudson/tasks/junit/JUnitParser.java index f745a705f0..aba7273b41 100644 --- a/core/src/main/java/hudson/tasks/junit/JUnitParser.java +++ b/core/src/main/java/hudson/tasks/junit/JUnitParser.java @@ -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; } diff --git a/core/src/main/java/hudson/tasks/junit/JUnitResultArchiver.java b/core/src/main/java/hudson/tasks/junit/JUnitResultArchiver.java index dffe1a4fb4..4320642ea0 100644 --- a/core/src/main/java/hudson/tasks/junit/JUnitResultArchiver.java +++ b/core/src/main/java/hudson/tasks/junit/JUnitResultArchiver.java @@ -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> testDataPublishers) { + this(testResults, false, testDataPublishers); + } @DataBoundConstructor public JUnitResultArchiver( String testResults, + boolean keepLongStdio, DescribableList> 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> testDataPublishers = new DescribableList>( 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); } /** diff --git a/core/src/main/java/hudson/tasks/junit/SuiteResult.java b/core/src/main/java/hudson/tasks/junit/SuiteResult.java index 648d73d685..978882c713 100644 --- a/core/src/main/java/hudson/tasks/junit/SuiteResult.java +++ b/core/src/main/java/hudson/tasks/junit/SuiteResult.java @@ -82,7 +82,7 @@ public final class SuiteResult implements Serializable { * This method returns a collection, as a single XML may have multiple <testsuite> * elements wrapped into the top-level <testsuites>. */ - static List parse(File xmlReport) throws DocumentException { + static List parse(File xmlReport, boolean keepLongStdio) throws DocumentException { List r = new ArrayList(); // 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)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,"")); + addCase(new CaseResult(this, suite, "", keepLongStdio)); } for (Element e : (List)suite.elements("testcase")) { @@ -146,11 +146,11 @@ public final class SuiteResult implements Serializable { // one wants to use @name from , // the other wants to use @classname from . - 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) { diff --git a/core/src/main/java/hudson/tasks/junit/TestResult.java b/core/src/main/java/hudson/tasks/junit/TestResult.java index febaef446e..84bc6f18b9 100644 --- a/core/src/main/java/hudson/tasks/junit/TestResult.java +++ b/core/src/main/java/hudson/tasks/junit/TestResult.java @@ -86,19 +86,29 @@ public final class TestResult extends MetaTabulatedResult { * Number of failed/error tests. */ private transient List 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); diff --git a/core/src/main/resources/hudson/tasks/junit/JUnitResultArchiver/config.jelly b/core/src/main/resources/hudson/tasks/junit/JUnitResultArchiver/config.jelly index ea2146c10f..55e837692d 100644 --- a/core/src/main/resources/hudson/tasks/junit/JUnitResultArchiver/config.jelly +++ b/core/src/main/resources/hudson/tasks/junit/JUnitResultArchiver/config.jelly @@ -28,6 +28,10 @@ THE SOFTWARE. field="testResults"> + + + + diff --git a/core/src/main/resources/hudson/tasks/junit/JUnitResultArchiver/help-keepLongStdio.html b/core/src/main/resources/hudson/tasks/junit/JUnitResultArchiver/help-keepLongStdio.html new file mode 100644 index 0000000000..db6b9a3952 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/junit/JUnitResultArchiver/help-keepLongStdio.html @@ -0,0 +1,9 @@ +
+ 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! +
diff --git a/core/src/test/java/hudson/tasks/junit/SuiteResultTest.java b/core/src/test/java/hudson/tasks/junit/SuiteResultTest.java index b389a4211a..828de3ff38 100755 --- a/core/src/test/java/hudson/tasks/junit/SuiteResultTest.java +++ b/core/src/test/java/hudson/tasks/junit/SuiteResultTest.java @@ -49,7 +49,7 @@ public class SuiteResultTest extends TestCase { } private SuiteResult parseOne(File file) throws DocumentException { - List results = SuiteResult.parse(file); + List 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 results = SuiteResult.parse(getDataFile("junit-report-1472.xml")); + List results = SuiteResult.parse(getDataFile("junit-report-1472.xml"), false); assertTrue(results.size()>20); // lots of data here SuiteResult sr0 = results.get(0); -- GitLab