View Javadoc
1   package org.apache.maven.plugin.surefire.report;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   * Reports data for a single test set.
41   * <br>
42   *
43   * @author Kristian Rosenvold
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 void debug( String message )
92      {
93          consoleReporter.getConsoleLogger().debug( trimTrailingNewLine( message ) );
94      }
95  
96      @Override
97      public void info( String message )
98      {
99          consoleReporter.getConsoleLogger().info( trimTrailingNewLine( message ) );
100     }
101 
102     @Override
103     public void warning( String message )
104     {
105         consoleReporter.getConsoleLogger().warning( trimTrailingNewLine( message ) );
106     }
107 
108     @Override
109     public void error( String message )
110     {
111         consoleReporter.getConsoleLogger().error( trimTrailingNewLine( message ) );
112     }
113 
114     @Override
115     public void error( String message, Throwable t )
116     {
117         consoleReporter.getConsoleLogger().error( message, t );
118     }
119 
120     @Override
121     public void error( Throwable t )
122     {
123         consoleReporter.getConsoleLogger().error( t );
124     }
125 
126     @Override
127     public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
128     {
129         try
130         {
131             if ( stdout )
132             {
133                 testStdOut.write( buf, off, len );
134             }
135             else
136             {
137                 testStdErr.write( buf, off, len );
138             }
139         }
140         catch ( IOException e )
141         {
142             throw new RuntimeException( e );
143         }
144         consoleOutputReceiver.writeTestOutput( buf, off, len, stdout );
145     }
146 
147     @Override
148     public void testSetStarting( TestSetReportEntry report )
149     {
150         detailsForThis.testSetStart();
151         consoleReporter.testSetStarting( report );
152         consoleOutputReceiver.testSetStarting( report );
153     }
154 
155     public void clearCapture()
156     {
157         testStdOut = initDeferred( "stdout" );
158         testStdErr = initDeferred( "stderr" );
159     }
160 
161     @Override
162     public void testSetCompleted( TestSetReportEntry report )
163     {
164         final WrappedReportEntry wrap = wrapTestSet( report );
165         final List<String> testResults =
166                 briefOrPlainFormat ? detailsForThis.getTestResults() : Collections.<String>emptyList();
167         fileReporter.testSetCompleted( wrap, detailsForThis, testResults );
168         simpleXMLReporter.testSetCompleted( wrap, detailsForThis );
169         statisticsReporter.testSetCompleted();
170         consoleReporter.testSetCompleted( wrap, detailsForThis, testResults );
171         consoleOutputReceiver.testSetCompleted( wrap );
172         consoleReporter.reset();
173 
174         wrap.getStdout().free();
175         wrap.getStdErr().free();
176 
177         addTestMethodStats();
178         detailsForThis.reset();
179         clearCapture();
180     }
181 
182     // ----------------------------------------------------------------------
183     // Test
184     // ----------------------------------------------------------------------
185 
186     @Override
187     public void testStarting( ReportEntry report )
188     {
189         detailsForThis.testStart();
190     }
191 
192     @Override
193     public void testSucceeded( ReportEntry reportEntry )
194     {
195         WrappedReportEntry wrapped = wrap( reportEntry, SUCCESS );
196         detailsForThis.testSucceeded( wrapped );
197         statisticsReporter.testSucceeded( reportEntry );
198         clearCapture();
199     }
200 
201     @Override
202     public void testError( ReportEntry reportEntry )
203     {
204         WrappedReportEntry wrapped = wrap( reportEntry, ERROR );
205         detailsForThis.testError( wrapped );
206         statisticsReporter.testError( reportEntry );
207         clearCapture();
208     }
209 
210     @Override
211     public void testFailed( ReportEntry reportEntry )
212     {
213         WrappedReportEntry wrapped = wrap( reportEntry, FAILURE );
214         detailsForThis.testFailure( wrapped );
215         statisticsReporter.testFailed( reportEntry );
216         clearCapture();
217     }
218 
219     // ----------------------------------------------------------------------
220     // Counters
221     // ----------------------------------------------------------------------
222 
223     @Override
224     public void testSkipped( ReportEntry reportEntry )
225     {
226         WrappedReportEntry wrapped = wrap( reportEntry, SKIPPED );
227 
228         detailsForThis.testSkipped( wrapped );
229         statisticsReporter.testSkipped( reportEntry );
230         clearCapture();
231     }
232 
233     @Override
234     public void testExecutionSkippedByUser()
235     {
236     }
237 
238     @Override
239     public void testAssumptionFailure( ReportEntry report )
240     {
241         testSkipped( report );
242     }
243 
244     private WrappedReportEntry wrap( ReportEntry other, ReportEntryType reportEntryType )
245     {
246         final int estimatedElapsed;
247         if ( reportEntryType != SKIPPED )
248         {
249             if ( other.getElapsed() != null )
250             {
251                 estimatedElapsed = other.getElapsed();
252             }
253             else
254             {
255                 estimatedElapsed = detailsForThis.getElapsedSinceLastStart();
256             }
257         }
258         else
259         {
260             estimatedElapsed = 0;
261         }
262 
263         return new WrappedReportEntry( other, reportEntryType, estimatedElapsed, testStdOut, testStdErr );
264     }
265 
266     private WrappedReportEntry wrapTestSet( TestSetReportEntry other )
267     {
268         return new WrappedReportEntry( other, null, other.getElapsed() != null
269             ? other.getElapsed()
270             : detailsForThis.getElapsedSinceTestSetStart(), testStdOut, testStdErr, other.getSystemProperties() );
271     }
272 
273     public void close()
274     {
275         consoleOutputReceiver.close();
276     }
277 
278     public void  addTestMethodStats()
279     {
280         for ( WrappedReportEntry reportEntry : detailsForThis.getReportEntries() )
281         {
282             TestMethodStats methodStats =
283                 new TestMethodStats( reportEntry.getClassMethodName(), reportEntry.getReportEntryType(),
284                                      reportEntry.getStackTraceWriter() );
285             testMethodStats.add( methodStats );
286         }
287     }
288 
289     public List<TestMethodStats> getTestMethodStats()
290     {
291         return testMethodStats;
292     }
293 
294     public static String trimTrailingNewLine( final String message )
295     {
296         final int e = message == null ? 0 : lineBoundSymbolWidth( message );
297         return message != null && e != 0 ? message.substring( 0, message.length() - e ) : message;
298     }
299 
300     private static int lineBoundSymbolWidth( String message )
301     {
302         return message.endsWith( "\n" ) || message.endsWith( "\r" ) ? 1 : ( message.endsWith( "\r\n" ) ? 2 : 0 );
303     }
304 }