View Javadoc
1   package org.apache.maven.surefire.suite;
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.ByteArrayOutputStream;
23  import java.io.PrintWriter;
24  
25  /**
26   * Represents a test-run-result; this may be from a single test run or an aggregated result.
27   * <br>
28   * In the case of timeout==true, the run-counts reflect the state of the test-run at the time
29   * of the timeout.
30   *
31   * @author Kristian Rosenvold
32   */
33  public class RunResult
34  {
35      private final int completedCount;
36  
37      private final int errors;
38  
39      private final int failures;
40  
41      private final int skipped;
42  
43      private final int flakes;
44  
45      private final String failure;
46  
47      private final boolean timeout;
48  
49      public static final int SUCCESS = 0;
50  
51      private static final int FAILURE = 255;
52  
53      private static final int NO_TESTS = 254;
54  
55      public static RunResult timeout( RunResult accumulatedAtTimeout )
56      {
57          return errorCode( accumulatedAtTimeout, accumulatedAtTimeout.getFailure(), true );
58      }
59  
60      public static RunResult failure( RunResult accumulatedAtTimeout, Exception cause )
61      {
62          return errorCode( accumulatedAtTimeout, getStackTrace( cause ), accumulatedAtTimeout.isTimeout() );
63      }
64  
65      private static RunResult errorCode( RunResult other, String failure, boolean timeout )
66      {
67          return new RunResult( other.getCompletedCount(), other.getErrors(), other.getFailures(), other.getSkipped(),
68                                      failure, timeout );
69      }
70  
71      public RunResult( int completedCount, int errors, int failures, int skipped )
72      {
73          this( completedCount, errors, failures, skipped, null, false );
74      }
75  
76      public RunResult( int completedCount, int errors, int failures, int skipped, int flakes )
77      {
78          this( completedCount, errors, failures, skipped, flakes, null, false );
79      }
80  
81      public RunResult( int completedCount, int errors, int failures, int skipped, String failure, boolean timeout )
82      {
83          this( completedCount, errors, failures, skipped, 0, failure, timeout );
84      }
85  
86      public RunResult( int completedCount, int errors, int failures, int skipped, int flakes, String failure,
87                        boolean timeout )
88      {
89          this.completedCount = completedCount;
90          this.errors = errors;
91          this.failures = failures;
92          this.skipped = skipped;
93          this.failure = failure;
94          this.timeout = timeout;
95          this.flakes = flakes;
96      }
97  
98      private static String getStackTrace( Exception e )
99      {
100         if ( e == null )
101         {
102             return null;
103         }
104         ByteArrayOutputStream out = new ByteArrayOutputStream();
105         try ( PrintWriter pw = new PrintWriter( out ) )
106         {
107             e.printStackTrace( pw );
108         }
109         return new String( out.toByteArray() );
110     }
111 
112     public int getCompletedCount()
113     {
114         return completedCount;
115     }
116 
117     public int getErrors()
118     {
119         return errors;
120     }
121 
122     public int getFlakes()
123     {
124         return flakes;
125     }
126 
127     public int getFailures()
128     {
129         return failures;
130     }
131 
132     public int getSkipped()
133     {
134         return skipped;
135     }
136 
137     public Integer getFailsafeCode()  // Only used for compatibility reasons.
138     {
139         if ( completedCount == 0 )
140         {
141             return NO_TESTS;
142         }
143         if ( !isErrorFree() )
144         {
145             return FAILURE;
146         }
147         return null;
148     }
149 
150     /* Indicates if the tests are error free */
151     public boolean isErrorFree()
152     {
153         return getFailures() == 0 && getErrors() == 0 && !isFailure();
154     }
155 
156     public boolean isInternalError()
157     {
158         return getFailures() == 0 && getErrors() == 0 && isFailure();
159     }
160 
161     /* Indicates test timeout or technical failure */
162     public boolean isFailureOrTimeout()
163     {
164         return isTimeout() || isFailure();
165     }
166 
167     public boolean isFailure()
168     {
169         return failure != null;
170     }
171 
172     public String getFailure()
173     {
174         return failure;
175     }
176 
177     public boolean isTimeout()
178     {
179         return timeout;
180     }
181 
182     public RunResult aggregate( RunResult other )
183     {
184         String failureMessage = getFailure() != null ? getFailure() : other.getFailure();
185         boolean timeout = isTimeout() || other.isTimeout();
186         int completed = getCompletedCount() + other.getCompletedCount();
187         int fail = getFailures() + other.getFailures();
188         int ign = getSkipped() + other.getSkipped();
189         int err = getErrors() + other.getErrors();
190         int flakes = getFlakes() + other.getFlakes();
191         return new RunResult( completed, err, fail, ign, flakes, failureMessage, timeout );
192     }
193 
194     public static RunResult noTestsRun()
195     {
196         return new RunResult( 0, 0, 0, 0 );
197     }
198 
199     @Override
200     @SuppressWarnings( "RedundantIfStatement" )
201     public boolean equals( Object o )
202     {
203         if ( this == o )
204         {
205             return true;
206         }
207         if ( o == null || getClass() != o.getClass() )
208         {
209             return false;
210         }
211 
212         RunResult runResult = (RunResult) o;
213 
214         if ( completedCount != runResult.completedCount )
215         {
216             return false;
217         }
218         if ( errors != runResult.errors )
219         {
220             return false;
221         }
222         if ( failures != runResult.failures )
223         {
224             return false;
225         }
226         if ( skipped != runResult.skipped )
227         {
228             return false;
229         }
230         if ( timeout != runResult.timeout )
231         {
232             return false;
233         }
234         if ( failure != null ? !failure.equals( runResult.failure ) : runResult.failure != null )
235         {
236             return false;
237         }
238 
239         return true;
240     }
241 
242     @Override
243     public int hashCode()
244     {
245         int result = completedCount;
246         result = 31 * result + errors;
247         result = 31 * result + failures;
248         result = 31 * result + skipped;
249         result = 31 * result + ( failure != null ? failure.hashCode() : 0 );
250         result = 31 * result + ( timeout ? 1 : 0 );
251         return result;
252     }
253 }