View Javadoc
1   package org.apache.maven.surefire.junitcore.pc;
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.surefire.junitcore.JUnitCoreParameters;
23  import org.apache.maven.surefire.testset.TestSetFailedException;
24  import org.junit.AfterClass;
25  import org.junit.BeforeClass;
26  import org.junit.Rule;
27  import org.junit.experimental.theories.DataPoint;
28  import org.junit.experimental.theories.Theories;
29  import org.junit.experimental.theories.Theory;
30  import org.junit.rules.ExpectedException;
31  import org.junit.runner.RunWith;
32  
33  import java.util.HashMap;
34  import java.util.Map;
35  
36  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.*;
37  import static org.apache.maven.surefire.junitcore.pc.ParallelComputerUtil.*;
38  import static org.hamcrest.core.Is.is;
39  import static org.junit.Assert.*;
40  
41  /**
42   * Testing an algorithm in {@link ParallelComputerUtil} which configures
43   * optimized thread resources in ParallelComputer by given {@link org.apache.maven.surefire.junitcore.JUnitCoreParameters}.
44   *
45   * @author Tibor Digana (tibor17)
46   * @see ParallelComputerUtil
47   * @since 2.17
48   */
49  @RunWith( Theories.class )
50  public final class OptimizedParallelComputerTest
51  {
52      @DataPoint
53      public static final int CPU_1 = 1;
54  
55      @DataPoint
56      public static final int CPU_4 = 4;
57  
58      @Rule
59      public final ExpectedException exception = ExpectedException.none();
60  
61      @BeforeClass
62      public static void beforeClass()
63      {
64          overrideAvailableProcessors( 1 );
65      }
66  
67      @AfterClass
68      public static void afterClass()
69      {
70          setDefaultAvailableProcessors();
71      }
72  
73      @Theory
74      public void threadCountSuites( int cpu )
75          throws TestSetFailedException
76      {
77          overrideAvailableProcessors( cpu );
78          Map<String, String> properties = new HashMap<>();
79          properties.put(PARALLEL_KEY, "suites");
80          properties.put(THREADCOUNT_KEY, "3");
81          JUnitCoreParameters params = new JUnitCoreParameters( properties );
82          RunnerCounter counter = new RunnerCounter( 5, 10, 20 );
83          Concurrency concurrency = resolveConcurrency( params, counter );
84          assertTrue( params.isParallelSuites() );
85          assertFalse( params.isParallelClasses() );
86          assertFalse( params.isParallelMethods() );
87          assertThat( concurrency.capacity, is( 0 ) );
88          assertThat( concurrency.suites, is( (int) Math.min( 3 * cpu, counter.suites ) ) );
89          assertThat( concurrency.classes, is( 0 ) );
90          assertThat( concurrency.methods, is( 0 ) );
91      }
92  
93      @Theory
94      public void threadCountClasses( int cpu )
95          throws TestSetFailedException
96      {
97          overrideAvailableProcessors( cpu );
98          Map<String, String> properties = new HashMap<>();
99          properties.put(PARALLEL_KEY, "classes");
100         properties.put(THREADCOUNT_KEY, "3");
101         JUnitCoreParameters params = new JUnitCoreParameters( properties );
102         RunnerCounter counter = new RunnerCounter( 1, 5, 10 );
103         Concurrency concurrency = resolveConcurrency( params, counter );
104         assertFalse( params.isParallelSuites() );
105         assertTrue( params.isParallelClasses() );
106         assertFalse( params.isParallelMethods() );
107         assertThat( concurrency.capacity, is( 0 ) );
108         assertThat( concurrency.suites, is( 0 ) );
109         assertThat( concurrency.classes, is( (int) Math.min( 3 * cpu, counter.classes ) ) );
110         assertThat( concurrency.methods, is( 0 ) );
111     }
112 
113     @Theory
114     public void threadCountMethods( int cpu )
115         throws TestSetFailedException
116     {
117         overrideAvailableProcessors( cpu );
118         Map<String, String> properties = new HashMap<>();
119         properties.put(PARALLEL_KEY, "methods");
120         properties.put(THREADCOUNT_KEY, "3");
121         JUnitCoreParameters params = new JUnitCoreParameters( properties );
122         RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
123         Concurrency concurrency = resolveConcurrency( params, counter );
124         assertFalse( params.isParallelSuites() );
125         assertFalse( params.isParallelClasses() );
126         assertTrue( params.isParallelMethods() );
127         assertThat( concurrency.capacity, is( 0 ) );
128         assertThat( concurrency.suites, is( 0 ) );
129         assertThat( concurrency.classes, is( 0 ) );
130         assertThat( concurrency.methods, is( (int) Math.min( 3 * cpu, counter.methods ) ) );
131     }
132 
133     @Theory
134     public void threadCountBoth( int cpu )
135         throws TestSetFailedException
136     {
137         overrideAvailableProcessors( cpu );
138         Map<String, String> properties = new HashMap<>();
139         properties.put(PARALLEL_KEY, "both");
140         properties.put(THREADCOUNT_KEY, "3");
141         JUnitCoreParameters params = new JUnitCoreParameters( properties );
142         RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
143         Concurrency concurrency = resolveConcurrency( params, counter );
144         assertFalse( params.isParallelSuites() );
145         assertTrue( params.isParallelClasses() );
146         assertTrue( params.isParallelMethods() );
147         assertThat( concurrency.capacity, is( 3 * cpu ) );
148         assertThat( concurrency.suites, is( 0 ) );
149         assertThat( concurrency.classes, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
150         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
151     }
152 
153     @Theory
154     public void threadCountClassesAndMethods( int cpu )
155         throws TestSetFailedException
156     {
157         overrideAvailableProcessors( cpu );
158         Map<String, String> properties = new HashMap<>();
159         properties.put(PARALLEL_KEY, "classesAndMethods");
160         properties.put(THREADCOUNT_KEY, "3");
161         JUnitCoreParameters params = new JUnitCoreParameters( properties );
162         RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
163         Concurrency concurrency = resolveConcurrency( params, counter );
164         assertFalse( params.isParallelSuites() );
165         assertTrue( params.isParallelClasses() );
166         assertTrue( params.isParallelMethods() );
167         assertThat( concurrency.capacity, is( 3 * cpu ) );
168         assertThat( concurrency.suites, is( 0 ) );
169         assertThat( concurrency.classes, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
170         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
171     }
172 
173     @Theory
174     public void threadCountSuitesAndMethods( int cpu )
175         throws TestSetFailedException
176     {
177         overrideAvailableProcessors( cpu );
178         Map<String, String> properties = new HashMap<>();
179         properties.put(PARALLEL_KEY, "suitesAndMethods");
180         properties.put(THREADCOUNT_KEY, "3");
181         JUnitCoreParameters params = new JUnitCoreParameters( properties );
182         RunnerCounter counter = new RunnerCounter( 2, 3, 5 );
183         Concurrency concurrency = resolveConcurrency( params, counter );
184         assertTrue( params.isParallelSuites() );
185         assertFalse( params.isParallelClasses() );
186         assertTrue( params.isParallelMethods() );
187         assertThat( concurrency.capacity, is( 3 * cpu ) );
188         assertThat( concurrency.suites, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
189         assertThat( concurrency.classes, is( 0 ) );
190         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
191     }
192 
193     @Theory
194     public void threadCountSuitesAndClasses( int cpu )
195         throws TestSetFailedException
196     {
197         overrideAvailableProcessors( cpu );
198         Map<String, String> properties = new HashMap<>();
199         properties.put(PARALLEL_KEY, "suitesAndClasses");
200         properties.put(THREADCOUNT_KEY, "3");
201         JUnitCoreParameters params = new JUnitCoreParameters( properties );
202         RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
203         Concurrency concurrency = resolveConcurrency( params, counter );
204         assertTrue( params.isParallelSuites() );
205         assertTrue( params.isParallelClasses() );
206         assertFalse( params.isParallelMethods() );
207         assertThat( concurrency.capacity, is( 3 * cpu ) );
208         assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 7 ) * cpu, 2 ) ) );
209         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
210         assertThat( concurrency.methods, is( 0 ) );
211     }
212 
213     @Theory
214     public void threadCountAll( int cpu )
215         throws TestSetFailedException
216     {
217         overrideAvailableProcessors( cpu );
218         Map<String, String> properties = new HashMap<>();
219         properties.put(PARALLEL_KEY, "all");
220         properties.put(THREADCOUNT_KEY, "3");
221         JUnitCoreParameters params = new JUnitCoreParameters( properties );
222         RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
223         Concurrency concurrency = resolveConcurrency( params, counter );
224         assertTrue( params.isParallelSuites() );
225         assertTrue( params.isParallelClasses() );
226         assertTrue( params.isParallelMethods() );
227         assertThat( concurrency.capacity, is( 3 * cpu ) );
228         assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 11 ) * cpu, 2 ) ) );
229         assertThat( concurrency.classes, is( (int) Math.min( ( 5d * 3 / 11 ) * cpu, 5 ) ) );
230         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
231     }
232 
233     @Theory
234     public void reusableThreadCountSuitesAndClasses( int cpu )
235         throws TestSetFailedException
236     {
237         // 4 * cpu to 5 * cpu threads to run test classes
238         overrideAvailableProcessors( cpu );
239         Map<String, String> properties = new HashMap<>();
240         properties.put(PARALLEL_KEY, "suitesAndClasses");
241         properties.put(THREADCOUNT_KEY, "6");
242         properties.put(THREADCOUNTSUITES_KEY, "2");
243         JUnitCoreParameters params = new JUnitCoreParameters( properties );
244         RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
245         Concurrency concurrency = resolveConcurrency( params, counter );
246         assertTrue( params.isParallelSuites() );
247         assertTrue( params.isParallelClasses() );
248         assertFalse( params.isParallelMethods() );
249         assertThat( concurrency.capacity, is( 6 * cpu ) );
250         assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
251         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
252         assertThat( concurrency.methods, is( 0 ) );
253     }
254 
255     @Theory
256     public void reusableThreadCountSuitesAndMethods( int cpu )
257         throws TestSetFailedException
258     {
259         // 4 * cpu to 5 * cpu threads to run test methods
260         overrideAvailableProcessors( cpu );
261         Map<String, String> properties = new HashMap<>();
262         properties.put(PARALLEL_KEY, "suitesAndMethods");
263         properties.put(THREADCOUNT_KEY, "6");
264         properties.put(THREADCOUNTSUITES_KEY, "2");
265         JUnitCoreParameters params = new JUnitCoreParameters( properties );
266         RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
267         Concurrency concurrency = resolveConcurrency( params, counter );
268         assertTrue( params.isParallelSuites() );
269         assertFalse( params.isParallelClasses() );
270         assertTrue( params.isParallelMethods() );
271         assertThat( concurrency.capacity, is( 6 * cpu ) );
272         assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
273         assertThat( concurrency.classes, is( 0 ) );
274         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
275     }
276 
277     @Theory
278     public void reusableThreadCountClassesAndMethods( int cpu )
279         throws TestSetFailedException
280     {
281         // 4 * cpu to 5 * cpu threads to run test methods
282         overrideAvailableProcessors( cpu );
283         Map<String, String> properties = new HashMap<>();
284         properties.put(PARALLEL_KEY, "classesAndMethods");
285         properties.put(THREADCOUNT_KEY, "6");
286         properties.put(THREADCOUNTCLASSES_KEY, "2");
287         JUnitCoreParameters params = new JUnitCoreParameters( properties );
288         RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
289         Concurrency concurrency = resolveConcurrency( params, counter );
290         assertFalse( params.isParallelSuites() );
291         assertTrue( params.isParallelClasses() );
292         assertTrue( params.isParallelMethods() );
293         assertThat( concurrency.capacity, is( 6 * cpu ) );
294         assertThat( concurrency.suites, is( 0 ) );
295         assertThat( concurrency.classes, is( Math.min( 2 * cpu, 5 ) ) );
296         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
297     }
298 
299     @Theory
300     public void reusableThreadCountAll( int cpu )
301         throws TestSetFailedException
302     {
303         // 8 * cpu to 13 * cpu threads to run test methods
304         overrideAvailableProcessors( cpu );
305         Map<String, String> properties = new HashMap<>();
306         properties.put( PARALLEL_KEY, "all" );
307         properties.put( THREADCOUNT_KEY, "14" );
308         properties.put( THREADCOUNTSUITES_KEY, "2" );
309         properties.put( THREADCOUNTCLASSES_KEY, "4" );
310         JUnitCoreParameters params = new JUnitCoreParameters( properties );
311         RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
312         Concurrency concurrency = resolveConcurrency( params, counter );
313         assertTrue( params.isParallelSuites() );
314         assertTrue( params.isParallelClasses() );
315         assertTrue( params.isParallelMethods() );
316         assertThat( concurrency.capacity, is( 14 * cpu ) );
317         assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
318         assertThat( concurrency.classes, is( Math.min( 4 * cpu, 5 ) ) );
319         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
320     }
321 }