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