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