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 java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26
27 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
28 import org.apache.maven.plugin.surefire.runorder.StatisticsReporter;
29 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
30 import org.apache.maven.surefire.report.ReportEntry;
31 import org.apache.maven.surefire.report.RunListener;
32 import org.apache.maven.surefire.report.TestSetReportEntry;
33
34 import static org.apache.maven.plugin.surefire.report.ReportEntryType.ERROR;
35 import static org.apache.maven.plugin.surefire.report.ReportEntryType.FAILURE;
36 import static org.apache.maven.plugin.surefire.report.ReportEntryType.SKIPPED;
37 import static org.apache.maven.plugin.surefire.report.ReportEntryType.SUCCESS;
38
39
40
41
42
43
44
45 public class TestSetRunListener
46 implements RunListener, ConsoleOutputReceiver, ConsoleLogger
47 {
48 private final TestSetStats detailsForThis;
49
50 private List<TestMethodStats> testMethodStats;
51
52 private Utf8RecodingDeferredFileOutputStream testStdOut = initDeferred( "stdout" );
53
54 private Utf8RecodingDeferredFileOutputStream testStdErr = initDeferred( "stderr" );
55
56 private Utf8RecodingDeferredFileOutputStream initDeferred( String channel )
57 {
58 return new Utf8RecodingDeferredFileOutputStream( channel );
59 }
60
61 private final TestcycleConsoleOutputReceiver consoleOutputReceiver;
62
63 private final boolean briefOrPlainFormat;
64
65 private final StatelessXmlReporter simpleXMLReporter;
66
67 private final ConsoleReporter consoleReporter;
68
69 private final FileReporter fileReporter;
70
71 private final StatisticsReporter statisticsReporter;
72
73 @SuppressWarnings( "checkstyle:parameternumber" )
74 public TestSetRunListener( ConsoleReporter consoleReporter, FileReporter fileReporter,
75 StatelessXmlReporter simpleXMLReporter,
76 TestcycleConsoleOutputReceiver consoleOutputReceiver,
77 StatisticsReporter statisticsReporter, boolean trimStackTrace,
78 boolean isPlainFormat, boolean briefOrPlainFormat )
79 {
80 this.consoleReporter = consoleReporter;
81 this.fileReporter = fileReporter;
82 this.statisticsReporter = statisticsReporter;
83 this.simpleXMLReporter = simpleXMLReporter;
84 this.consoleOutputReceiver = consoleOutputReceiver;
85 this.briefOrPlainFormat = briefOrPlainFormat;
86 detailsForThis = new TestSetStats( trimStackTrace, isPlainFormat );
87 testMethodStats = new ArrayList<TestMethodStats>();
88 }
89
90 @Override
91 public boolean isDebugEnabled()
92 {
93 return consoleReporter.getConsoleLogger().isDebugEnabled();
94 }
95
96 @Override
97 public void debug( String message )
98 {
99 consoleReporter.getConsoleLogger().debug( trimTrailingNewLine( message ) );
100 }
101
102 @Override
103 public boolean isInfoEnabled()
104 {
105 return consoleReporter.getConsoleLogger().isInfoEnabled();
106 }
107
108 @Override
109 public void info( String message )
110 {
111 consoleReporter.getConsoleLogger().info( trimTrailingNewLine( message ) );
112 }
113
114 @Override
115 public boolean isWarnEnabled()
116 {
117 return consoleReporter.getConsoleLogger().isWarnEnabled();
118 }
119
120 @Override
121 public void warning( String message )
122 {
123 consoleReporter.getConsoleLogger().warning( trimTrailingNewLine( message ) );
124 }
125
126 @Override
127 public boolean isErrorEnabled()
128 {
129 return consoleReporter.getConsoleLogger().isErrorEnabled();
130 }
131
132 @Override
133 public void error( String message )
134 {
135 consoleReporter.getConsoleLogger().error( trimTrailingNewLine( message ) );
136 }
137
138 @Override
139 public void error( String message, Throwable t )
140 {
141 consoleReporter.getConsoleLogger().error( message, t );
142 }
143
144 @Override
145 public void error( Throwable t )
146 {
147 consoleReporter.getConsoleLogger().error( t );
148 }
149
150 @Override
151 public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
152 {
153 try
154 {
155 if ( stdout )
156 {
157 testStdOut.write( buf, off, len );
158 }
159 else
160 {
161 testStdErr.write( buf, off, len );
162 }
163 consoleOutputReceiver.writeTestOutput( buf, off, len, stdout );
164 }
165 catch ( IOException e )
166 {
167 throw new RuntimeException( e );
168 }
169 }
170
171 @Override
172 public void testSetStarting( TestSetReportEntry report )
173 {
174 detailsForThis.testSetStart();
175 consoleReporter.testSetStarting( report );
176 consoleOutputReceiver.testSetStarting( report );
177 }
178
179 private void clearCapture()
180 {
181 testStdOut = initDeferred( "stdout" );
182 testStdErr = initDeferred( "stderr" );
183 }
184
185 @Override
186 public void testSetCompleted( TestSetReportEntry report )
187 {
188 final WrappedReportEntry wrap = wrapTestSet( report );
189 final List<String> testResults =
190 briefOrPlainFormat ? detailsForThis.getTestResults() : Collections.<String>emptyList();
191 fileReporter.testSetCompleted( wrap, detailsForThis, testResults );
192 simpleXMLReporter.testSetCompleted( wrap, detailsForThis );
193 statisticsReporter.testSetCompleted();
194 consoleReporter.testSetCompleted( wrap, detailsForThis, testResults );
195 consoleOutputReceiver.testSetCompleted( wrap );
196 consoleReporter.reset();
197
198 wrap.getStdout().free();
199 wrap.getStdErr().free();
200
201 addTestMethodStats();
202 detailsForThis.reset();
203 clearCapture();
204 }
205
206
207
208
209
210 @Override
211 public void testStarting( ReportEntry report )
212 {
213 detailsForThis.testStart();
214 }
215
216 @Override
217 public void testSucceeded( ReportEntry reportEntry )
218 {
219 WrappedReportEntry wrapped = wrap( reportEntry, SUCCESS );
220 detailsForThis.testSucceeded( wrapped );
221 statisticsReporter.testSucceeded( reportEntry );
222 clearCapture();
223 }
224
225 @Override
226 public void testError( ReportEntry reportEntry )
227 {
228 WrappedReportEntry wrapped = wrap( reportEntry, ERROR );
229 detailsForThis.testError( wrapped );
230 statisticsReporter.testError( reportEntry );
231 clearCapture();
232 }
233
234 @Override
235 public void testFailed( ReportEntry reportEntry )
236 {
237 WrappedReportEntry wrapped = wrap( reportEntry, FAILURE );
238 detailsForThis.testFailure( wrapped );
239 statisticsReporter.testFailed( reportEntry );
240 clearCapture();
241 }
242
243
244
245
246
247 @Override
248 public void testSkipped( ReportEntry reportEntry )
249 {
250 WrappedReportEntry wrapped = wrap( reportEntry, SKIPPED );
251 detailsForThis.testSkipped( wrapped );
252 statisticsReporter.testSkipped( reportEntry );
253 clearCapture();
254 }
255
256 @Override
257 public void testExecutionSkippedByUser()
258 {
259 }
260
261 @Override
262 public void testAssumptionFailure( ReportEntry report )
263 {
264 testSkipped( report );
265 }
266
267 private WrappedReportEntry wrap( ReportEntry other, ReportEntryType reportEntryType )
268 {
269 int estimatedElapsed = 0;
270 if ( reportEntryType != SKIPPED )
271 {
272 Integer etime = other.getElapsed();
273 estimatedElapsed = etime == null ? detailsForThis.getElapsedSinceLastStart() : etime;
274 }
275
276 return new WrappedReportEntry( other, reportEntryType, estimatedElapsed, testStdOut, testStdErr );
277 }
278
279 private WrappedReportEntry wrapTestSet( TestSetReportEntry other )
280 {
281 return new WrappedReportEntry( other, null, other.getElapsed() != null
282 ? other.getElapsed()
283 : detailsForThis.getElapsedSinceTestSetStart(), testStdOut, testStdErr, other.getSystemProperties() );
284 }
285
286 public void close()
287 {
288 consoleOutputReceiver.close();
289 }
290
291 private void addTestMethodStats()
292 {
293 for ( WrappedReportEntry reportEntry : detailsForThis.getReportEntries() )
294 {
295 TestMethodStats methodStats =
296 new TestMethodStats( reportEntry.getClassMethodName(), reportEntry.getReportEntryType(),
297 reportEntry.getStackTraceWriter() );
298 testMethodStats.add( methodStats );
299 }
300 }
301
302 public List<TestMethodStats> getTestMethodStats()
303 {
304 return testMethodStats;
305 }
306
307 private static String trimTrailingNewLine( final String message )
308 {
309 final int e = message == null ? 0 : lineBoundSymbolWidth( message );
310 return message != null && e != 0 ? message.substring( 0, message.length() - e ) : message;
311 }
312
313 private static int lineBoundSymbolWidth( String message )
314 {
315 return message.endsWith( "\n" ) || message.endsWith( "\r" ) ? 1 : ( message.endsWith( "\r\n" ) ? 2 : 0 );
316 }
317 }