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 org.apache.maven.shared.utils.logging.MessageBuilder;
23  import org.apache.maven.surefire.report.ReportEntry;
24  
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.List;
28  import java.util.Queue;
29  import java.util.concurrent.ConcurrentLinkedQueue;
30  
31  import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
32  
33  /**
34   * Maintains per-thread test result state. Not thread safe.
35   */
36  public class TestSetStats
37  {
38      private static final String TESTS = "Tests ";
39      private static final String RUN = "run: ";
40      private static final String TESTS_RUN = "Tests run: ";
41      private static final String FAILURES = "Failures: ";
42      private static final String ERRORS = "Errors: ";
43      private static final String SKIPPED = "Skipped: ";
44      private static final String FAILURE_MARKER = " <<< FAILURE!";
45      private static final String IN_MARKER = " - in ";
46      private static final String COMMA = ", ";
47  
48      private final Queue<WrappedReportEntry> reportEntries = new ConcurrentLinkedQueue<WrappedReportEntry>();
49  
50      private final boolean trimStackTrace;
51  
52      private final boolean plainFormat;
53  
54      private long testSetStartAt;
55  
56      private long testStartAt;
57  
58      private int completedCount;
59  
60      private int errors;
61  
62      private int failures;
63  
64      private int skipped;
65  
66      private long lastStartAt;
67  
68      public TestSetStats( boolean trimStackTrace, boolean plainFormat )
69      {
70          this.trimStackTrace = trimStackTrace;
71          this.plainFormat = plainFormat;
72      }
73  
74      public int getElapsedSinceTestSetStart()
75      {
76          return testSetStartAt > 0 ? (int) ( System.currentTimeMillis() - testSetStartAt ) : 0;
77      }
78  
79      public int getElapsedSinceLastStart()
80      {
81          return lastStartAt > 0 ? (int) ( System.currentTimeMillis() - lastStartAt ) : 0;
82      }
83  
84      public void testSetStart()
85      {
86          testSetStartAt = System.currentTimeMillis();
87          lastStartAt = testSetStartAt;
88      }
89  
90      public void testStart()
91      {
92          testStartAt = System.currentTimeMillis();
93          lastStartAt = testStartAt;
94      }
95  
96      private long finishTest( WrappedReportEntry reportEntry )
97      {
98          reportEntries.add( reportEntry );
99          incrementCompletedCount();
100         long testEndAt = System.currentTimeMillis();
101         // SUREFIRE-398 skipped tests call endTest without calling testStarting
102         // if startTime = 0, set it to endTime, so the diff will be 0
103         if ( testStartAt == 0 )
104         {
105             testStartAt = testEndAt;
106         }
107         Integer elapsedTime = reportEntry.getElapsed();
108         return elapsedTime != null ? elapsedTime : testEndAt - testStartAt;
109     }
110 
111     public void testSucceeded( WrappedReportEntry reportEntry )
112     {
113         finishTest( reportEntry );
114     }
115 
116     public void testError( WrappedReportEntry reportEntry )
117     {
118         errors += 1;
119         finishTest( reportEntry );
120     }
121 
122     public void testFailure( WrappedReportEntry reportEntry )
123     {
124         failures += 1;
125         finishTest( reportEntry );
126     }
127 
128     public void testSkipped( WrappedReportEntry reportEntry )
129     {
130         skipped += 1;
131         finishTest( reportEntry );
132     }
133 
134     public void reset()
135     {
136         completedCount = 0;
137         errors = 0;
138         failures = 0;
139         skipped = 0;
140 
141         for ( WrappedReportEntry entry : reportEntries )
142         {
143             entry.getStdout().free();
144             entry.getStdErr().free();
145         }
146 
147         reportEntries.clear();
148     }
149 
150     public int getCompletedCount()
151     {
152         return completedCount;
153     }
154 
155     public int getErrors()
156     {
157         return errors;
158     }
159 
160     public int getFailures()
161     {
162         return failures;
163     }
164 
165     public int getSkipped()
166     {
167         return skipped;
168     }
169 
170     public String elapsedTimeAsString( long runTime )
171     {
172         return ReporterUtils.formatElapsedTime( runTime );
173     }
174 
175     private void incrementCompletedCount()
176     {
177         completedCount += 1;
178     }
179 
180     public String getTestSetSummary( WrappedReportEntry reportEntry )
181     {
182         String summary = TESTS_RUN + completedCount
183                                  + COMMA
184                                  + FAILURES + failures
185                                  + COMMA
186                                  + ERRORS + errors
187                                  + COMMA
188                                  + SKIPPED + skipped
189                                  + COMMA
190                                  + reportEntry.getElapsedTimeVerbose();
191 
192         if ( failures > 0 || errors > 0 )
193         {
194             summary += FAILURE_MARKER;
195         }
196 
197         summary += IN_MARKER + reportEntry.getNameWithGroup();
198 
199         return summary;
200     }
201 
202     public String getColoredTestSetSummary( WrappedReportEntry reportEntry )
203     {
204         final boolean isSuccessful = failures == 0 && errors == 0 && skipped == 0;
205         final boolean isFailure = failures > 0;
206         final boolean isError = errors > 0;
207         final boolean isFailureOrError = isFailure | isError;
208         final boolean isSkipped = skipped > 0;
209         final  MessageBuilder builder = buffer();
210         if ( isSuccessful )
211         {
212             if ( completedCount == 0 )
213             {
214                 builder.strong( TESTS_RUN ).strong( completedCount );
215             }
216             else
217             {
218                 builder.success( TESTS_RUN ).success( completedCount );
219             }
220         }
221         else
222         {
223             if ( isFailureOrError )
224             {
225                 builder.failure( TESTS ).strong( RUN ).strong( completedCount );
226             }
227             else
228             {
229                 builder.warning( TESTS ).strong( RUN ).strong( completedCount );
230             }
231         }
232         builder.a( COMMA );
233         if ( isFailure )
234         {
235             builder.failure( FAILURES ).failure( failures );
236         }
237         else
238         {
239             builder.a( FAILURES ).a( failures );
240         }
241         builder.a( COMMA );
242         if ( isError )
243         {
244             builder.failure( ERRORS ).failure( errors );
245         }
246         else
247         {
248             builder.a( ERRORS ).a( errors );
249         }
250         builder.a( COMMA );
251         if ( isSkipped )
252         {
253             builder.warning( SKIPPED ).warning( skipped );
254         }
255         else
256         {
257             builder.a( SKIPPED ).a( skipped );
258         }
259         builder.a( COMMA )
260                 .a( reportEntry.getElapsedTimeVerbose() );
261         if ( isFailureOrError )
262         {
263             builder.failure( FAILURE_MARKER );
264         }
265         builder.a( IN_MARKER );
266         return concatenateWithTestGroup( builder, reportEntry );
267     }
268 
269     public List<String> getTestResults()
270     {
271         List<String> result = new ArrayList<String>();
272         for ( WrappedReportEntry testResult : reportEntries )
273         {
274             if ( testResult.isErrorOrFailure() )
275             {
276                 result.add( testResult.getOutput( trimStackTrace ) );
277             }
278             else if ( plainFormat && testResult.isSkipped() )
279             {
280                 result.add( testResult.getName() + " skipped" );
281             }
282             else if ( plainFormat && testResult.isSucceeded() )
283             {
284                 result.add( testResult.getElapsedTimeSummary() );
285             }
286         }
287         return result;
288     }
289 
290     public Collection<WrappedReportEntry> getReportEntries()
291     {
292         return reportEntries;
293     }
294 
295     /**
296      * Append the test set message for a report.
297      * e.g. "org.foo.BarTest ( of group )"
298      *
299      * @param builder    MessageBuilder with preceded text inside
300      * @param report     report whose test set is starting
301      * @return the message
302      */
303     public static String concatenateWithTestGroup( MessageBuilder builder, ReportEntry report )
304     {
305         final String testClass = report.getNameWithGroup();
306         int delimiter = testClass.lastIndexOf( '.' );
307         String pkg = testClass.substring( 0, 1 + delimiter );
308         String cls = testClass.substring( 1 + delimiter );
309         return builder.a( pkg )
310                        .strong( cls )
311                        .toString();
312     }
313 }