1 package org.apache.maven.plugin.surefire.report;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import junit.framework.TestCase;
23 import org.apache.maven.plugin.surefire.booterclient.output.DeserializedStacktraceWriter;
24 import org.apache.maven.surefire.shared.utils.StringUtils;
25 import org.apache.maven.surefire.shared.utils.xml.Xpp3Dom;
26 import org.apache.maven.surefire.shared.utils.xml.Xpp3DomBuilder;
27 import org.apache.maven.surefire.api.report.ReportEntry;
28 import org.apache.maven.surefire.api.report.SimpleReportEntry;
29 import org.apache.maven.surefire.api.report.StackTraceWriter;
30
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.IOException;
34 import java.io.InputStreamReader;
35 import java.util.Deque;
36 import java.util.HashMap;
37 import java.util.concurrent.ConcurrentHashMap;
38 import java.util.concurrent.atomic.AtomicInteger;
39
40 import static java.nio.charset.StandardCharsets.UTF_8;
41 import static org.apache.maven.surefire.api.util.internal.ObjectUtils.systemProps;
42
43
44
45
46 @SuppressWarnings( "ResultOfMethodCallIgnored" )
47 public class StatelessXmlReporterTest
48 extends TestCase
49 {
50 private static final String XSD =
51 "https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd";
52 private static final String TEST_ONE = "aTestMethod";
53 private static final String TEST_TWO = "bTestMethod";
54 private static final String TEST_THREE = "cTestMethod";
55 private static final AtomicInteger FOLDER_POSTFIX = new AtomicInteger();
56
57 private TestSetStats stats;
58 private TestSetStats rerunStats;
59 private File expectedReportFile;
60 private File reportDir;
61
62 @Override
63 protected void setUp()
64 throws Exception
65 {
66 stats = new TestSetStats( false, true );
67 rerunStats = new TestSetStats( false, true );
68
69 File basedir = new File( "." );
70 File target = new File( basedir.getCanonicalFile(), "target" );
71 target.mkdir();
72 String reportRelDir = getClass().getSimpleName() + "-" + FOLDER_POSTFIX.incrementAndGet();
73 reportDir = new File( target, reportRelDir );
74 reportDir.mkdir();
75 }
76
77 @Override
78 protected void tearDown()
79 {
80 if ( expectedReportFile != null )
81 {
82 expectedReportFile.delete();
83 }
84 }
85
86 public void testFileNameWithoutSuffix()
87 {
88 StatelessXmlReporter reporter =
89 new StatelessXmlReporter( reportDir, null, false, 0,
90 new ConcurrentHashMap<String, Deque<WrappedReportEntry>>(), XSD, "3.0",
91 false, false, false, false );
92 reporter.cleanTestHistoryMap();
93
94 ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), null, getClass().getName(), null, 12 );
95 WrappedReportEntry testSetReportEntry = new WrappedReportEntry( reportEntry, ReportEntryType.SUCCESS,
96 12, null, null, systemProps() );
97 stats.testSucceeded( testSetReportEntry );
98 reporter.testSetCompleted( testSetReportEntry, stats );
99
100 expectedReportFile = new File( reportDir, "TEST-" + getClass().getName() + ".xml" );
101 assertTrue( "Report file (" + expectedReportFile.getAbsolutePath() + ") doesn't exist",
102 expectedReportFile.exists() );
103 }
104
105
106 public void testAllFieldsSerialized()
107 throws IOException
108 {
109 ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), null, TEST_ONE, null, 12 );
110 WrappedReportEntry testSetReportEntry =
111 new WrappedReportEntry( reportEntry, ReportEntryType.SUCCESS, 12, null, null, systemProps() );
112 expectedReportFile = new File( reportDir, "TEST-" + getClass().getName() + ".xml" );
113
114 stats.testSucceeded( testSetReportEntry );
115 StackTraceWriter stackTraceWriter = new DeserializedStacktraceWriter( "A fud msg", "trimmed", "fail at foo" );
116 Utf8RecodingDeferredFileOutputStream stdOut = new Utf8RecodingDeferredFileOutputStream( "fds" );
117 String stdOutPrefix;
118 String stdErrPrefix;
119 if ( defaultCharsetSupportsSpecialChar() )
120 {
121 stdErrPrefix = "std-\u0115rr";
122 stdOutPrefix = "st]]>d-o\u00DCt";
123 }
124 else
125 {
126 stdErrPrefix = "std-err";
127 stdOutPrefix = "st]]>d-out";
128 }
129
130 stdOut.write( stdOutPrefix + "<null>!\u0020\u0000\u001F", false );
131
132 Utf8RecodingDeferredFileOutputStream stdErr = new Utf8RecodingDeferredFileOutputStream( "fds" );
133
134 stdErr.write( stdErrPrefix + "?&-&£\u0020\u0000\u001F", false );
135 WrappedReportEntry t2 =
136 new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_TWO, null,
137 stackTraceWriter, 13 ), ReportEntryType.ERROR, 13, stdOut, stdErr );
138
139 stats.testSucceeded( t2 );
140 StatelessXmlReporter reporter = new StatelessXmlReporter( reportDir, null, false, 0,
141 new ConcurrentHashMap<String, Deque<WrappedReportEntry>>(), XSD, "3.0", false, false, false, false );
142 reporter.testSetCompleted( testSetReportEntry, stats );
143
144 FileInputStream fileInputStream = new FileInputStream( expectedReportFile );
145
146 Xpp3Dom testSuite = Xpp3DomBuilder.build( new InputStreamReader( fileInputStream, UTF_8 ) );
147 assertEquals( "testsuite", testSuite.getName() );
148 Xpp3Dom properties = testSuite.getChild( "properties" );
149 assertEquals( System.getProperties().size(), properties.getChildCount() );
150 Xpp3Dom child = properties.getChild( 1 );
151 assertFalse( StringUtils.isEmpty( child.getAttribute( "value" ) ) );
152 assertFalse( StringUtils.isEmpty( child.getAttribute( "name" ) ) );
153
154 Xpp3Dom[] testcase = testSuite.getChildren( "testcase" );
155 Xpp3Dom tca = testcase[0];
156 assertEquals( TEST_ONE, tca.getAttribute( "name" ) );
157 assertEquals( "0.012", tca.getAttribute( "time" ) );
158 assertEquals( getClass().getName(), tca.getAttribute( "classname" ) );
159
160 Xpp3Dom tcb = testcase[1];
161 assertEquals( TEST_TWO, tcb.getAttribute( "name" ) );
162 assertEquals( "0.013", tcb.getAttribute( "time" ) );
163 assertEquals( getClass().getName(), tcb.getAttribute( "classname" ) );
164 Xpp3Dom errorNode = tcb.getChild( "error" );
165 assertNotNull( errorNode );
166 assertEquals( "A fud msg", errorNode.getAttribute( "message" ) );
167 assertEquals( "fail at foo", errorNode.getAttribute( "type" ) );
168 assertEquals( stdOutPrefix + "<null>! &#0;&#31;", tcb.getChild( "system-out" ).getValue() );
169
170
171 assertEquals( stdErrPrefix + "?&-&£ &#0;&#31;", tcb.getChild( "system-err" ).getValue() );
172 }
173
174 public void testOutputRerunFlakyFailure()
175 throws IOException
176 {
177 WrappedReportEntry testSetReportEntry =
178 new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_ONE, null, 12 ),
179 ReportEntryType.SUCCESS, 12, null, null, systemProps() );
180 expectedReportFile = new File( reportDir, "TEST-" + getClass().getName() + ".xml" );
181
182 stats.testSucceeded( testSetReportEntry );
183 StackTraceWriter stackTraceWriterOne = new DeserializedStacktraceWriter( "A fud msg", "trimmed",
184 "fail at foo" );
185 StackTraceWriter stackTraceWriterTwo =
186 new DeserializedStacktraceWriter( "A fud msg two", "trimmed two", "fail at foo two" );
187
188 String firstRunOut = "first run out";
189 String firstRunErr = "first run err";
190 String secondRunOut = "second run out";
191 String secondRunErr = "second run err";
192
193 WrappedReportEntry testTwoFirstError =
194 new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_TWO, null,
195 stackTraceWriterOne, 5 ), ReportEntryType.ERROR, 5, createStdOutput( firstRunOut ),
196 createStdOutput( firstRunErr ) );
197
198 WrappedReportEntry testTwoSecondError =
199 new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_TWO, null,
200 stackTraceWriterTwo, 13 ), ReportEntryType.ERROR, 13, createStdOutput( secondRunOut ),
201 createStdOutput( secondRunErr ) );
202
203 WrappedReportEntry testThreeFirstRun =
204 new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_THREE, null,
205 stackTraceWriterOne, 13 ), ReportEntryType.FAILURE, 13, createStdOutput( firstRunOut ),
206 createStdOutput( firstRunErr ) );
207
208 WrappedReportEntry testThreeSecondRun =
209 new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_THREE, null,
210 stackTraceWriterTwo, 2 ), ReportEntryType.SUCCESS, 2, createStdOutput( secondRunOut ),
211 createStdOutput( secondRunErr ) );
212
213 stats.testSucceeded( testTwoFirstError );
214 stats.testSucceeded( testThreeFirstRun );
215 rerunStats.testSucceeded( testTwoSecondError );
216 rerunStats.testSucceeded( testThreeSecondRun );
217
218 StatelessXmlReporter reporter =
219 new StatelessXmlReporter( reportDir, null, false, 1,
220 new HashMap<String, Deque<WrappedReportEntry>>(), XSD, "3.0", false, false, false, false );
221
222 reporter.testSetCompleted( testSetReportEntry, stats );
223 reporter.testSetCompleted( testSetReportEntry, rerunStats );
224
225 FileInputStream fileInputStream = new FileInputStream( expectedReportFile );
226
227 Xpp3Dom testSuite = Xpp3DomBuilder.build( new InputStreamReader( fileInputStream, UTF_8 ) );
228 assertEquals( "testsuite", testSuite.getName() );
229 assertEquals( "0.012", testSuite.getAttribute( "time" ) );
230 Xpp3Dom properties = testSuite.getChild( "properties" );
231 assertEquals( System.getProperties().size(), properties.getChildCount() );
232 Xpp3Dom child = properties.getChild( 1 );
233 assertFalse( StringUtils.isEmpty( child.getAttribute( "value" ) ) );
234 assertFalse( StringUtils.isEmpty( child.getAttribute( "name" ) ) );
235
236 Xpp3Dom[] testcase = testSuite.getChildren( "testcase" );
237 Xpp3Dom testCaseOne = testcase[0];
238 assertEquals( TEST_ONE, testCaseOne.getAttribute( "name" ) );
239 assertEquals( "0.012", testCaseOne.getAttribute( "time" ) );
240 assertEquals( getClass().getName(), testCaseOne.getAttribute( "classname" ) );
241
242 Xpp3Dom testCaseTwo = testcase[1];
243 assertEquals( TEST_TWO, testCaseTwo.getAttribute( "name" ) );
244
245 assertEquals( "0.005", testCaseTwo.getAttribute( "time" ) );
246 assertEquals( getClass().getName(), testCaseTwo.getAttribute( "classname" ) );
247 Xpp3Dom errorNode = testCaseTwo.getChild( "error" );
248 Xpp3Dom rerunErrorNode = testCaseTwo.getChild( "rerunError" );
249 assertNotNull( errorNode );
250 assertNotNull( rerunErrorNode );
251
252 assertEquals( "A fud msg", errorNode.getAttribute( "message" ) );
253 assertEquals( "fail at foo", errorNode.getAttribute( "type" ) );
254
255
256 assertEquals( firstRunOut, testCaseTwo.getChild( "system-out" ).getValue() );
257 assertEquals( firstRunErr, testCaseTwo.getChild( "system-err" ).getValue() );
258 assertEquals( secondRunOut, rerunErrorNode.getChild( "system-out" ).getValue() );
259 assertEquals( secondRunErr, rerunErrorNode.getChild( "system-err" ).getValue() );
260 assertEquals( "A fud msg two", rerunErrorNode.getAttribute( "message" ) );
261 assertEquals( "fail at foo two", rerunErrorNode.getAttribute( "type" ) );
262
263
264 Xpp3Dom testCaseThree = testcase[2];
265 assertEquals( TEST_THREE, testCaseThree.getAttribute( "name" ) );
266
267 assertEquals( "0.002", testCaseThree.getAttribute( "time" ) );
268 assertEquals( getClass().getName(), testCaseThree.getAttribute( "classname" ) );
269 Xpp3Dom flakyFailureNode = testCaseThree.getChild( "flakyFailure" );
270 assertNotNull( flakyFailureNode );
271 assertEquals( firstRunOut, flakyFailureNode.getChild( "system-out" ).getValue() );
272 assertEquals( firstRunErr, flakyFailureNode.getChild( "system-err" ).getValue() );
273
274 assertNull( testCaseThree.getChild( "system-out" ) );
275 assertNull( testCaseThree.getChild( "system-err" ) );
276 }
277
278 private boolean defaultCharsetSupportsSpecialChar()
279 {
280
281 return "\u0115\u00DC".equals( new String( "\u0115\u00DC".getBytes() ) );
282 }
283
284 private Utf8RecodingDeferredFileOutputStream createStdOutput( String content )
285 throws IOException
286 {
287 Utf8RecodingDeferredFileOutputStream stdOut = new Utf8RecodingDeferredFileOutputStream( "fds2" );
288 stdOut.write( content, false );
289 return stdOut;
290 }
291 }