Coverage Report - org.apache.maven.surefire.suite.RunResult
 
Classes in this File Line Coverage Branch Coverage Complexity
RunResult
73%
79/107
51%
30/58
2,4
 
 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.BufferedInputStream;
 23  
 import java.io.ByteArrayOutputStream;
 24  
 import java.io.File;
 25  
 import java.io.FileInputStream;
 26  
 import java.io.FileNotFoundException;
 27  
 import java.io.FileWriter;
 28  
 import java.io.IOException;
 29  
 import java.io.InputStream;
 30  
 import java.io.PrintWriter;
 31  
 import org.apache.maven.shared.utils.StringUtils;
 32  
 import org.apache.maven.shared.utils.io.IOUtil;
 33  
 import org.apache.maven.shared.utils.xml.PrettyPrintXMLWriter;
 34  
 import org.apache.maven.shared.utils.xml.Xpp3Dom;
 35  
 import org.apache.maven.shared.utils.xml.Xpp3DomBuilder;
 36  
 import org.apache.maven.shared.utils.xml.Xpp3DomWriter;
 37  
 
 38  
 /**
 39  
  * Represents a test-run-result; this may be from a single test run or an aggregated result.
 40  
  * <p/>
 41  
  * In the case of timeout==true, the run-counts reflect the state of the test-run at the time
 42  
  * of the timeout.
 43  
  *
 44  
  * @author Kristian Rosenvold
 45  
  */
 46  
 public class RunResult
 47  
 {
 48  
     private final int completedCount;
 49  
 
 50  
     private final int errors;
 51  
 
 52  
     private final int failures;
 53  
 
 54  
     private final int skipped;
 55  
 
 56  
     private final String failure;
 57  
 
 58  
     private final boolean timeout;
 59  
 
 60  
     public static final int SUCCESS = 0;
 61  
 
 62  
     private static final int FAILURE = 255;
 63  
 
 64  
     private static final int NO_TESTS = 254;
 65  
 
 66  
     public static RunResult timeout( RunResult accumulatedAtTimeout )
 67  
     {
 68  0
         return errorCode( accumulatedAtTimeout, accumulatedAtTimeout.getFailure(), true );
 69  
     }
 70  
 
 71  
     public static RunResult failure( RunResult accumulatedAtTimeout, Exception cause )
 72  
     {
 73  0
         return errorCode( accumulatedAtTimeout, getStackTrace( cause ), accumulatedAtTimeout.isTimeout() );
 74  
     }
 75  
 
 76  
     private static RunResult errorCode( RunResult other, String failure, boolean timeout )
 77  
     {
 78  0
         return new RunResult( other.getCompletedCount(), other.getErrors(), other.getFailures(), other.getSkipped(),
 79  
                               failure, timeout );
 80  
 
 81  
     }
 82  
 
 83  
     public RunResult( int completedCount, int errors, int failures, int skipped )
 84  
     {
 85  9
         this( completedCount, errors, failures, skipped, null, false );
 86  9
     }
 87  
 
 88  
     public RunResult( int completedCount, int errors, int failures, int skipped, String failure, boolean timeout )
 89  23
     {
 90  23
         this.completedCount = completedCount;
 91  23
         this.errors = errors;
 92  23
         this.failures = failures;
 93  23
         this.skipped = skipped;
 94  23
         this.failure = failure;
 95  23
         this.timeout = timeout;
 96  23
     }
 97  
 
 98  
     private static String getStackTrace( Exception e )
 99  
     {
 100  0
         if ( e == null )
 101  
         {
 102  0
             return null;
 103  
         }
 104  0
         ByteArrayOutputStream out = new ByteArrayOutputStream();
 105  0
         PrintWriter pw = new PrintWriter( out );
 106  0
         e.printStackTrace( pw );
 107  0
         return new String( out.toByteArray() );
 108  
     }
 109  
 
 110  
     public int getCompletedCount()
 111  
     {
 112  13
         return completedCount;
 113  
     }
 114  
 
 115  
     public int getErrors()
 116  
     {
 117  14
         return errors;
 118  
     }
 119  
 
 120  
     public int getFailures()
 121  
     {
 122  19
         return failures;
 123  
     }
 124  
 
 125  
     public int getSkipped()
 126  
     {
 127  13
         return skipped;
 128  
     }
 129  
 
 130  
     public Integer getFailsafeCode()  // Only used for compatibility reasons.
 131  
     {
 132  5
         if ( completedCount == 0 )
 133  
         {
 134  1
             return NO_TESTS;
 135  
         }
 136  4
         if ( !isErrorFree() )
 137  
         {
 138  4
             return FAILURE;
 139  
         }
 140  0
         return null;
 141  
     }
 142  
 
 143  
     /* Indicates if the tests are error free */
 144  
     public boolean isErrorFree()
 145  
     {
 146  6
         return getFailures() == 0 && getErrors() == 0;
 147  
     }
 148  
 
 149  
     /* Indicates test timeout or technical failure */
 150  
     public boolean isFailureOrTimeout()
 151  
     {
 152  0
         return this.timeout || isFailure();
 153  
     }
 154  
 
 155  
     public boolean isFailure()
 156  
     {
 157  0
         return failure != null;
 158  
     }
 159  
 
 160  
     public String getFailure()
 161  
     {
 162  12
         return failure;
 163  
     }
 164  
 
 165  
     public boolean isTimeout()
 166  
     {
 167  11
         return timeout;
 168  
     }
 169  
 
 170  
 
 171  
     public RunResult aggregate( RunResult other )
 172  
     {
 173  6
         String failureMessage = getFailure() != null ? getFailure() : other.getFailure();
 174  6
         boolean timeout = isTimeout() || other.isTimeout();
 175  6
         int completed = getCompletedCount() + other.getCompletedCount();
 176  6
         int fail = getFailures() + other.getFailures();
 177  6
         int ign = getSkipped() + other.getSkipped();
 178  6
         int err = getErrors() + other.getErrors();
 179  6
         return new RunResult( completed, err, fail, ign, failureMessage, timeout );
 180  
     }
 181  
 
 182  
     public static RunResult noTestsRun()
 183  
     {
 184  1
         return new RunResult( 0, 0, 0, 0 );
 185  
     }
 186  
 
 187  
     private Xpp3Dom create( String node, String value )
 188  
     {
 189  25
         Xpp3Dom dom = new Xpp3Dom( node );
 190  25
         dom.setValue( value );
 191  25
         return dom;
 192  
     }
 193  
 
 194  
     private Xpp3Dom create( String node, int value )
 195  
     {
 196  20
         return create( node, Integer.toString( value ) );
 197  
     }
 198  
 
 199  
     Xpp3Dom asXpp3Dom()
 200  
     {
 201  5
         Xpp3Dom dom = new Xpp3Dom( "failsafe-summary" );
 202  5
         Integer failsafeCode = getFailsafeCode();
 203  5
         if ( failsafeCode != null )
 204  
         {
 205  5
             dom.setAttribute( "result", Integer.toString( failsafeCode ) );
 206  
         }
 207  5
         dom.setAttribute( "timeout", Boolean.toString( this.timeout ) );
 208  5
         dom.addChild( create( "completed", this.completedCount ) );
 209  5
         dom.addChild( create( "errors", this.errors ) );
 210  5
         dom.addChild( create( "failures", this.failures ) );
 211  5
         dom.addChild( create( "skipped", this.skipped ) );
 212  5
         dom.addChild( create( "failureMessage", this.failure ) );
 213  5
         return dom;
 214  
     }
 215  
 
 216  
     public static RunResult fromInputStream( InputStream inputStream, String encoding )
 217  
         throws FileNotFoundException
 218  
     {
 219  5
         Xpp3Dom dom = Xpp3DomBuilder.build( inputStream, encoding );
 220  5
         boolean timeout = Boolean.parseBoolean( dom.getAttribute( "timeout" ) );
 221  5
         int completed = Integer.parseInt( dom.getChild( "completed" ).getValue() );
 222  5
         int errors = Integer.parseInt( dom.getChild( "errors" ).getValue() );
 223  5
         int failures = Integer.parseInt( dom.getChild( "failures" ).getValue() );
 224  5
         int skipped = Integer.parseInt( dom.getChild( "skipped" ).getValue() );
 225  5
         String failureMessage1 = dom.getChild( "failureMessage" ).getValue();
 226  5
         String failureMessage = StringUtils.isEmpty( failureMessage1 ) ? null : failureMessage1;
 227  5
         return new RunResult( completed, errors, failures, skipped, failureMessage, timeout );
 228  
     }
 229  
 
 230  
     public void writeSummary( File summaryFile, boolean inProgress, String encoding )
 231  
         throws IOException
 232  
     {
 233  2
         if ( !summaryFile.getParentFile().isDirectory() )
 234  
         {
 235  
             //noinspection ResultOfMethodCallIgnored
 236  0
             summaryFile.getParentFile().mkdirs();
 237  
         }
 238  
 
 239  2
         FileInputStream fin = null;
 240  2
         FileWriter writer = null;
 241  
         try
 242  
         {
 243  2
             RunResult mergedSummary = this;
 244  2
             if ( summaryFile.exists() && inProgress )
 245  
             {
 246  1
                 fin = new FileInputStream( summaryFile );
 247  
 
 248  1
                 RunResult runResult = RunResult.fromInputStream( new BufferedInputStream( fin ), encoding );
 249  1
                 mergedSummary = mergedSummary.aggregate( runResult );
 250  
             }
 251  
 
 252  2
             writer = new FileWriter( summaryFile );
 253  2
             writer.write( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
 254  2
             PrettyPrintXMLWriter prettyPrintXMLWriter = new PrettyPrintXMLWriter( writer );
 255  2
             Xpp3DomWriter.write( prettyPrintXMLWriter, mergedSummary.asXpp3Dom() );
 256  
         }
 257  
         finally
 258  
         {
 259  2
             IOUtil.close( fin );
 260  2
             IOUtil.close( writer );
 261  2
         }
 262  2
     }
 263  
 
 264  
     @SuppressWarnings( "RedundantIfStatement" )
 265  
     public boolean equals( Object o )
 266  
     {
 267  4
         if ( this == o )
 268  
         {
 269  0
             return true;
 270  
         }
 271  4
         if ( o == null || getClass() != o.getClass() )
 272  
         {
 273  0
             return false;
 274  
         }
 275  
 
 276  4
         RunResult runResult = (RunResult) o;
 277  
 
 278  4
         if ( completedCount != runResult.completedCount )
 279  
         {
 280  0
             return false;
 281  
         }
 282  4
         if ( errors != runResult.errors )
 283  
         {
 284  0
             return false;
 285  
         }
 286  4
         if ( failures != runResult.failures )
 287  
         {
 288  0
             return false;
 289  
         }
 290  4
         if ( skipped != runResult.skipped )
 291  
         {
 292  0
             return false;
 293  
         }
 294  4
         if ( timeout != runResult.timeout )
 295  
         {
 296  0
             return false;
 297  
         }
 298  4
         if ( failure != null ? !failure.equals( runResult.failure ) : runResult.failure != null )
 299  
         {
 300  0
             return false;
 301  
         }
 302  
 
 303  4
         return true;
 304  
     }
 305  
 
 306  
     public int hashCode()
 307  
     {
 308  0
         int result = completedCount;
 309  0
         result = 31 * result + errors;
 310  0
         result = 31 * result + failures;
 311  0
         result = 31 * result + skipped;
 312  0
         result = 31 * result + ( failure != null ? failure.hashCode() : 0 );
 313  0
         result = 31 * result + ( timeout ? 1 : 0 );
 314  0
         return result;
 315  
     }
 316  
 }