1 package org.apache.maven.surefire.api.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.api.runorder.RunEntryStatisticsMap;
23 import org.apache.maven.surefire.api.testset.RunOrderParameters;
24
25 import java.util.ArrayList;
26 import java.util.Calendar;
27 import java.util.Collections;
28 import java.util.Comparator;
29 import java.util.LinkedHashSet;
30 import java.util.List;
31 import java.util.Random;
32
33
34
35
36
37
38 public class DefaultRunOrderCalculator
39 implements RunOrderCalculator
40 {
41 private final Comparator<Class> sortOrder;
42
43 private final RunOrder[] runOrder;
44
45 private final RunOrderParameters runOrderParameters;
46
47 private final int threadCount;
48
49 private final Random random;
50
51 public DefaultRunOrderCalculator( RunOrderParameters runOrderParameters, int threadCount )
52 {
53 this.runOrderParameters = runOrderParameters;
54 this.threadCount = threadCount;
55 this.runOrder = runOrderParameters.getRunOrder();
56 this.sortOrder = this.runOrder.length > 0 ? getSortOrderComparator( this.runOrder[0] ) : null;
57 Long runOrderRandomSeed = runOrderParameters.getRunOrderRandomSeed();
58 if ( runOrderRandomSeed == null )
59 {
60 runOrderRandomSeed = System.nanoTime();
61 runOrderParameters.setRunOrderRandomSeed( runOrderRandomSeed );
62 }
63 this.random = new Random( runOrderRandomSeed );
64 }
65
66 @Override
67 @SuppressWarnings( "checkstyle:magicnumber" )
68 public TestsToRun orderTestClasses( TestsToRun scannedClasses )
69 {
70 List<Class<?>> result = new ArrayList<>( 512 );
71
72 for ( Class<?> scannedClass : scannedClasses )
73 {
74 result.add( scannedClass );
75 }
76
77 orderTestClasses( result, runOrder.length != 0 ? runOrder[0] : null );
78 return new TestsToRun( new LinkedHashSet<>( result ) );
79 }
80
81 private void orderTestClasses( List<Class<?>> testClasses, RunOrder runOrder )
82 {
83 if ( RunOrder.RANDOM.equals( runOrder ) )
84 {
85 Collections.shuffle( testClasses, random );
86 }
87 else if ( RunOrder.FAILEDFIRST.equals( runOrder ) )
88 {
89 RunEntryStatisticsMap stat = RunEntryStatisticsMap.fromFile( runOrderParameters.getRunStatisticsFile() );
90 List<Class<?>> prioritized = stat.getPrioritizedTestsByFailureFirst( testClasses );
91 testClasses.clear();
92 testClasses.addAll( prioritized );
93
94 }
95 else if ( RunOrder.BALANCED.equals( runOrder ) )
96 {
97 RunEntryStatisticsMap stat = RunEntryStatisticsMap.fromFile( runOrderParameters.getRunStatisticsFile() );
98 List<Class<?>> prioritized = stat.getPrioritizedTestsClassRunTime( testClasses, threadCount );
99 testClasses.clear();
100 testClasses.addAll( prioritized );
101
102 }
103 else if ( sortOrder != null )
104 {
105 Collections.sort( testClasses, sortOrder );
106 }
107 }
108
109 private Comparator<Class> getSortOrderComparator( RunOrder runOrder )
110 {
111 if ( RunOrder.ALPHABETICAL.equals( runOrder ) )
112 {
113 return getAlphabeticalComparator();
114 }
115 else if ( RunOrder.REVERSE_ALPHABETICAL.equals( runOrder ) )
116 {
117 return getReverseAlphabeticalComparator();
118 }
119 else if ( RunOrder.HOURLY.equals( runOrder ) )
120 {
121 final int hour = Calendar.getInstance().get( Calendar.HOUR_OF_DAY );
122 return ( ( hour % 2 ) == 0 ) ? getAlphabeticalComparator() : getReverseAlphabeticalComparator();
123 }
124 else
125 {
126 return null;
127 }
128 }
129
130 private Comparator<Class> getReverseAlphabeticalComparator()
131 {
132 return new Comparator<Class>()
133 {
134 @Override
135 public int compare( Class o1, Class o2 )
136 {
137 return o2.getName().compareTo( o1.getName() );
138 }
139 };
140 }
141
142 private Comparator<Class> getAlphabeticalComparator()
143 {
144 return new Comparator<Class>()
145 {
146 @Override
147 public int compare( Class o1, Class o2 )
148 {
149 return o1.getName().compareTo( o2.getName() );
150 }
151 };
152 }
153 }