You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2022/02/02 23:46:00 UTC
[maven-surefire] branch release/2.22.3 updated: [SUREFIRE-1556] Test XML file is not valid when rerun "fails" with an assumption
This is an automated email from the ASF dual-hosted git repository.
tibordigana pushed a commit to branch release/2.22.3
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
The following commit(s) were added to refs/heads/release/2.22.3 by this push:
new d24ac6d [SUREFIRE-1556] Test XML file is not valid when rerun "fails" with an assumption
d24ac6d is described below
commit d24ac6d1ab5a2584a6d8cacf35eea693b68fc8f4
Author: Tibor Digaňa <ti...@apache.org>
AuthorDate: Fri Jan 28 01:04:12 2022 +0100
[SUREFIRE-1556] Test XML file is not valid when rerun "fails" with an assumption
(cherry picked from commit 47aebbb6d7faad3db837fe5fe93d8ffb11bf37c8)
---
.../surefire/report/StatelessXmlReporter.java | 58 ++++++++---
.../surefire/report/StatelessXmlReporterTest.java | 109 ++++++++++++++++++---
2 files changed, 137 insertions(+), 30 deletions(-)
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java
index 0773788..cd2a7ed 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java
@@ -24,7 +24,6 @@ import org.apache.maven.shared.utils.xml.XMLWriter;
import org.apache.maven.surefire.report.ReportEntry;
import org.apache.maven.surefire.report.ReporterException;
import org.apache.maven.surefire.report.SafeThrowable;
-import org.apache.maven.surefire.util.internal.StringUtils;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -33,6 +32,7 @@ import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -44,9 +44,10 @@ import java.util.StringTokenizer;
import static org.apache.commons.io.IOUtils.closeQuietly;
import static org.apache.maven.plugin.surefire.report.DefaultReporterFactory.TestResultType;
import static org.apache.maven.plugin.surefire.report.FileReporterUtils.stripIllegalFilenameChars;
+import static org.apache.maven.plugin.surefire.report.ReportEntryType.SKIPPED;
import static org.apache.maven.plugin.surefire.report.ReportEntryType.SUCCESS;
-import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
import static org.apache.maven.surefire.util.internal.StringUtils.isBlank;
+import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
@SuppressWarnings( { "javadoc", "checkstyle:javadoctype" } )
// CHECKSTYLE_OFF: LineLength
@@ -85,6 +86,10 @@ import static org.apache.maven.surefire.util.internal.StringUtils.isBlank;
@Deprecated // this is no more stateless due to existence of testClassMethodRunHistoryMap since of 2.19. Rename to StatefulXmlReporter in 3.0.
public class StatelessXmlReporter
{
+ private static final String XML_INDENT = " ";
+
+ private static final String XML_NL = "\n";
+
private final File reportsDirectory;
private final String reportNameSuffix;
@@ -128,8 +133,7 @@ public class StatelessXmlReporter
OutputStreamWriter fw = getWriter( outputStream );
try
{
- XMLWriter ppw = new PrettyPrintXMLWriter( fw );
- ppw.setEncoding( StringUtils.UTF_8.name() );
+ XMLWriter ppw = new PrettyPrintXMLWriter( new PrintWriter( fw ), XML_INDENT, XML_NL, UTF_8.name(), null );
createTestSuiteElement( ppw, testSetReportEntry, testSetStats, testSetReportEntry.elapsedTimeAsString() );
@@ -176,6 +180,11 @@ public class StatelessXmlReporter
singleRunEntry.getReportEntryType().getXmlTag(), false );
createOutErrElements( fw, ppw, singleRunEntry, outputStream );
}
+ else if ( singleRunEntry.getReportEntryType() == SKIPPED )
+ {
+ addCommentElementTestCase( "a skipped test execution in re-run phase",
+ fw, ppw, outputStream );
+ }
else
{
getTestProblems( fw, ppw, singleRunEntry, trimStackTrace, outputStream,
@@ -508,6 +517,29 @@ public class StatelessXmlReporter
return containsEscapesIllegalXml10( message ) ? escapeXml( message, attribute ) : message;
}
+ private static void addCommentElementTestCase( String comment, OutputStreamWriter outputStreamWriter,
+ XMLWriter xmlWriter, OutputStream fw )
+ {
+ try
+ {
+ xmlWriter.writeText( "" ); // Cheat sax to emit element
+ outputStreamWriter.flush();
+ fw.write( XML_NL.getBytes( UTF_8 ) );
+ fw.write( XML_INDENT.getBytes( UTF_8 ) );
+ fw.write( XML_INDENT.getBytes( UTF_8 ) );
+ fw.write( ByteConstantsHolder.COMMENT_START );
+ fw.write( comment.getBytes( UTF_8 ) );
+ fw.write( ByteConstantsHolder.COMMENT_END );
+ fw.write( XML_NL.getBytes( UTF_8 ) );
+ fw.write( XML_INDENT.getBytes( UTF_8 ) );
+ fw.flush();
+ }
+ catch ( IOException e )
+ {
+ throw new ReporterException( "When writing xml report stdout/stderr", e );
+ }
+ }
+
private static final class EncodingOutputStream
extends FilterOutputStream
{
@@ -608,20 +640,16 @@ public class StatelessXmlReporter
private static final class ByteConstantsHolder
{
- private static final byte[] CDATA_START_BYTES;
+ private static final byte[] CDATA_START_BYTES = "<![CDATA[".getBytes( UTF_8 );
- private static final byte[] CDATA_END_BYTES;
+ private static final byte[] CDATA_END_BYTES = "]]>".getBytes( UTF_8 );
- private static final byte[] CDATA_ESCAPE_STRING_BYTES;
+ private static final byte[] CDATA_ESCAPE_STRING_BYTES = "]]><![CDATA[>".getBytes( UTF_8 );
- private static final byte[] AMP_BYTES;
+ private static final byte[] AMP_BYTES = "&#".getBytes( UTF_8 );
- static
- {
- CDATA_START_BYTES = "<![CDATA[".getBytes( UTF_8 );
- CDATA_END_BYTES = "]]>".getBytes( UTF_8 );
- CDATA_ESCAPE_STRING_BYTES = "]]><![CDATA[>".getBytes( UTF_8 );
- AMP_BYTES = "&#".getBytes( UTF_8 );
- }
+ private static final byte[] COMMENT_START = "<!-- ".getBytes( UTF_8 );
+
+ private static final byte[] COMMENT_END = " --> ".getBytes( UTF_8 );
}
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java
index 445eaa8..901a249 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java
@@ -21,15 +21,16 @@ package org.apache.maven.plugin.surefire.report;
import junit.framework.TestCase;
import org.apache.maven.plugin.surefire.booterclient.output.DeserializedStacktraceWriter;
-import org.apache.maven.shared.utils.StringUtils;
import org.apache.maven.shared.utils.xml.Xpp3Dom;
import org.apache.maven.shared.utils.xml.Xpp3DomBuilder;
import org.apache.maven.surefire.report.ReportEntry;
import org.apache.maven.surefire.report.SimpleReportEntry;
import org.apache.maven.surefire.report.StackTraceWriter;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
@@ -38,10 +39,15 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
+import static org.apache.maven.plugin.surefire.report.ReportEntryType.ERROR;
+import static org.apache.maven.plugin.surefire.report.ReportEntryType.FAILURE;
+import static org.apache.maven.plugin.surefire.report.ReportEntryType.SKIPPED;
+import static org.apache.maven.plugin.surefire.report.ReportEntryType.SUCCESS;
import static org.apache.maven.surefire.util.internal.ObjectUtils.systemProps;
+import static org.apache.maven.surefire.util.internal.StringUtils.isBlank;
import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
-@SuppressWarnings( "ResultOfMethodCallIgnored" )
+@SuppressWarnings( { "ResultOfMethodCallIgnored", "checkstyle:magicnumber" } )
public class StatelessXmlReporterTest
extends TestCase
{
@@ -91,7 +97,7 @@ public class StatelessXmlReporterTest
ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), getClass().getName(), 12 );
WrappedReportEntry testSetReportEntry =
- new WrappedReportEntry( reportEntry, ReportEntryType.SUCCESS, 12, null, null, systemProps() );
+ new WrappedReportEntry( reportEntry, SUCCESS, 12, null, null, systemProps() );
stats.testSucceeded( testSetReportEntry );
reporter.testSetCompleted( testSetReportEntry, stats );
@@ -106,7 +112,7 @@ public class StatelessXmlReporterTest
{
ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), TEST_ONE, 12 );
WrappedReportEntry testSetReportEntry =
- new WrappedReportEntry( reportEntry, ReportEntryType.SUCCESS, 12, null, null, systemProps() );
+ new WrappedReportEntry( reportEntry, SUCCESS, 12, null, null, systemProps() );
expectedReportFile = new File( reportDir, "TEST-" + TEST_ONE + ".xml" );
stats.testSucceeded( testSetReportEntry );
@@ -135,7 +141,7 @@ public class StatelessXmlReporterTest
stdErr.write( stdErrBytes, 0, stdErrBytes.length );
WrappedReportEntry t2 =
new WrappedReportEntry( new SimpleReportEntry( Inner.class.getName(), TEST_TWO, stackTraceWriter, 13 ),
- ReportEntryType.ERROR, 13, stdOut, stdErr );
+ ERROR, 13, stdOut, stdErr );
stats.testSucceeded( t2 );
StatelessXmlReporter reporter = new StatelessXmlReporter( reportDir, null, false, 0,
@@ -149,8 +155,8 @@ public class StatelessXmlReporterTest
Xpp3Dom properties = testSuite.getChild( "properties" );
assertEquals( System.getProperties().size(), properties.getChildCount() );
Xpp3Dom child = properties.getChild( 1 );
- assertFalse( StringUtils.isEmpty( child.getAttribute( "value" ) ) );
- assertFalse( StringUtils.isEmpty( child.getAttribute( "name" ) ) );
+ assertFalse( isBlank( child.getAttribute( "value" ) ) );
+ assertFalse( isBlank( child.getAttribute( "name" ) ) );
Xpp3Dom[] testcase = testSuite.getChildren( "testcase" );
Xpp3Dom tca = testcase[0];
@@ -178,7 +184,7 @@ public class StatelessXmlReporterTest
ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), TEST_ONE, 12 );
WrappedReportEntry testSetReportEntry =
- new WrappedReportEntry( reportEntry, ReportEntryType.SUCCESS, 12, null, null, systemProps() );
+ new WrappedReportEntry( reportEntry, ReportEntryType.SUCCESS, 12, null, null, systemProps() );
expectedReportFile = new File( reportDir, "TEST-" + TEST_ONE + ".xml" );
stats.testSucceeded( testSetReportEntry );
@@ -194,22 +200,22 @@ public class StatelessXmlReporterTest
WrappedReportEntry testTwoFirstError =
new WrappedReportEntry( new SimpleReportEntry( Inner.class.getName(), TEST_TWO, stackTraceWriterOne, 5 ),
- ReportEntryType.ERROR, 5, createStdOutput( firstRunOut ),
+ ERROR, 5, createStdOutput( firstRunOut ),
createStdOutput( firstRunErr ) );
WrappedReportEntry testTwoSecondError =
new WrappedReportEntry( new SimpleReportEntry( Inner.class.getName(), TEST_TWO, stackTraceWriterTwo, 13 ),
- ReportEntryType.ERROR, 13, createStdOutput( secondRunOut ),
+ ERROR, 13, createStdOutput( secondRunOut ),
createStdOutput( secondRunErr ) );
WrappedReportEntry testThreeFirstRun =
new WrappedReportEntry( new SimpleReportEntry( Inner.class.getName(), TEST_THREE, stackTraceWriterOne, 13 ),
- ReportEntryType.FAILURE, 13, createStdOutput( firstRunOut ),
+ FAILURE, 13, createStdOutput( firstRunOut ),
createStdOutput( firstRunErr ) );
WrappedReportEntry testThreeSecondRun =
new WrappedReportEntry( new SimpleReportEntry( Inner.class.getName(), TEST_THREE, stackTraceWriterTwo, 2 ),
- ReportEntryType.SUCCESS, 2, createStdOutput( secondRunOut ),
+ SUCCESS, 2, createStdOutput( secondRunOut ),
createStdOutput( secondRunErr ) );
stats.testSucceeded( testTwoFirstError );
@@ -226,14 +232,14 @@ public class StatelessXmlReporterTest
FileInputStream fileInputStream = new FileInputStream( expectedReportFile );
- Xpp3Dom testSuite = Xpp3DomBuilder.build( new InputStreamReader( fileInputStream, UTF_8 ) );
+ Xpp3Dom testSuite = Xpp3DomBuilder.build( new InputStreamReader( fileInputStream, UTF_8) );
assertEquals( "testsuite", testSuite.getName() );
assertEquals( "0.012", testSuite.getAttribute( "time" ) );
Xpp3Dom properties = testSuite.getChild( "properties" );
assertEquals( System.getProperties().size(), properties.getChildCount() );
Xpp3Dom child = properties.getChild( 1 );
- assertFalse( StringUtils.isEmpty( child.getAttribute( "value" ) ) );
- assertFalse( StringUtils.isEmpty( child.getAttribute( "name" ) ) );
+ assertFalse( isBlank( child.getAttribute( "value" ) ) );
+ assertFalse( isBlank( child.getAttribute( "name" ) ) );
Xpp3Dom[] testcase = testSuite.getChildren( "testcase" );
Xpp3Dom testCaseOne = testcase[0];
@@ -277,6 +283,79 @@ public class StatelessXmlReporterTest
assertNull( testCaseThree.getChild( "system-err" ) );
}
+ public void testOutputRerunFlakyAssumption()
+ throws IOException
+ {
+ expectedReportFile = new File( reportDir, "TEST-" + getClass().getName() + ".xml" );
+
+ StackTraceWriter stackTraceWriterOne = new DeserializedStacktraceWriter( "A fud msg", "trimmed",
+ "fail at foo" );
+
+ StackTraceWriter stackTraceWriterTwo =
+ new DeserializedStacktraceWriter( "A fud msg two", "trimmed two", "fail at foo two" );
+
+ String firstRunOut = "first run out";
+ String firstRunErr = "first run err";
+ String secondRunOut = "second run out";
+ String secondRunErr = "second run err";
+
+ WrappedReportEntry testTwoFirstError =
+ new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), TEST_TWO,
+ stackTraceWriterOne, 5 ), ERROR, 5, createStdOutput( firstRunOut ),
+ createStdOutput( firstRunErr ) );
+
+ stats.testSucceeded( testTwoFirstError );
+
+ WrappedReportEntry testTwoSecondError =
+ new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), TEST_TWO,
+ stackTraceWriterTwo, 13 ), SKIPPED, 13, createStdOutput( secondRunOut ),
+ createStdOutput( secondRunErr ) );
+
+ rerunStats.testSucceeded( testTwoSecondError );
+
+ StatelessXmlReporter reporter =
+ new StatelessXmlReporter( reportDir, null, false, 1,
+ new HashMap<String, Map<String, List<WrappedReportEntry>>>(), XSD );
+
+ WrappedReportEntry testSetReportEntry =
+ new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), getClass().getName(),
+ stackTraceWriterOne, 5 ), ERROR, 20, createStdOutput( firstRunOut ),
+ createStdOutput( firstRunErr ) );
+
+ reporter.testSetCompleted( testSetReportEntry, stats );
+ reporter.testSetCompleted( testSetReportEntry, rerunStats );
+
+ FileInputStream fileInputStream = new FileInputStream( expectedReportFile );
+
+ Xpp3Dom testSuite = Xpp3DomBuilder.build( new InputStreamReader( fileInputStream, UTF_8) );
+ assertEquals( "testsuite", testSuite.getName() );
+ assertEquals( "0.02", testSuite.getAttribute( "time" ) );
+
+ Xpp3Dom[] testcase = testSuite.getChildren( "testcase" );
+ assertEquals( 1, testcase.length );
+ Xpp3Dom testCaseOne = testcase[0];
+ assertEquals( getClass().getName(), testCaseOne.getAttribute( "classname" ) );
+ assertEquals( TEST_TWO, testCaseOne.getAttribute( "name" ) );
+ assertEquals( "0.005", testCaseOne.getAttribute( "time" ) );
+
+ Xpp3Dom[] testCaseElements = testCaseOne.getChildren();
+ assertEquals( 3, testCaseElements.length );
+ assertEquals( "error", testCaseElements[0].getName() );
+ assertEquals( "system-out", testCaseElements[1].getName() );
+ assertEquals( "system-err", testCaseElements[2].getName() );
+ long linesWithComments = 0;
+ BufferedReader reader = new BufferedReader( new FileReader( expectedReportFile ) );
+ for( String line = reader.readLine(); line != null; line = reader.readLine() )
+ {
+ line = reader.readLine();
+ if ( line.contains( "<!-- a skipped test execution in re-run phase -->" ) )
+ {
+ linesWithComments++;
+ }
+ }
+ assertEquals( 1, linesWithComments );
+ }
+
private boolean defaultCharsetSupportsSpecialChar()
{
// some charsets are not able to deal with \u0115 on both ways of the conversion