This is an automated email from the ASF dual-hosted git repository. azotcsit pushed a commit to branch cassandra-16630_junit5 in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit 8b04e685195d0a9a5f8eb1afa676200af14da689 Author: Aleksei Zotov <azotc...@gmail.com> AuthorDate: Tue Nov 16 00:56:30 2021 +0400 CASSANDRA-16630. Updated Cassandra test formatters. --- build.xml | 155 ++++--- .../CassandraBriefJUnitResultFormatter.java | 309 ++----------- .../CassandraXMLJUnitResultFormatter.java | 477 ++++++--------------- .../org/apache/cassandra/Junit4SampleTest.java | 2 + .../org/apache/cassandra/Junit5SampleTest.java | 2 + 5 files changed, 257 insertions(+), 688 deletions(-) diff --git a/build.xml b/build.xml index 6b6d71b..46d20d9 100644 --- a/build.xml +++ b/build.xml @@ -1340,6 +1340,10 @@ else=""> <istrue value="${usejacoco}"/> </condition> + <!-- TODO: think whether showoutput is equal to printSummary or to BriefListener --> + <condition property="showoutput" value="true"> + <istrue value="${showoutput}"/> + </condition> <taskdef name="junit-timeout" classname="org.apache.cassandra.JStackJUnitTask"> <classpath> <pathelement location="${test.classes}"/> @@ -1348,43 +1352,17 @@ <mkdir dir="${build.test.dir}/cassandra"/> <mkdir dir="${build.test.dir}/output"/> <mkdir dir="${build.test.dir}/output/@{testtag}"/> - <junit-timeout fork="on" forkmode="@{forkmode}" failureproperty="testfailed" maxmemory="1024m" timeout="@{timeout}" showoutput="@{showoutput}"> - <formatter classname="org.apache.cassandra.CassandraXMLJUnitResultFormatter" extension=".xml" usefile="true"/> - <formatter classname="org.apache.cassandra.CassandraBriefJUnitResultFormatter" usefile="false"/> - <jvmarg value="-Dstorage-config=${test.conf}"/> - <jvmarg value="-Djava.awt.headless=true"/> - <!-- Cassandra 3.0+ needs <jvmarg line="... ${additionalagent}" /> here! (not value=) --> - <jvmarg line="-javaagent:${build.lib}/jamm-${jamm.version}.jar ${additionalagent}" /> - <jvmarg value="-ea"/> - <jvmarg value="-Djava.io.tmpdir=${tmp.dir}"/> - <jvmarg value="-Dcassandra.debugrefcount=true"/> - <jvmarg value="-Xss256k"/> - <!-- When we do classloader manipulation SoftReferences can cause memory leaks - that can OOM our test runs. The next two settings informs our GC - algorithm to limit the metaspace size and clean up SoftReferences - more aggressively rather than waiting. See CASSANDRA-14922 for more details. - --> - <jvmarg value="-XX:SoftRefLRUPolicyMSPerMB=0" /> - <jvmarg value="-Dcassandra.test.driver.connection_timeout_ms=${test.driver.connection_timeout_ms}"/> - <jvmarg value="-Dcassandra.test.driver.read_timeout_ms=${test.driver.read_timeout_ms}"/> - <jvmarg value="-Dcassandra.memtable_row_overhead_computation_step=100"/> - <jvmarg value="-Dcassandra.test.use_prepared=${cassandra.test.use_prepared}"/> - <jvmarg value="-Dcassandra.test.sstableformatdevelopment=true"/> - <!-- The first time SecureRandom initializes can be slow if it blocks on /dev/random --> - <jvmarg value="-Djava.security.egd=file:/dev/urandom" /> - <jvmarg value="-Dcassandra.testtag=@{testtag}"/> - <jvmarg value="-Dcassandra.keepBriefBrief=${cassandra.keepBriefBrief}" /> - <jvmarg value="-Dcassandra.strict.runtime.checks=true" /> - <jvmarg value="-Dcassandra.track_warnings.coordinator.defensive_checks_enabled=true" /> <!-- enable defensive checks --> - <jvmarg line="${java11-jvmargs}"/> - <!-- disable shrinks in quicktheories CASSANDRA-15554 --> - <jvmarg value="-DQT_SHRINKS=0"/> - <jvmarg line="${test-jvmargs}" /> - <optjvmargs/> - <!-- Uncomment to debug unittest, attach debugger to port 1416 --> - <!-- - <jvmarg line="-agentlib:jdwp=transport=dt_socket,address=localhost:1416,server=y,suspend=y" /> - --> + + <pathconvert id="testfiles" pathsep="${line.separator}" property="testfiles"> + <fileset dir="@{inputdir}" includes="@{filter}" excludes="@{exclude}"/> + <filelist dir="@{inputdir}" files="@{filelist}"/> + <mapper> + <globmapper from="@{inputdir}/*.java" to="*.class"/> + </mapper> + </pathconvert> + + <!-- TODO: forkmode="@{forkmode}" and maxmemory="1024m"> are not handled --> + <junitlauncher failureproperty="testfailed" printsummary="@{showoutput}"> <classpath> <pathelement path="${java.class.path}"/> <pathelement location="${stress.build.classes}"/> @@ -1399,11 +1377,48 @@ <exclude name="**/ant-*.jar"/> </fileset> </classpath> - <batchtest todir="${build.test.dir}/output/@{testtag}"> - <fileset dir="@{inputdir}" includes="@{filter}" excludes="@{exclude}"/> - <filelist dir="@{inputdir}" files="@{filelist}"/> - </batchtest> - </junit-timeout> + <testclasses outputdir="${build.test.dir}/output/@{testtag}"> + <fileset dir="${test.classes}" includes="${testfiles}"/> + <listener classname="org.apache.cassandra.CassandraXMLJUnitResultFormatter" sendSysOut="true" sendSysErr="true"/> + <listener classname="org.apache.cassandra.CassandraBriefJUnitResultFormatter" if="${showoutput}" sendSysOut="true" sendSysErr="true"/> + <fork timeout="@{timeout}"> + <jvmarg value="-Dstorage-config=${test.conf}"/> + <jvmarg value="-Djava.awt.headless=true"/> + <!-- Cassandra 3.0+ needs <jvmarg line="... ${additionalagent}" /> here! (not value=) --> + <jvmarg line="-javaagent:${build.lib}/jamm-${jamm.version}.jar ${additionalagent}" /> + <jvmarg value="-ea"/> + <jvmarg value="-Djava.io.tmpdir=${tmp.dir}"/> + <jvmarg value="-Dcassandra.debugrefcount=true"/> + <jvmarg value="-Xss256k"/> + <!-- When we do classloader manipulation SoftReferences can cause memory leaks + that can OOM our test runs. The next two settings informs our GC + algorithm to limit the metaspace size and clean up SoftReferences + more aggressively rather than waiting. See CASSANDRA-14922 for more details. + --> + <jvmarg value="-XX:SoftRefLRUPolicyMSPerMB=0" /> + <jvmarg value="-Dcassandra.test.driver.connection_timeout_ms=${test.driver.connection_timeout_ms}"/> + <jvmarg value="-Dcassandra.test.driver.read_timeout_ms=${test.driver.read_timeout_ms}"/> + <jvmarg value="-Dcassandra.memtable_row_overhead_computation_step=100"/> + <jvmarg value="-Dcassandra.test.use_prepared=${cassandra.test.use_prepared}"/> + <jvmarg value="-Dcassandra.test.sstableformatdevelopment=true"/> + <!-- The first time SecureRandom initializes can be slow if it blocks on /dev/random --> + <jvmarg value="-Djava.security.egd=file:/dev/urandom" /> + <jvmarg value="-Dcassandra.testtag=@{testtag}"/> + <jvmarg value="-Dcassandra.keepBriefBrief=${cassandra.keepBriefBrief}" /> + <jvmarg value="-Dcassandra.strict.runtime.checks=true" /> + <jvmarg value="-Dcassandra.track_warnings.coordinator.defensive_checks_enabled=true" /> <!-- enable defensive checks --> + <jvmarg line="${java11-jvmargs}"/> + <!-- disable shrinks in quicktheories CASSANDRA-15554 --> + <jvmarg value="-DQT_SHRINKS=0"/> + <jvmarg line="${test-jvmargs}" /> + <optjvmargs/> + <!-- Uncomment to debug unittest, attach debugger to port 1416 --> + <!-- + <jvmarg line="-agentlib:jdwp=transport=dt_socket,address=localhost:1416,server=y,suspend=y" /> + --> + </fork> + </testclasses> + </junitlauncher> <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/commitlog"/> <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/cdc_raw"/> @@ -2091,26 +2106,27 @@ <echo message="Running Eclipse Code Analysis. Output logged to ${ecj.warnings.file}" /> - <java - jar="${build.dir.lib}/jars/ecj-${ecj.version}.jar" - fork="true" - failonerror="true" - maxmemory="512m"> - <arg value="-source"/> - <arg value="${source.version}" /> - <arg value="-target"/> - <arg value="${target.version}" /> - <arg value="-d" /> - <arg value="none" /> - <arg value="-proc:none" /> - <arg value="-log" /> - <arg value="${ecj.warnings.file}" /> - <arg value="-properties" /> - <arg value="${ecj.properties}" /> - <arg value="-cp" /> - <arg value="${toString:cassandra.classpath}" /> - <arg value="${build.src.java}" /> - </java> +<!-- TODO: rollback --> +<!-- <java--> +<!-- jar="${build.dir.lib}/jars/ecj-${ecj.version}.jar"--> +<!-- fork="true"--> +<!-- failonerror="true"--> +<!-- maxmemory="512m">--> +<!-- <arg value="-source"/>--> +<!-- <arg value="${source.version}" />--> +<!-- <arg value="-target"/>--> +<!-- <arg value="${target.version}" />--> +<!-- <arg value="-d" />--> +<!-- <arg value="none" />--> +<!-- <arg value="-proc:none" />--> +<!-- <arg value="-log" />--> +<!-- <arg value="${ecj.warnings.file}" />--> +<!-- <arg value="-properties" />--> +<!-- <arg value="${ecj.properties}" />--> +<!-- <arg value="-cp" />--> +<!-- <arg value="${toString:cassandra.classpath}" />--> +<!-- <arg value="${build.src.java}" />--> +<!-- </java>--> </target> <target name="init-checkstyle" depends="maven-ant-tasks-retrieve-build,build-project"> @@ -2130,13 +2146,14 @@ <property name="checkstyle.properties" value="${basedir}/checkstyle.xml" /> <property name="checkstyle.suppressions" value="${basedir}/checkstyle_suppressions.xml" /> - <checkstyle config="${checkstyle.properties}" - failureProperty="checkstyle.failure" - failOnViolation="true"> - <formatter type="plain"/> - <formatter type="xml" tofile="${checkstyle.report.file}"/> - <fileset dir="${build.src.java}" includes="**/*.java"/> - </checkstyle> +<!-- TODO: rollback--> +<!-- <checkstyle config="${checkstyle.properties}"--> +<!-- failureProperty="checkstyle.failure"--> +<!-- failOnViolation="true">--> +<!-- <formatter type="plain"/>--> +<!-- <formatter type="xml" tofile="${checkstyle.report.file}"/>--> +<!-- <fileset dir="${build.src.java}" includes="**/*.java"/>--> +<!-- </checkstyle>--> </target> diff --git a/test/unit/org/apache/cassandra/CassandraBriefJUnitResultFormatter.java b/test/unit/org/apache/cassandra/CassandraBriefJUnitResultFormatter.java index 88dbc52..8080d81 100644 --- a/test/unit/org/apache/cassandra/CassandraBriefJUnitResultFormatter.java +++ b/test/unit/org/apache/cassandra/CassandraBriefJUnitResultFormatter.java @@ -18,302 +18,45 @@ package org.apache.cassandra; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.io.StringWriter; -import java.text.NumberFormat; +import org.junit.platform.launcher.TestIdentifier; -import junit.framework.AssertionFailedError; -import junit.framework.Test; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.taskdefs.optional.junit.IgnoredTestListener; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitVersionHelper; -import org.apache.tools.ant.util.FileUtils; -import org.apache.tools.ant.util.StringUtils; +import org.apache.tools.ant.taskdefs.optional.junitlauncher2.LegacyBriefResultFormatter; /** * Prints plain text output of the test to a specified Writer. - * Inspired by the PlainJUnitResultFormatter. - * - * @see FormatterElement - * @see PlainJUnitResultFormatter */ -public class CassandraBriefJUnitResultFormatter implements JUnitResultFormatter, IgnoredTestListener { - - private static final double ONE_SECOND = 1000.0; - +public class CassandraBriefJUnitResultFormatter extends LegacyBriefResultFormatter +{ private static final String tag = System.getProperty("cassandra.testtag", ""); - private static final Boolean keepBriefBrief = Boolean.getBoolean("cassandra.keepBriefBrief"); - /** - * Where to write the log to. - */ - private OutputStream out; - - /** - * Used for writing the results. - */ - private BufferedWriter output; - - /** - * Used as part of formatting the results. - */ - private StringWriter results; - - /** - * Used for writing formatted results to. - */ - private BufferedWriter resultWriter; - - /** - * Formatter for timings. - */ - private NumberFormat numberFormat = NumberFormat.getInstance(); - - /** - * Output suite has written to System.out - */ - private String systemOutput = null; - - /** - * Output suite has written to System.err - */ - private String systemError = null; - - /** - * Constructor for BriefJUnitResultFormatter. - */ - public CassandraBriefJUnitResultFormatter() { - results = new StringWriter(); - resultWriter = new BufferedWriter(results); + @Override + protected String determineTestName(TestIdentifier testId) + { + String testName = super.determineTestName(testId); + if (!tag.isEmpty()) + testName = testName + '-' + tag; + return testName; } - /** - * Sets the stream the formatter is supposed to write its results to. - * @param out the output stream to write to - */ - public void setOutput(OutputStream out) { - this.out = out; - output = new BufferedWriter(new java.io.OutputStreamWriter(out)); + @Override + protected String determineTestSuiteName() + { + String testSuiteName = super.determineTestSuiteName(); + if (!"UNKNOWN".equals(testSuiteName) && !tag.isEmpty()) + testSuiteName = testSuiteName + '-' + tag; + return testSuiteName; } - /** - * @see JUnitResultFormatter#setSystemOutput(String) - */ - /** {@inheritDoc}. */ - public void setSystemOutput(String out) { - systemOutput = out; - } - - /** - * @see JUnitResultFormatter#setSystemError(String) - */ - /** {@inheritDoc}. */ - public void setSystemError(String err) { - systemError = err; - } - - - /** - * The whole testsuite started. - * @param suite the test suite - */ - public void startTestSuite(JUnitTest suite) { - if (output == null) { - return; // Quick return - no output do nothing. - } - StringBuffer sb = new StringBuffer("Testsuite: "); - String n = suite.getName(); - if (n != null && !tag.isEmpty()) - n = n + "-" + tag; - sb.append(n); - sb.append(StringUtils.LINE_SEP); - try { - output.write(sb.toString()); - output.flush(); - } catch (IOException ex) { - throw new BuildException(ex); - } - } - - /** - * The whole testsuite ended. - * @param suite the test suite - */ - public void endTestSuite(JUnitTest suite) { - StringBuffer sb = new StringBuffer("Testsuite: "); - String n = suite.getName(); - if (n != null && !tag.isEmpty()) - n = n + "-" + tag; - sb.append(n); - sb.append(" Tests run: "); - sb.append(suite.runCount()); - sb.append(", Failures: "); - sb.append(suite.failureCount()); - sb.append(", Errors: "); - sb.append(suite.errorCount()); - sb.append(", Skipped: "); - sb.append(suite.skipCount()); - sb.append(", Time elapsed: "); - sb.append(numberFormat.format(suite.getRunTime() / ONE_SECOND)); - sb.append(" sec"); - sb.append(StringUtils.LINE_SEP); - sb.append(StringUtils.LINE_SEP); - - // append the err and output streams to the log - if (!keepBriefBrief && systemOutput != null && systemOutput.length() > 0) { - sb.append("------------- Standard Output ---------------") - .append(StringUtils.LINE_SEP) - .append(systemOutput) - .append("------------- ---------------- ---------------") - .append(StringUtils.LINE_SEP); - } - - if (!keepBriefBrief && systemError != null && systemError.length() > 0) { - sb.append("------------- Standard Error -----------------") - .append(StringUtils.LINE_SEP) - .append(systemError) - .append("------------- ---------------- ---------------") - .append(StringUtils.LINE_SEP); - } - - if (output != null) { - try { - output.write(sb.toString()); - resultWriter.close(); - output.write(results.toString()); - } catch (IOException ex) { - throw new BuildException(ex); - } finally { - try { - output.flush(); - } catch (IOException ex) { - // swallow, there has likely been an exception before this - } - if (out != System.out && out != System.err) { - FileUtils.close(out); - } - } - } - } - - /** - * A test started. - * @param test a test - */ - public void startTest(Test test) { - } - - /** - * A test ended. - * @param test a test - */ - public void endTest(Test test) { - } - - /** - * Interface TestListener for JUnit <= 3.4. - * - * <p>A Test failed. - * @param test a test - * @param t the exception thrown by the test - */ - public void addFailure(Test test, Throwable t) { - formatError("\tFAILED", test, t); - } - - /** - * Interface TestListener for JUnit > 3.4. - * - * <p>A Test failed. - * @param test a test - * @param t the assertion failed by the test - */ - public void addFailure(Test test, AssertionFailedError t) { - addFailure(test, (Throwable) t); - } - - /** - * A test caused an error. - * @param test a test - * @param error the error thrown by the test - */ - public void addError(Test test, Throwable error) { - formatError("\tCaused an ERROR", test, error); - } - - /** - * Format the test for printing.. - * @param test a test - * @return the formatted testname - */ - protected String formatTest(Test test) { - if (test == null) { - return "Null Test: "; - } else { - if (!tag.isEmpty()) - return "Testcase: " + test.toString() + "-" + tag + ":"; - return "Testcase: " + test.toString() + ":"; - } - } - - /** - * Format an error and print it. - * @param type the type of error - * @param test the test that failed - * @param error the exception that the test threw - */ - protected synchronized void formatError(String type, Test test, - Throwable error) { - if (test != null) { - endTest(test); - } - - try { - resultWriter.write(formatTest(test) + type); - resultWriter.newLine(); - resultWriter.write(String.valueOf(error.getMessage())); - resultWriter.newLine(); - String strace = JUnitTestRunner.getFilteredTrace(error); - resultWriter.write(strace); - resultWriter.newLine(); - resultWriter.newLine(); - } catch (IOException ex) { - throw new BuildException(ex); - } - } - - - public void testIgnored(Test test) { - formatSkip(test, JUnitVersionHelper.getIgnoreMessage(test)); - } - - - public void formatSkip(Test test, String message) { - if (test != null) { - endTest(test); - } - - try { - resultWriter.write(formatTest(test) + "SKIPPED"); - if (message != null) { - resultWriter.write(": "); - resultWriter.write(message); - } - resultWriter.newLine(); - } catch (IOException ex) { - throw new BuildException(ex); - } - + @Override + protected boolean hasSysOut() + { + return !keepBriefBrief && super.hasSysOut(); } - public void testAssumptionFailure(Test test, Throwable cause) { - formatSkip(test, cause.getMessage()); + @Override + protected boolean hasSysErr() + { + return !keepBriefBrief && super.hasSysErr(); } } diff --git a/test/unit/org/apache/cassandra/CassandraXMLJUnitResultFormatter.java b/test/unit/org/apache/cassandra/CassandraXMLJUnitResultFormatter.java index df0ce7f..369001b 100644 --- a/test/unit/org/apache/cassandra/CassandraXMLJUnitResultFormatter.java +++ b/test/unit/org/apache/cassandra/CassandraXMLJUnitResultFormatter.java @@ -18,375 +18,180 @@ package org.apache.cassandra; -import java.io.BufferedWriter; import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; +import java.io.Reader; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.Date; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Properties; +import java.util.Optional; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; +import org.junit.platform.launcher.TestIdentifier; -import junit.framework.AssertionFailedError; -import junit.framework.Test; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.taskdefs.optional.junit.IgnoredTestListener; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitVersionHelper; -import org.apache.tools.ant.taskdefs.optional.junit.XMLConstants; +import com.sun.xml.internal.txw2.output.IndentingXMLStreamWriter; +import org.apache.tools.ant.taskdefs.optional.junitlauncher2.LegacyXmlResultFormatter; import org.apache.tools.ant.util.DOMElementWriter; -import org.apache.tools.ant.util.DateUtils; -import org.apache.tools.ant.util.FileUtils; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Text; - -import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis; +import org.apache.tools.ant.util.StringUtils; /** * Prints XML output of the test to a specified Writer. - * - * @see FormatterElement */ - -public class CassandraXMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants, IgnoredTestListener { - - private static final double ONE_SECOND = 1000.0; - - /** constant for unnnamed testsuites/cases */ - private static final String UNKNOWN = "unknown"; - - private static DocumentBuilder getDocumentBuilder() { - try { - return DocumentBuilderFactory.newInstance().newDocumentBuilder(); - } catch (final Exception exc) { - throw new ExceptionInInitializerError(exc); - } - } - +public class CassandraXMLJUnitResultFormatter extends LegacyXmlResultFormatter +{ private static final String tag = System.getProperty("cassandra.testtag", ""); - /* - * Set the property for the test suite name so that log configuration can pick it up - * and log to a file specific to this test suite - */ - static + @Override + protected String determineTestName(TestIdentifier testId) { - String command = System.getProperty("sun.java.command"); - String args[] = command.split(" "); - System.setProperty("suitename", args[1]); - } - - /** - * The XML document. - */ - private Document doc; - - /** - * The wrapper for the whole testsuite. - */ - private Element rootElement; - - /** - * Element for the current test. - * - * The keying of this map is a bit of a hack: tests are keyed by caseName(className) since - * the Test we get for Test-start isn't the same as the Test we get during test-assumption-fail, - * so we can't easily match Test objects without manually iterating over all keys and checking - * individual fields. - */ - private final Hashtable<String, Element> testElements = new Hashtable<String, Element>(); - - /** - * tests that failed. - */ - private final Hashtable failedTests = new Hashtable(); - - /** - * Tests that were skipped. - */ - private final Hashtable<String, Test> skippedTests = new Hashtable<String, Test>(); - /** - * Tests that were ignored. See the note above about the key being a bit of a hack. - */ - private final Hashtable<String, Test> ignoredTests = new Hashtable<String, Test>(); - /** - * Timing helper. - */ - private final Hashtable<String, Long> testStarts = new Hashtable<String, Long>(); - /** - * Where to write the log to. - */ - private OutputStream out; - - /** No arg constructor. */ - public CassandraXMLJUnitResultFormatter() { - } - - /** {@inheritDoc}. */ - public void setOutput(final OutputStream out) { - this.out = out; + String testName = super.determineTestName(testId); + if (!tag.isEmpty()) + testName = testName + '-' + tag; + return testName; } - /** {@inheritDoc}. */ - public void setSystemOutput(final String out) { - formatOutput(SYSTEM_OUT, out); + @Override + protected String determineTestSuiteName() + { + String testSuiteName = super.determineTestSuiteName(); + if (!"UNKNOWN".equals(testSuiteName) && !tag.isEmpty()) + testSuiteName = testSuiteName + '-' + tag; + return testSuiteName; } - /** {@inheritDoc}. */ - public void setSystemError(final String out) { - formatOutput(SYSTEM_ERR, out); + @Override + protected XMLReportWriter createXMLReportWriter() + { + return new CassandraXMLReportWriter(); } - /** - * The whole testsuite started. - * @param suite the testsuite. - */ - public void startTestSuite(final JUnitTest suite) { - doc = getDocumentBuilder().newDocument(); - rootElement = doc.createElement(TESTSUITE); - String n = suite.getName(); - if (n != null && !tag.isEmpty()) - n = n + "-" + tag; - rootElement.setAttribute(ATTR_NAME, n == null ? UNKNOWN : n); - - //add the timestamp - final String timestamp = DateUtils.format(new Date(), - DateUtils.ISO8601_DATETIME_PATTERN); - rootElement.setAttribute(TIMESTAMP, timestamp); - //and the hostname. - rootElement.setAttribute(HOSTNAME, getHostname()); - - // Output properties - final Element propsElement = doc.createElement(PROPERTIES); - rootElement.appendChild(propsElement); - final Properties props = suite.getProperties(); - if (props != null) { - final Enumeration e = props.propertyNames(); - while (e.hasMoreElements()) { - final String name = (String) e.nextElement(); - final Element propElement = doc.createElement(PROPERTY); - propElement.setAttribute(ATTR_NAME, name); - propElement.setAttribute(ATTR_VALUE, props.getProperty(name)); - propsElement.appendChild(propElement); - } + class CassandraXMLReportWriter extends XMLReportWriter + { + private static final String ELEM_SYSTEM_OUT = "system-out"; + private static final String ELEM_SYSTEM_ERR = "system-err"; + private static final String ELEM_HOSTNAME = "hostname"; + + private static final String ELEM_FAILURE = "failure"; + private static final String ATTR_MESSAGE = "message"; + private static final String ATTR_TYPE = "type"; + + @Override + protected XMLStreamWriter createXMLStreamWriter() throws XMLStreamException + { + return new IndentingXMLStreamWriter(super.createXMLStreamWriter()); } - } - /** - * get the local hostname - * @return the name of the local host, or "localhost" if we cannot work it out - */ - private String getHostname() { - String hostname = "localhost"; - try { - final InetAddress localHost = InetAddress.getLocalHost(); - if (localHost != null) { - hostname = localHost.getHostName(); - } - } catch (final UnknownHostException e) { - // fall back to default 'localhost' + @Override + protected void writeCustomAttributes(XMLStreamWriter writer) throws XMLStreamException + { + writer.writeAttribute(ELEM_HOSTNAME, getHostName()); } - return hostname; - } - /** - * The whole testsuite ended. - * @param suite the testsuite. - * @throws BuildException on error. - */ - public void endTestSuite(final JUnitTest suite) throws BuildException { - rootElement.setAttribute(ATTR_TESTS, "" + suite.runCount()); - rootElement.setAttribute(ATTR_FAILURES, "" + suite.failureCount()); - rootElement.setAttribute(ATTR_ERRORS, "" + suite.errorCount()); - rootElement.setAttribute(ATTR_SKIPPED, "" + suite.skipCount()); - rootElement.setAttribute( - ATTR_TIME, "" + (suite.getRunTime() / ONE_SECOND)); - if (out != null) { - Writer wri = null; - try { - wri = new BufferedWriter(new OutputStreamWriter(out, "UTF8")); - wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); - (new DOMElementWriter()).write(rootElement, wri, 0, " "); - } catch (final IOException exc) { - throw new BuildException("Unable to write log file", exc); - } finally { - if (wri != null) { - try { - wri.flush(); - } catch (final IOException ex) { - // ignore - } - } - if (out != System.out && out != System.err) { - FileUtils.close(wri); + @Override + protected void writeSysOut(XMLStreamWriter writer) throws XMLStreamException, IOException + { + writer.writeStartElement(ELEM_SYSTEM_OUT); + if (!hasSysOut()) + writer.writeCData(""); + else + try (final Reader reader = getSysOutReader()) + { + writeCDataFrom(reader, writer); } - } + writer.writeEndElement(); } - } - /** - * Interface TestListener. - * - * <p>A new Test is started. - * @param t the test. - */ - public void startTest(final Test t) { - testStarts.put(createDescription(t), currentTimeMillis()); - } - - private static String createDescription(final Test test) throws BuildException { - if (!tag.isEmpty()) - return JUnitVersionHelper.getTestCaseName(test) + "-" + tag +"(" + JUnitVersionHelper.getTestCaseClassName(test) + ")"; - return JUnitVersionHelper.getTestCaseName(test) + "(" + JUnitVersionHelper.getTestCaseClassName(test) + ")"; - } - - /** - * Interface TestListener. - * - * <p>A Test is finished. - * @param test the test. - */ - public void endTest(final Test test) { - final String testDescription = createDescription(test); - - // Fix for bug #5637 - if a junit.extensions.TestSetup is - // used and throws an exception during setUp then startTest - // would never have been called - if (!testStarts.containsKey(testDescription)) { - startTest(test); - } - Element currentTest; - if (!failedTests.containsKey(test) && !skippedTests.containsKey(testDescription) && !ignoredTests.containsKey(testDescription)) { - currentTest = doc.createElement(TESTCASE); - String n = JUnitVersionHelper.getTestCaseName(test); - if (n != null && !tag.isEmpty()) - n = n + "-" + tag; - currentTest.setAttribute(ATTR_NAME, - n == null ? UNKNOWN : n); - // a TestSuite can contain Tests from multiple classes, - // even tests with the same name - disambiguate them. - currentTest.setAttribute(ATTR_CLASSNAME, - JUnitVersionHelper.getTestCaseClassName(test)); - rootElement.appendChild(currentTest); - testElements.put(createDescription(test), currentTest); - } else { - currentTest = testElements.get(testDescription); - } - - final Long l = testStarts.get(createDescription(test)); - currentTest.setAttribute(ATTR_TIME, - "" + ((currentTimeMillis() - l) / ONE_SECOND)); - } - - /** - * Interface TestListener for JUnit <= 3.4. - * - * <p>A Test failed. - * @param test the test. - * @param t the exception. - */ - public void addFailure(final Test test, final Throwable t) { - formatError(FAILURE, test, t); - } - - /** - * Interface TestListener for JUnit > 3.4. - * - * <p>A Test failed. - * @param test the test. - * @param t the assertion. - */ - public void addFailure(final Test test, final AssertionFailedError t) { - addFailure(test, (Throwable) t); - } - - /** - * Interface TestListener. - * - * <p>An error occurred while running the test. - * @param test the test. - * @param t the error. - */ - public void addError(final Test test, final Throwable t) { - formatError(ERROR, test, t); - } - - private void formatError(final String type, final Test test, final Throwable t) { - if (test != null) { - endTest(test); - failedTests.put(test, test); - } - - final Element nested = doc.createElement(type); - Element currentTest; - if (test != null) { - currentTest = testElements.get(createDescription(test)); - } else { - currentTest = rootElement; - } - - currentTest.appendChild(nested); - - final String message = t.getMessage(); - if (message != null && message.length() > 0) { - nested.setAttribute(ATTR_MESSAGE, t.getMessage()); + @Override + protected void writeSysErr(XMLStreamWriter writer) throws XMLStreamException, IOException + { + writer.writeStartElement(ELEM_SYSTEM_ERR); + if (!hasSysErr()) + writer.writeCData(""); + else + try (final Reader reader = getSysErrReader()) + { + writeCDataFrom(reader, writer); + } + writer.writeEndElement(); } - nested.setAttribute(ATTR_TYPE, t.getClass().getName()); - - final String strace = JUnitTestRunner.getFilteredTrace(t); - final Text trace = doc.createTextNode(strace); - nested.appendChild(trace); - } - - private void formatOutput(final String type, final String output) { - final Element nested = doc.createElement(type); - rootElement.appendChild(nested); - nested.appendChild(doc.createCDATASection(output)); - } - public void testIgnored(final Test test) { - formatSkip(test, JUnitVersionHelper.getIgnoreMessage(test)); - if (test != null) { - ignoredTests.put(createDescription(test), test); + @Override + protected void writeFailed(final XMLStreamWriter writer, final TestIdentifier testIdentifier) throws XMLStreamException + { + if (!failed.containsKey(testIdentifier)) + { + return; + } + writer.writeStartElement(ELEM_FAILURE); + final Optional<Throwable> cause = failed.get(testIdentifier); + if (cause.isPresent()) + { + final Throwable t = cause.get(); + final String message = t.getMessage(); + if (message != null && !message.trim().isEmpty()) + { + writeAttribute(writer, ATTR_MESSAGE, message); + } + writeAttribute(writer, ATTR_TYPE, t.getClass().getName()); + // write out the stacktrace + writer.writeCharacters(StringUtils.getStackTrace(t)); + } + writer.writeEndElement(); } - } - - public void formatSkip(final Test test, final String message) { - if (test != null) { - endTest(test); + private void writeCDataFrom(final Reader reader, final XMLStreamWriter writer) throws IOException, XMLStreamException + { + final char[] chars = new char[1024]; + int numRead; + while ((numRead = reader.read(chars)) != -1) + { + writer.writeCData(encode(new String(chars, 0, numRead))); + } } - final Element nested = doc.createElement("skipped"); - - if (message != null) { - nested.setAttribute("message", message); + @Override + protected String encode(String s) + { + boolean changed = false; + final StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) + { + if (!DOMElementWriter.isLegalXmlCharacter(c)) + { + changed = true; + sb.append("&#").append((int) c).append(';'); + } + if (c == 0xA || c == 0xD) + { + changed = true; + sb.append("&#x").append(Integer.toHexString(c)).append(';'); + } + else + { + sb.append(c); + } + } + return changed ? sb.toString() : s; } - Element currentTest; - if (test != null) { - currentTest = testElements.get(createDescription(test)); - } else { - currentTest = rootElement; + /** + * Get the local hostname. + * + * @return the name of the local host, or "localhost" if we cannot work it out + */ + private String getHostName() + { + String hostname = "localhost"; + try + { + final InetAddress localHost = InetAddress.getLocalHost(); + if (localHost != null) + hostname = localHost.getHostName(); + } + catch (final UnknownHostException e) + { + // fall back to default 'localhost' + } + return hostname; } - - currentTest.appendChild(nested); - - } - - public void testAssumptionFailure(final Test test, final Throwable failure) { - formatSkip(test, failure.getMessage()); - skippedTests.put(createDescription(test), test); - } -} // XMLJUnitResultFormatter +} diff --git a/test/unit/org/apache/cassandra/Junit4SampleTest.java b/test/unit/org/apache/cassandra/Junit4SampleTest.java index 7eb27a5..a506357 100644 --- a/test/unit/org/apache/cassandra/Junit4SampleTest.java +++ b/test/unit/org/apache/cassandra/Junit4SampleTest.java @@ -28,6 +28,8 @@ public class Junit4SampleTest @Test public void testSuccess() { + System.out.println("CUSTOM StdOut"); + System.err.println("CUSTOM StdErr"); assertTrue(true); } diff --git a/test/unit/org/apache/cassandra/Junit5SampleTest.java b/test/unit/org/apache/cassandra/Junit5SampleTest.java index 0388d3c..9e11340 100644 --- a/test/unit/org/apache/cassandra/Junit5SampleTest.java +++ b/test/unit/org/apache/cassandra/Junit5SampleTest.java @@ -29,6 +29,8 @@ public class Junit5SampleTest @Test public void testSuccess() { + System.out.println("CUSTOM StdOut"); + System.err.println("CUSTOM StdErr"); assertTrue(true); } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org