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.util.ArrayList;
23  import java.util.Collections;
24  import java.util.List;
25  import org.apache.maven.plugin.surefire.runorder.StatisticsReporter;
26  import org.apache.maven.surefire.report.ConsoleLogger;
27  import org.apache.maven.surefire.report.ConsoleOutputReceiver;
28  import org.apache.maven.surefire.report.ReportEntry;
29  import org.apache.maven.surefire.report.RunListener;
30  import org.apache.maven.surefire.report.RunStatistics;
31  import org.apache.maven.surefire.util.internal.ByteBuffer;
32  
33  /**
34   * Reports data for a single test set.
35   * <p/>
36   * 
37   * @author Kristian Rosenvold
38   */
39  public class TestSetRunListener
40      implements RunListener, ConsoleOutputReceiver, ConsoleLogger
41  {
42      private final RunStatistics globalStatistics;
43  
44      private final TestSetStats detailsForThis;
45  
46      private final List<ByteBuffer> testStdOut = Collections.synchronizedList( new ArrayList<ByteBuffer>() );
47  
48      private final List<ByteBuffer> testStdErr = Collections.synchronizedList( new ArrayList<ByteBuffer>() );
49  
50      private final TestcycleConsoleOutputReceiver consoleOutputReceiver;
51  
52      private final boolean briefOrPlainFormat;
53  
54      private final StatelessXmlReporter simpleXMLReporter;
55  
56      private final ConsoleReporter consoleReporter;
57  
58      private final FileReporter fileReporter;
59  
60      private final StatisticsReporter statisticsReporter;
61  
62      public TestSetRunListener( ConsoleReporter consoleReporter, FileReporter fileReporter,
63                                 StatelessXmlReporter simpleXMLReporter,
64                                 TestcycleConsoleOutputReceiver consoleOutputReceiver,
65                                 StatisticsReporter statisticsReporter, RunStatistics globalStats,
66                                 boolean trimStackTrace, boolean isPlainFormat, boolean briefOrPlainFormat )
67      {
68          this.consoleReporter = consoleReporter;
69          this.fileReporter = fileReporter;
70          this.statisticsReporter = statisticsReporter;
71          this.simpleXMLReporter = simpleXMLReporter;
72          this.consoleOutputReceiver = consoleOutputReceiver;
73          this.briefOrPlainFormat = briefOrPlainFormat;
74          this.detailsForThis = new TestSetStats( trimStackTrace, isPlainFormat );
75          this.globalStatistics = globalStats;
76      }
77  
78      public void info( String message )
79      {
80          if ( consoleReporter != null )
81          {
82              consoleReporter.writeMessage( message );
83          }
84      }
85  
86      public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
87      {
88          ByteBuffer byteBuffer = new ByteBuffer( buf, off, len );
89          if ( stdout )
90          {
91              testStdOut.add( byteBuffer );
92          }
93          else
94          {
95              testStdErr.add( byteBuffer );
96          }
97          consoleOutputReceiver.writeTestOutput( buf, off, len, stdout );
98      }
99  
100     public void testSetStarting( ReportEntry report )
101     {
102         detailsForThis.testSetStart();
103         if ( consoleReporter != null )
104         {
105             consoleReporter.testSetStarting( report );
106         }
107         consoleOutputReceiver.testSetStarting( report );
108     }
109 
110     public void clearCapture()
111     {
112         testStdErr.clear();
113         testStdOut.clear();
114     }
115 
116     public void testSetCompleted( ReportEntry report )
117     {
118         WrappedReportEntry wrap = wrapTestSet( report );
119         List<String> testResults = briefOrPlainFormat ? detailsForThis.getTestResults() : null;
120         if ( consoleReporter != null )
121         {
122             consoleReporter.testSetCompleted( wrap, detailsForThis, testResults );
123         }
124         consoleOutputReceiver.testSetCompleted( wrap );
125         if ( fileReporter != null )
126         {
127             fileReporter.testSetCompleted( wrap, detailsForThis, testResults );
128         }
129         if ( simpleXMLReporter != null )
130         {
131             simpleXMLReporter.testSetCompleted( wrap, detailsForThis );
132         }
133         if ( statisticsReporter != null )
134         {
135             statisticsReporter.testSetCompleted();
136         }
137         if ( consoleReporter != null )
138         {
139             consoleReporter.reset();
140         }
141 
142         globalStatistics.add( detailsForThis );
143         detailsForThis.reset();
144 
145     }
146 
147     // ----------------------------------------------------------------------
148     // Test
149     // ----------------------------------------------------------------------
150 
151     public void testStarting( ReportEntry report )
152     {
153         detailsForThis.testStart();
154 
155     }
156 
157     public void testSucceeded( ReportEntry reportEntry )
158     {
159         WrappedReportEntry wrapped = wrap( reportEntry, ReportEntryType.success );
160         detailsForThis.testSucceeded( wrapped );
161         if ( statisticsReporter != null )
162         {
163             statisticsReporter.testSucceeded( reportEntry );
164         }
165         clearCapture();
166     }
167 
168     public void testError( ReportEntry reportEntry )
169     {
170         WrappedReportEntry wrapped = wrap( reportEntry, ReportEntryType.error );
171         detailsForThis.testError( wrapped );
172         if ( statisticsReporter != null )
173         {
174             statisticsReporter.testError( reportEntry );
175         }
176         globalStatistics.addErrorSource( reportEntry.getStackTraceWriter() );
177         clearCapture();
178     }
179 
180     public void testFailed( ReportEntry reportEntry )
181     {
182         WrappedReportEntry wrapped = wrap( reportEntry, ReportEntryType.failure );
183         detailsForThis.testFailure( wrapped );
184         if ( statisticsReporter != null )
185         {
186             statisticsReporter.testFailed( reportEntry );
187         }
188         globalStatistics.addFailureSource( reportEntry.getStackTraceWriter() );
189         clearCapture();
190     }
191 
192     // ----------------------------------------------------------------------
193     // Counters
194     // ----------------------------------------------------------------------
195 
196     public void testSkipped( ReportEntry reportEntry )
197     {
198         WrappedReportEntry wrapped = wrap( reportEntry, ReportEntryType.skipped );
199         detailsForThis.testSkipped( wrapped );
200         if ( statisticsReporter != null )
201         {
202             statisticsReporter.testSkipped( reportEntry );
203         }
204         clearCapture();
205     }
206 
207     public void testAssumptionFailure( ReportEntry report )
208     {
209         testSkipped( report );
210     }
211 
212     public String getAsString( List<ByteBuffer> byteBufferList )
213     {
214         StringBuilder stringBuffer = new StringBuilder();
215         // To avoid getting a java.util.ConcurrentModificationException while iterating (see SUREFIRE-879) we need to
216         // iterate over a copy or the elements array. Since the passed in byteBufferList is always wrapped with
217         // Collections.synchronizedList( ) we are guaranteed toArray() is going to be atomic, so we are safe.
218         for ( Object byteBuffer : byteBufferList.toArray() )
219         {
220             stringBuffer.append( byteBuffer.toString() );
221         }
222         return stringBuffer.toString();
223     }
224 
225     private WrappedReportEntry wrap( ReportEntry other, ReportEntryType reportEntryType )
226     {
227         final int estimatedElapsed;
228         if ( reportEntryType != ReportEntryType.skipped )
229         {
230             if ( other.getElapsed() != null )
231             {
232                 estimatedElapsed = other.getElapsed();
233             }
234             else
235             {
236                 estimatedElapsed = detailsForThis.getElapsedSinceLastStart();
237             }
238         }
239         else
240         {
241             estimatedElapsed = 0;
242         }
243 
244         return new WrappedReportEntry( other, reportEntryType, estimatedElapsed, getAsString( testStdOut ),
245                                        getAsString( testStdErr ) );
246     }
247 
248     private WrappedReportEntry wrapTestSet( ReportEntry other )
249     {
250         return new WrappedReportEntry( other, null, other.getElapsed() != null 
251                         ? other.getElapsed()
252                         : detailsForThis.getElapsedSinceTestSetStart(), getAsString( testStdOut ),
253                                        getAsString( testStdErr ) );
254     }
255 
256     public void close()
257     {
258         if ( consoleOutputReceiver != null )
259         {
260             consoleOutputReceiver.close();
261         }
262     }
263 }