git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1556001 13f79535-47bb-0310-9956-ffa450edef68master
@@ -91,6 +91,10 @@ Other changes: | |||||
* <sql> has a new outputencoding attribute. | * <sql> has a new outputencoding attribute. | ||||
Bugzilla Report 39541 | Bugzilla Report 39541 | ||||
* changes to JUnitTestRunner and PlainJUnitResultFormatter to make | |||||
OutOfMemoryErrors less likely. | |||||
Bugzilla Report 45536 | |||||
Changes from Ant 1.9.2 TO Ant 1.9.3 | Changes from Ant 1.9.2 TO Ant 1.9.3 | ||||
=================================== | =================================== | ||||
@@ -558,8 +558,18 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||||
systemOut.close(); | systemOut.close(); | ||||
systemOut = null; | systemOut = null; | ||||
if (startTestSuiteSuccess) { | if (startTestSuiteSuccess) { | ||||
sendOutAndErr(new String(outStrm.toByteArray()), | |||||
new String(errStrm.toByteArray())); | |||||
String out, err; | |||||
try { | |||||
out = new String(outStrm.toByteArray()); | |||||
} catch (OutOfMemoryError ex) { | |||||
out = "out of memory on output stream"; | |||||
} | |||||
try { | |||||
err = new String(errStrm.toByteArray()); | |||||
} catch (OutOfMemoryError ex) { | |||||
err = "out of memory on error stream"; | |||||
} | |||||
sendOutAndErr(out, err); | |||||
} | } | ||||
} | } | ||||
fireEndTestSuite(); | fireEndTestSuite(); | ||||
@@ -117,6 +117,7 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredT | |||||
* @throws BuildException if unable to write the output | * @throws BuildException if unable to write the output | ||||
*/ | */ | ||||
public void endTestSuite(JUnitTest suite) throws BuildException { | public void endTestSuite(JUnitTest suite) throws BuildException { | ||||
try { | |||||
StringBuffer sb = new StringBuffer("Tests run: "); | StringBuffer sb = new StringBuffer("Tests run: "); | ||||
sb.append(suite.runCount()); | sb.append(suite.runCount()); | ||||
sb.append(", Failures: "); | sb.append(", Failures: "); | ||||
@@ -129,40 +130,49 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredT | |||||
sb.append(nf.format(suite.getRunTime() / ONE_SECOND)); | sb.append(nf.format(suite.getRunTime() / ONE_SECOND)); | ||||
sb.append(" sec"); | sb.append(" sec"); | ||||
sb.append(StringUtils.LINE_SEP); | sb.append(StringUtils.LINE_SEP); | ||||
write(sb.toString()); | |||||
// append the err and output streams to the log | |||||
// write the err and output streams to the log | |||||
if (systemOutput != null && systemOutput.length() > 0) { | if (systemOutput != null && systemOutput.length() > 0) { | ||||
sb.append("------------- Standard Output ---------------") | |||||
.append(StringUtils.LINE_SEP) | |||||
.append(systemOutput) | |||||
.append("------------- ---------------- ---------------") | |||||
.append(StringUtils.LINE_SEP); | |||||
write("------------- Standard Output ---------------"); | |||||
write(StringUtils.LINE_SEP); | |||||
write(systemOutput); | |||||
write("------------- ---------------- ---------------"); | |||||
write(StringUtils.LINE_SEP); | |||||
} | } | ||||
if (systemError != null && systemError.length() > 0) { | if (systemError != null && systemError.length() > 0) { | ||||
sb.append("------------- Standard Error -----------------") | |||||
.append(StringUtils.LINE_SEP) | |||||
.append(systemError) | |||||
.append("------------- ---------------- ---------------") | |||||
.append(StringUtils.LINE_SEP); | |||||
write("------------- Standard Error -----------------"); | |||||
write(StringUtils.LINE_SEP); | |||||
write(systemError); | |||||
write("------------- ---------------- ---------------"); | |||||
write(StringUtils.LINE_SEP); | |||||
} | } | ||||
sb.append(StringUtils.LINE_SEP); | |||||
write(StringUtils.LINE_SEP); | |||||
if (out != null) { | |||||
try { | |||||
wri.flush(); | |||||
write(inner.toString()); | |||||
} catch (IOException ioex) { | |||||
throw new BuildException("Unable to write output", ioex); | |||||
} | |||||
} | |||||
} finally { | |||||
if (out != null) { | if (out != null) { | ||||
try { | try { | ||||
out.write(sb.toString().getBytes()); | |||||
wri.close(); | wri.close(); | ||||
out.write(inner.toString().getBytes()); | |||||
out.flush(); | |||||
} catch (IOException ioex) { | } catch (IOException ioex) { | ||||
throw new BuildException("Unable to write output", ioex); | |||||
throw new BuildException("Unable to flush output", ioex); | |||||
} finally { | } finally { | ||||
if (out != System.out && out != System.err) { | if (out != System.out && out != System.err) { | ||||
FileUtils.close(out); | FileUtils.close(out); | ||||
} | } | ||||
wri = null; | |||||
out = null; | |||||
} | } | ||||
} | } | ||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -286,4 +296,22 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredT | |||||
public void testAssumptionFailure(Test test, Throwable throwable) { | public void testAssumptionFailure(Test test, Throwable throwable) { | ||||
formatSkip(test, throwable.getMessage()); | formatSkip(test, throwable.getMessage()); | ||||
} | } | ||||
/** | |||||
* Print out some text, and flush the output stream; encoding in the platform | |||||
* local default encoding. | |||||
* @param text text to write. | |||||
* @throws BuildException on IO Problems. | |||||
*/ | |||||
private void write(String text) { | |||||
if (out == null) { | |||||
return; | |||||
} | |||||
try { | |||||
out.write(text.getBytes()); | |||||
out.flush(); | |||||
} catch (IOException ex) { | |||||
throw new BuildException("Unable to write output " + ex, ex); | |||||
} | |||||
} | |||||
} // PlainJUnitResultFormatter | } // PlainJUnitResultFormatter |
@@ -21,6 +21,7 @@ package org.apache.tools.ant.util; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.io.OutputStreamWriter; | import java.io.OutputStreamWriter; | ||||
import java.io.StringWriter; | |||||
import java.io.Writer; | import java.io.Writer; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
@@ -233,7 +234,7 @@ public class DOMElementWriter { | |||||
case Node.CDATA_SECTION_NODE: | case Node.CDATA_SECTION_NODE: | ||||
out.write("<![CDATA["); | out.write("<![CDATA["); | ||||
out.write(encodedata(((Text) child).getData())); | |||||
encodedata(out, ((Text) child).getData()); | |||||
out.write("]]>"); | out.write("]]>"); | ||||
break; | break; | ||||
@@ -486,19 +487,59 @@ public class DOMElementWriter { | |||||
* href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p> | * href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p> | ||||
* @param value the value to be encoded. | * @param value the value to be encoded. | ||||
* @return the encoded value. | * @return the encoded value. | ||||
*/ | */ | ||||
public String encodedata(final String value) { | public String encodedata(final String value) { | ||||
final StringWriter out = new StringWriter(); | |||||
try { | |||||
encodedata(out, value); | |||||
} catch (IOException ex) { | |||||
throw new RuntimeException(ex); | |||||
} | |||||
return out.toString(); | |||||
} | |||||
/** | |||||
* Drop characters that are illegal in XML documents and write the | |||||
* rest to the given writer. | |||||
* | |||||
* <p>Also ensure that we are not including an <code>]]></code> | |||||
* marker by replacing that sequence with | |||||
* <code>&#x5d;&#x5d;&gt;</code>.</p> | |||||
* | |||||
* <p>See XML 1.0 2.2 <a | |||||
* href="http://www.w3.org/TR/1998/REC-xml-19980210#charsets"> | |||||
* http://www.w3.org/TR/1998/REC-xml-19980210#charsets</a> and | |||||
* 2.7 <a | |||||
* href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p> | |||||
* @param value the value to be encoded. | |||||
* @param out where to write the encoded data to. | |||||
*/ | |||||
public void encodedata(final Writer out, final String value) throws IOException { | |||||
final int len = value.length(); | final int len = value.length(); | ||||
StringBuffer sb = new StringBuffer(len); | |||||
for (int i = 0; i < len; ++i) { | |||||
final char c = value.charAt(i); | |||||
if (isLegalCharacter(c)) { | |||||
sb.append(c); | |||||
int prevEnd = 0, cdataEndPos = value.indexOf("]]>"); | |||||
while (prevEnd < len) { | |||||
final int end = (cdataEndPos < 0 ? len : cdataEndPos); | |||||
// Write out stretches of legal characters in the range [prevEnd, end). | |||||
for (int prevLegalCharPos = prevEnd; prevLegalCharPos < end; /*empty*/) { | |||||
int illegalCharPos; | |||||
for (illegalCharPos = prevLegalCharPos; true; ++illegalCharPos) { | |||||
if (illegalCharPos >= end | |||||
|| !isLegalCharacter(value.charAt(illegalCharPos))) { | |||||
break; | |||||
} | |||||
} | |||||
out.write(value, prevLegalCharPos, illegalCharPos - prevLegalCharPos); | |||||
prevLegalCharPos = illegalCharPos + 1; | |||||
} | } | ||||
} | |||||
return sb.substring(0).replace("]]>", "]]]]><![CDATA[>"); | |||||
if (cdataEndPos >= 0) { | |||||
out.write("]]]]><![CDATA[>"); | |||||
prevEnd = cdataEndPos + 3; | |||||
cdataEndPos = value.indexOf("]]>", prevEnd); | |||||
} else { | |||||
prevEnd = end; | |||||
} | |||||
} | |||||
} | } | ||||
/** | /** | ||||