Coverage Report - org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMap
 
Classes in this File Line Coverage Branch Coverage Complexity
RunEntryStatisticsMap
0%
0/90
0%
0/30
2,211
RunEntryStatisticsMap$LeastFailureComparator
0%
0/4
N/A
2,211
RunEntryStatisticsMap$PrioritizedTestComparator
0%
0/4
N/A
2,211
RunEntryStatisticsMap$RunCountComparator
0%
0/7
0%
0/2
2,211
RunEntryStatisticsMap$TestRuntimeComparator
0%
0/4
N/A
2,211
 
 1  
 package org.apache.maven.plugin.surefire.runorder;
 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  
 
 23  
 import java.io.BufferedReader;
 24  
 import java.io.File;
 25  
 import java.io.FileNotFoundException;
 26  
 import java.io.FileOutputStream;
 27  
 import java.io.FileReader;
 28  
 import java.io.IOException;
 29  
 import java.io.PrintWriter;
 30  
 import java.io.Reader;
 31  
 import java.util.ArrayList;
 32  
 import java.util.Collections;
 33  
 import java.util.Comparator;
 34  
 import java.util.HashMap;
 35  
 import java.util.Iterator;
 36  
 import java.util.List;
 37  
 import java.util.Map;
 38  
 import java.util.regex.Matcher;
 39  
 import java.util.regex.Pattern;
 40  
 import org.apache.maven.surefire.report.ReportEntry;
 41  
 
 42  
 /**
 43  
  * @author Kristian Rosenvold
 44  
  */
 45  
 public class RunEntryStatisticsMap
 46  
 {
 47  
     private final Map runEntryStatistics;
 48  
 
 49  
     public RunEntryStatisticsMap( Map runEntryStatistics )
 50  0
     {
 51  0
         this.runEntryStatistics = Collections.synchronizedMap( runEntryStatistics );
 52  0
     }
 53  
 
 54  
     public RunEntryStatisticsMap()
 55  
     {
 56  0
         this( new HashMap() );
 57  0
     }
 58  
 
 59  
     public static RunEntryStatisticsMap fromFile( File file )
 60  
     {
 61  0
         if ( file.exists() )
 62  
         {
 63  
             try
 64  
             {
 65  0
                 FileReader fileReader = new FileReader( file );
 66  0
                 return fromReader( fileReader );
 67  
             }
 68  0
             catch ( FileNotFoundException e )
 69  
             {
 70  0
                 throw new RuntimeException( e );
 71  
             }
 72  0
             catch ( IOException e1 )
 73  
             {
 74  0
                 throw new RuntimeException( e1 );
 75  
             }
 76  
 
 77  
         }
 78  0
         return new RunEntryStatisticsMap();
 79  
     }
 80  
 
 81  
     static RunEntryStatisticsMap fromReader( Reader fileReader )
 82  
         throws IOException
 83  
     {
 84  0
         Map result = new HashMap();
 85  0
         BufferedReader bufferedReader = new BufferedReader( fileReader );
 86  0
         String line = bufferedReader.readLine();
 87  0
         while ( line != null )
 88  
         {
 89  0
             if ( !line.startsWith( "#" ) )
 90  
             {
 91  0
                 final RunEntryStatistics stats = RunEntryStatistics.fromString( line );
 92  0
                 result.put( stats.getTestName(), stats );
 93  
             }
 94  0
             line = bufferedReader.readLine();
 95  
         }
 96  0
         return new RunEntryStatisticsMap( result );
 97  
     }
 98  
 
 99  
     public void serialize( File file )
 100  
         throws FileNotFoundException
 101  
     {
 102  0
         FileOutputStream fos = new FileOutputStream( file );
 103  0
         PrintWriter printWriter = new PrintWriter( fos );
 104  0
         List items = new ArrayList( runEntryStatistics.values() );
 105  0
         Collections.sort( items, new RunCountComparator() );
 106  
         RunEntryStatistics item;
 107  0
         for ( Iterator iter = items.iterator(); iter.hasNext(); )
 108  
         {
 109  0
             item = (RunEntryStatistics) iter.next();
 110  0
             printWriter.println( item.getAsString() );
 111  
         }
 112  0
         printWriter.close();
 113  0
     }
 114  
 
 115  
 
 116  
     public RunEntryStatistics findOrCreate( ReportEntry reportEntry )
 117  
     {
 118  0
         final RunEntryStatistics item = (RunEntryStatistics) runEntryStatistics.get( reportEntry.getName() );
 119  0
         return item != null ? item : RunEntryStatistics.fromReportEntry( reportEntry );
 120  
     }
 121  
 
 122  
     public RunEntryStatistics createNextGeneration( ReportEntry reportEntry )
 123  
     {
 124  0
         final RunEntryStatistics newItem = findOrCreate( reportEntry );
 125  0
         final Integer elapsed = reportEntry.getElapsed();
 126  0
         return newItem.nextGeneration( elapsed != null ? elapsed.intValue() : 0 );
 127  
     }
 128  
 
 129  
     public RunEntryStatistics createNextGenerationFailure( ReportEntry reportEntry )
 130  
     {
 131  0
         final RunEntryStatistics newItem = findOrCreate( reportEntry );
 132  0
         final Integer elapsed = reportEntry.getElapsed();
 133  0
         return newItem.nextGenerationFailure( elapsed != null ? elapsed.intValue() : 0 );
 134  
     }
 135  
 
 136  
     public void add( RunEntryStatistics item )
 137  
     {
 138  0
         runEntryStatistics.put( item.getTestName(), item );
 139  0
     }
 140  
 
 141  0
     class RunCountComparator
 142  
         implements Comparator
 143  
     {
 144  
         public int compare( Object o, Object o1 )
 145  
         {
 146  0
             RunEntryStatistics re = (RunEntryStatistics) o;
 147  0
             RunEntryStatistics re1 = (RunEntryStatistics) o1;
 148  0
             int runtime = re.getSuccessfulBuilds() - re1.getSuccessfulBuilds();
 149  0
             if ( runtime == 0 )
 150  
             {
 151  0
                 return re.getRunTime() - re1.getRunTime();
 152  
             }
 153  0
             return runtime;
 154  
         }
 155  
     }
 156  
 
 157  
     public List getPrioritizedTestsClassRunTime( List testsToRun, int threadCount )
 158  
     {
 159  0
         final List prioritizedTests = getPrioritizedTests( testsToRun, new TestRuntimeComparator() );
 160  0
         ThreadedExecutionScheduler threadedExecutionScheduler = new ThreadedExecutionScheduler( threadCount );
 161  0
         for ( Iterator prioritizedTest = prioritizedTests.iterator(); prioritizedTest.hasNext(); )
 162  
         {
 163  0
             threadedExecutionScheduler.addTest( (PrioritizedTest) prioritizedTest.next() );
 164  
         }
 165  
 
 166  0
         return threadedExecutionScheduler.getResult();
 167  
 
 168  
     }
 169  
 
 170  
     public List getPrioritizedTestsByFailureFirst( List testsToRun )
 171  
     {
 172  0
         final List prioritizedTests = getPrioritizedTests( testsToRun, new LeastFailureComparator() );
 173  0
         return transformToClasses( prioritizedTests );
 174  
     }
 175  
 
 176  
 
 177  
     private List getPrioritizedTests( List testsToRun, Comparator priorityComparator )
 178  
     {
 179  0
         Map classPriorities = getPriorities( priorityComparator );
 180  
 
 181  0
         List tests = new ArrayList();
 182  0
         for ( Iterator iter = testsToRun.iterator(); iter.hasNext(); )
 183  
         {
 184  0
             Class clazz = (Class) iter.next();
 185  0
             Priority pri = (Priority) classPriorities.get( clazz.getName() );
 186  0
             if ( pri == null )
 187  
             {
 188  0
                 pri = Priority.newTestClassPriority( clazz.getName() );
 189  
             }
 190  0
             PrioritizedTest prioritizedTest = new PrioritizedTest( clazz, pri );
 191  0
             tests.add( prioritizedTest );
 192  0
         }
 193  0
         Collections.sort( tests, new PrioritizedTestComparator() );
 194  0
         return tests;
 195  
 
 196  
     }
 197  
 
 198  
     private List transformToClasses( List tests )
 199  
     {
 200  0
         List result = new ArrayList();
 201  0
         for ( int i = 0; i < tests.size(); i++ )
 202  
         {
 203  0
             result.add( ( (PrioritizedTest) tests.get( i ) ).getClazz() );
 204  
         }
 205  0
         return result;
 206  
     }
 207  
 
 208  
     public Map getPriorities( Comparator priorityComparator )
 209  
     {
 210  0
         Map priorities = new HashMap();
 211  0
         for ( Iterator iter = runEntryStatistics.keySet().iterator(); iter.hasNext(); )
 212  
         {
 213  0
             String testNames = (String) iter.next();
 214  0
             String clazzName = extractClassName( testNames );
 215  0
             Priority priority = (Priority) priorities.get( clazzName );
 216  0
             if ( priority == null )
 217  
             {
 218  0
                 priority = new Priority( clazzName );
 219  0
                 priorities.put( clazzName, priority );
 220  
             }
 221  
 
 222  0
             RunEntryStatistics itemStat = (RunEntryStatistics) runEntryStatistics.get( testNames );
 223  0
             priority.addItem( itemStat );
 224  0
         }
 225  
 
 226  0
         List items = new ArrayList( priorities.values() );
 227  0
         Collections.sort( items, priorityComparator );
 228  0
         Map result = new HashMap();
 229  0
         int i = 0;
 230  0
         for ( Iterator iter = items.iterator(); iter.hasNext(); )
 231  
         {
 232  0
             Priority pri = (Priority) iter.next();
 233  0
             pri.setPriority( i++ );
 234  0
             result.put( pri.getClassName(), pri );
 235  0
         }
 236  0
         return result;
 237  
     }
 238  
 
 239  0
     class PrioritizedTestComparator
 240  
         implements Comparator
 241  
     {
 242  
         public int compare( Object o, Object o1 )
 243  
         {
 244  0
             PrioritizedTest re = (PrioritizedTest) o;
 245  0
             PrioritizedTest re1 = (PrioritizedTest) o1;
 246  0
             return re.getPriority() - re1.getPriority();
 247  
         }
 248  
     }
 249  
 
 250  0
     class TestRuntimeComparator
 251  
         implements Comparator
 252  
     {
 253  
         public int compare( Object o, Object o1 )
 254  
         {
 255  0
             Priority re = (Priority) o;
 256  0
             Priority re1 = (Priority) o1;
 257  0
             return re1.getTotalRuntime() - re.getTotalRuntime();
 258  
         }
 259  
     }
 260  
 
 261  0
     class LeastFailureComparator
 262  
         implements Comparator
 263  
     {
 264  
         public int compare( Object o, Object o1 )
 265  
         {
 266  0
             Priority re = (Priority) o;
 267  0
             Priority re1 = (Priority) o1;
 268  0
             return re.getMinSuccessRate() - re1.getMinSuccessRate();
 269  
         }
 270  
     }
 271  
 
 272  
 
 273  0
     private static final Pattern PARENS = Pattern.compile( "^" + "[^\\(\\)]+" //non-parens
 274  
                                                                + "\\((" // then an open-paren (start matching a group)
 275  
                                                                + "[^\\\\(\\\\)]+" //non-parens
 276  
                                                                + ")\\)" + "$" ); // then a close-paren (end group match)
 277  
 
 278  
     String extractClassName( String displayName )
 279  
     {
 280  0
         Matcher m = PARENS.matcher( displayName );
 281  0
         if ( !m.find() )
 282  
         {
 283  0
             return displayName;
 284  
         }
 285  0
         return m.group( 1 );
 286  
     }
 287  
 
 288  
 
 289  
 }