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