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.api.report.ConsoleStream;
24  import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
25  import org.apache.maven.surefire.api.testset.TestSetFailedException;
26  import org.junit.AfterClass;
27  import org.junit.BeforeClass;
28  import org.junit.Before;
29  import org.junit.Rule;
30  import org.junit.Test;
31  import org.junit.experimental.theories.DataPoint;
32  import org.junit.experimental.theories.Theories;
33  import org.junit.experimental.theories.Theory;
34  import org.junit.rules.ExpectedException;
35  import org.junit.runner.JUnitCore;
36  import org.junit.runner.Result;
37  import org.junit.runner.RunWith;
38  
39  import java.util.Collections;
40  import java.util.HashMap;
41  import java.util.Map;
42  import java.util.concurrent.TimeUnit;
43  
44  import static org.apache.maven.surefire.junitcore.pc.ParallelComputerUtil.resolveConcurrency;
45  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.PARALLEL_KEY;
46  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.THREADCOUNT_KEY;
47  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.THREADCOUNTSUITES_KEY;
48  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.THREADCOUNTCLASSES_KEY;
49  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.THREADCOUNTMETHODS_KEY;
50  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.PARALLEL_TIMEOUT_KEY;
51  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.PARALLEL_TIMEOUTFORCED_KEY;
52  import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.USEUNLIMITEDTHREADS_KEY;
53  import static org.hamcrest.core.Is.is;
54  import static org.junit.Assert.assertEquals;
55  import static org.junit.Assert.assertFalse;
56  import static org.junit.Assert.assertThat;
57  import static org.junit.Assert.assertTrue;
58  
59  /**
60   * Testing an algorithm in {@link ParallelComputerUtil} which configures allocated thread resources in ParallelComputer
61   * by given {@link org.apache.maven.surefire.junitcore.JUnitCoreParameters}.
62   *
63   * @author Tibor Digana (tibor17)
64   * @see ParallelComputerUtil
65   * @since 2.16
66   */
67  @RunWith( Theories.class )
68  @SuppressWarnings( "checkstyle:magicnumber" )
69  public final class ParallelComputerUtilTest
70  {
71      private static final ConsoleStream LOGGER = new DefaultDirectConsoleReporter( System.out );
72  
73      @DataPoint
74      public static final int CPU_1 = 1;
75  
76      @DataPoint
77      public static final int CPU_4 = 4;
78  
79      @Rule
80      public final ExpectedException exception = ExpectedException.none();
81  
82      @BeforeClass
83      public static void beforeClass()
84      {
85          ParallelComputerUtil.overrideAvailableProcessors( 1 );
86      }
87  
88      @AfterClass
89      public static void afterClass()
90      {
91          ParallelComputerUtil.setDefaultAvailableProcessors();
92      }
93  
94      @Before
95      public void beforeTest() throws InterruptedException
96      {
97          System.gc();
98          Thread.sleep( 50L );
99          assertFalse( Thread.currentThread().isInterrupted() );
100     }
101 
102     private static Map<String, String> parallel( String parallel )
103     {
104         return Collections.singletonMap( PARALLEL_KEY, parallel );
105     }
106 
107     @Test
108     public void unknownParallel() throws TestSetFailedException
109     {
110         Map<String, String> properties = new HashMap<>();
111         exception.expect( TestSetFailedException.class );
112         resolveConcurrency( new JUnitCoreParameters( properties ), null );
113     }
114 
115     @Test
116     public void unknownThreadCountSuites() throws TestSetFailedException
117     {
118         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suites" ) );
119         assertTrue( params.isParallelSuites() );
120         assertFalse( params.isParallelClasses() );
121         assertFalse( params.isParallelMethods() );
122         exception.expect( TestSetFailedException.class );
123         resolveConcurrency( params, null );
124     }
125 
126     @Test
127     public void unknownThreadCountClasses() throws TestSetFailedException
128     {
129         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classes" ) );
130         assertFalse( params.isParallelSuites() );
131         assertTrue( params.isParallelClasses() );
132         assertFalse( params.isParallelMethods() );
133         exception.expect( TestSetFailedException.class );
134         resolveConcurrency( params, null );
135     }
136 
137     @Test
138     public void unknownThreadCountMethods() throws TestSetFailedException
139     {
140         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "methods" ) );
141         assertFalse( params.isParallelSuites() );
142         assertFalse( params.isParallelClasses() );
143         assertTrue( params.isParallelMethods() );
144         exception.expect( TestSetFailedException.class );
145         resolveConcurrency( params, null );
146     }
147 
148     @Test
149     public void unknownThreadCountBoth() throws TestSetFailedException
150     {
151         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "both" ) );
152         assertFalse( params.isParallelSuites() );
153         assertTrue( params.isParallelClasses() );
154         assertTrue( params.isParallelMethods() );
155         exception.expect( TestSetFailedException.class );
156         resolveConcurrency( params, null );
157     }
158 
159     @Test
160     public void unknownThreadCountAll() throws TestSetFailedException
161     {
162         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "all" ) );
163         assertTrue( params.isParallelSuites() );
164         assertTrue( params.isParallelClasses() );
165         assertTrue( params.isParallelMethods() );
166         exception.expect( TestSetFailedException.class );
167         resolveConcurrency( params, null );
168     }
169 
170     @Test
171     public void unknownThreadCountSuitesAndClasses() throws TestSetFailedException
172     {
173         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndClasses" ) );
174         assertTrue( params.isParallelSuites() );
175         assertTrue( params.isParallelClasses() );
176         assertFalse( params.isParallelMethods() );
177         exception.expect( TestSetFailedException.class );
178         resolveConcurrency( params, null );
179     }
180 
181     @Test
182     public void unknownThreadCountSuitesAndMethods() throws TestSetFailedException
183     {
184         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndMethods" ) );
185         assertTrue( params.isParallelSuites() );
186         assertFalse( params.isParallelClasses() );
187         assertTrue( params.isParallelMethods() );
188         exception.expect( TestSetFailedException.class );
189         resolveConcurrency( params, null );
190     }
191 
192     @Test
193     public void unknownThreadCountClassesAndMethods() throws TestSetFailedException
194     {
195         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classesAndMethods" ) );
196         assertFalse( params.isParallelSuites() );
197         assertTrue( params.isParallelClasses() );
198         assertTrue( params.isParallelMethods() );
199         exception.expect( TestSetFailedException.class );
200         resolveConcurrency( params, null );
201     }
202 
203     @Theory
204     public void useUnlimitedThreadsSuites( int cpu ) throws TestSetFailedException
205     {
206         ParallelComputerUtil.overrideAvailableProcessors( cpu );
207         Map<String, String> properties = new HashMap<>();
208         properties.put( PARALLEL_KEY, "suites" );
209         properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
210         JUnitCoreParameters params = new JUnitCoreParameters( properties );
211         Concurrency concurrency = resolveConcurrency( params, null );
212         assertTrue( params.isParallelSuites() );
213         assertFalse( params.isParallelClasses() );
214         assertFalse( params.isParallelMethods() );
215         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
216         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
217         assertThat( concurrency.classes, is( 0 ) );
218         assertThat( concurrency.methods, is( 0 ) );
219 
220         properties.put( THREADCOUNTSUITES_KEY, "5" );
221         params = new JUnitCoreParameters( properties );
222         concurrency = resolveConcurrency( params, null );
223         assertTrue( params.isParallelSuites() );
224         assertFalse( params.isParallelClasses() );
225         assertFalse( params.isParallelMethods() );
226         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
227         assertThat( concurrency.suites, is( 5 * cpu ) );
228         assertThat( concurrency.classes, is( 0 ) );
229         assertThat( concurrency.methods, is( 0 ) );
230     }
231 
232     @Theory
233     public void useUnlimitedThreadsClasses( int cpu ) throws TestSetFailedException
234     {
235         ParallelComputerUtil.overrideAvailableProcessors( cpu );
236         Map<String, String> properties = new HashMap<>();
237         properties.put( PARALLEL_KEY, "classes" );
238         properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
239         JUnitCoreParameters params = new JUnitCoreParameters( properties );
240         Concurrency concurrency = resolveConcurrency( params, null );
241         assertFalse( params.isParallelSuites() );
242         assertTrue( params.isParallelClasses() );
243         assertFalse( params.isParallelMethods() );
244         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
245         assertThat( concurrency.suites, is( 0 ) );
246         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
247         assertThat( concurrency.methods, is( 0 ) );
248 
249         properties.put( THREADCOUNTCLASSES_KEY, "5" );
250         params = new JUnitCoreParameters( properties );
251         concurrency = resolveConcurrency( params, null );
252         assertFalse( params.isParallelSuites() );
253         assertTrue( params.isParallelClasses() );
254         assertFalse( params.isParallelMethods() );
255         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
256         assertThat( concurrency.suites, is( 0 ) );
257         assertThat( concurrency.classes, is( 5 * cpu ) );
258         assertThat( concurrency.methods, is( 0 ) );
259     }
260 
261     @Theory
262     public void unlimitedThreadsMethods( int cpu ) throws TestSetFailedException
263     {
264         ParallelComputerUtil.overrideAvailableProcessors( cpu );
265         Map<String, String> properties = new HashMap<>();
266         properties.put( PARALLEL_KEY, "methods" );
267         properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
268         JUnitCoreParameters params = new JUnitCoreParameters( properties );
269         Concurrency concurrency = resolveConcurrency( params, null );
270         assertFalse( params.isParallelSuites() );
271         assertFalse( params.isParallelClasses() );
272         assertTrue( params.isParallelMethods() );
273         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
274         assertThat( concurrency.suites, is( 0 ) );
275         assertThat( concurrency.classes, is( 0 ) );
276         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
277 
278         properties.put( THREADCOUNTMETHODS_KEY, "5" );
279         params = new JUnitCoreParameters( properties );
280         concurrency = resolveConcurrency( params, null );
281         assertFalse( params.isParallelSuites() );
282         assertFalse( params.isParallelClasses() );
283         assertTrue( params.isParallelMethods() );
284         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
285         assertThat( concurrency.suites, is( 0 ) );
286         assertThat( concurrency.classes, is( 0 ) );
287         assertThat( concurrency.methods, is( 5 * cpu ) );
288     }
289 
290     @Theory
291     public void unlimitedThreadsSuitesAndClasses( int cpu ) throws TestSetFailedException
292     {
293         ParallelComputerUtil.overrideAvailableProcessors( cpu );
294         Map<String, String> properties = new HashMap<>();
295         properties.put( PARALLEL_KEY, "suitesAndClasses" );
296         properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
297         JUnitCoreParameters params = new JUnitCoreParameters( properties );
298         Concurrency concurrency = resolveConcurrency( params, null );
299         assertTrue( params.isParallelSuites() );
300         assertTrue( params.isParallelClasses() );
301         assertFalse( params.isParallelMethods() );
302         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
303         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
304         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
305         assertThat( concurrency.methods, is( 0 ) );
306 
307         properties.put( THREADCOUNTSUITES_KEY, "5" );
308         properties.put( THREADCOUNTCLASSES_KEY, "15" );
309         params = new JUnitCoreParameters( properties );
310         concurrency = resolveConcurrency( params, null );
311         assertTrue( params.isParallelSuites() );
312         assertTrue( params.isParallelClasses() );
313         assertFalse( params.isParallelMethods() );
314         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
315         assertThat( concurrency.suites, is( 5 * cpu ) );
316         assertThat( concurrency.classes, is( 15 * cpu ) );
317         assertThat( concurrency.methods, is( 0 ) );
318     }
319 
320     @Theory
321     public void unlimitedThreadsSuitesAndMethods( int cpu ) throws TestSetFailedException
322     {
323         ParallelComputerUtil.overrideAvailableProcessors( cpu );
324         Map<String, String> properties = new HashMap<>();
325         properties.put( PARALLEL_KEY, "suitesAndMethods" );
326         properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
327         JUnitCoreParameters params = new JUnitCoreParameters( properties );
328         Concurrency concurrency = resolveConcurrency( params, null );
329         assertTrue( params.isParallelSuites() );
330         assertFalse( params.isParallelClasses() );
331         assertTrue( params.isParallelMethods() );
332         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
333         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
334         assertThat( concurrency.classes, is( 0 ) );
335         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
336 
337         properties.put( THREADCOUNTSUITES_KEY, "5" );
338         properties.put( THREADCOUNTMETHODS_KEY, "15" );
339         params = new JUnitCoreParameters( properties );
340         concurrency = resolveConcurrency( params, null );
341         assertTrue( params.isParallelSuites() );
342         assertFalse( params.isParallelClasses() );
343         assertTrue( params.isParallelMethods() );
344         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
345         assertThat( concurrency.suites, is( 5 * cpu ) );
346         assertThat( concurrency.classes, is( 0 ) );
347         assertThat( concurrency.methods, is( 15 * cpu ) );
348     }
349 
350     @Theory
351     public void unlimitedThreadsClassesAndMethods( int cpu ) throws TestSetFailedException
352     {
353         ParallelComputerUtil.overrideAvailableProcessors( cpu );
354         Map<String, String> properties = new HashMap<>();
355         properties.put( PARALLEL_KEY, "classesAndMethods" );
356         properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
357         JUnitCoreParameters params = new JUnitCoreParameters( properties );
358         Concurrency concurrency = resolveConcurrency( params, null );
359         assertFalse( params.isParallelSuites() );
360         assertTrue( params.isParallelClasses() );
361         assertTrue( params.isParallelMethods() );
362         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
363         assertThat( concurrency.suites, is( 0 ) );
364         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
365         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
366 
367         properties.put( THREADCOUNTCLASSES_KEY, "5" );
368         properties.put( THREADCOUNTMETHODS_KEY, "15" );
369         params = new JUnitCoreParameters( properties );
370         concurrency = resolveConcurrency( params, null );
371         assertFalse( params.isParallelSuites() );
372         assertTrue( params.isParallelClasses() );
373         assertTrue( params.isParallelMethods() );
374         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
375         assertThat( concurrency.suites, is( 0 ) );
376         assertThat( concurrency.classes, is( 5 * cpu ) );
377         assertThat( concurrency.methods, is( 15 * cpu ) );
378     }
379 
380     @Theory
381     public void unlimitedThreadsAll( int cpu ) throws TestSetFailedException
382     {
383         ParallelComputerUtil.overrideAvailableProcessors( cpu );
384         Map<String, String> properties = new HashMap<>();
385         properties.put( PARALLEL_KEY, "all" );
386         properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
387         JUnitCoreParameters params = new JUnitCoreParameters( properties );
388         Concurrency concurrency = resolveConcurrency( params, null );
389         assertTrue( params.isParallelSuites() );
390         assertTrue( params.isParallelClasses() );
391         assertTrue( params.isParallelMethods() );
392         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
393         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
394         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
395         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
396 
397         properties.put( THREADCOUNTSUITES_KEY, "5" );
398         properties.put( THREADCOUNTCLASSES_KEY, "15" );
399         properties.put( THREADCOUNTMETHODS_KEY, "30" );
400         params = new JUnitCoreParameters( properties );
401         concurrency = resolveConcurrency( params, null );
402         assertTrue( params.isParallelSuites() );
403         assertTrue( params.isParallelClasses() );
404         assertTrue( params.isParallelMethods() );
405         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
406         assertThat( concurrency.suites, is( 5 * cpu ) );
407         assertThat( concurrency.classes, is( 15 * cpu ) );
408         assertThat( concurrency.methods, is( 30 * cpu ) );
409     }
410 
411     @Theory
412     public void threadCountSuites( int cpu ) throws TestSetFailedException
413     {
414         ParallelComputerUtil.overrideAvailableProcessors( cpu );
415         Map<String, String> properties = new HashMap<>();
416         properties.put( PARALLEL_KEY, "suites" );
417         properties.put( THREADCOUNT_KEY, "3" );
418         JUnitCoreParameters params = new JUnitCoreParameters( properties );
419         Concurrency concurrency = resolveConcurrency( params, null );
420         assertTrue( params.isParallelSuites() );
421         assertFalse( params.isParallelClasses() );
422         assertFalse( params.isParallelMethods() );
423         assertThat( concurrency.capacity, is( 0 ) );
424         assertThat( concurrency.suites, is( 3 * cpu ) );
425         assertThat( concurrency.classes, is( 0 ) );
426         assertThat( concurrency.methods, is( 0 ) );
427     }
428 
429     @Theory
430     public void threadCountClasses( int cpu ) throws TestSetFailedException
431     {
432         ParallelComputerUtil.overrideAvailableProcessors( cpu );
433         Map<String, String> properties = new HashMap<>();
434         properties.put( PARALLEL_KEY, "classes" );
435         properties.put( THREADCOUNT_KEY, "3" );
436         JUnitCoreParameters params = new JUnitCoreParameters( properties );
437         Concurrency concurrency = resolveConcurrency( params, null );
438         assertFalse( params.isParallelSuites() );
439         assertTrue( params.isParallelClasses() );
440         assertFalse( params.isParallelMethods() );
441         assertThat( concurrency.capacity, is( 0 ) );
442         assertThat( concurrency.suites, is( 0 ) );
443         assertThat( concurrency.classes, is( 3 * cpu ) );
444         assertThat( concurrency.methods, is( 0 ) );
445     }
446 
447     @Theory
448     public void threadCountMethods( int cpu ) throws TestSetFailedException
449     {
450         ParallelComputerUtil.overrideAvailableProcessors( cpu );
451         Map<String, String> properties = new HashMap<>();
452         properties.put( PARALLEL_KEY, "methods" );
453         properties.put( THREADCOUNT_KEY, "3" );
454         JUnitCoreParameters params = new JUnitCoreParameters( properties );
455         Concurrency concurrency = resolveConcurrency( params, null );
456         assertFalse( params.isParallelSuites() );
457         assertFalse( params.isParallelClasses() );
458         assertTrue( params.isParallelMethods() );
459         assertThat( concurrency.capacity, is( 0 ) );
460         assertThat( concurrency.suites, is( 0 ) );
461         assertThat( concurrency.classes, is( 0 ) );
462         assertThat( concurrency.methods, is( 3 * cpu ) );
463     }
464 
465     @Theory
466     public void threadCountBoth( int cpu ) throws TestSetFailedException
467     {
468         ParallelComputerUtil.overrideAvailableProcessors( cpu );
469         Map<String, String> properties = new HashMap<>();
470         properties.put( PARALLEL_KEY, "both" );
471         properties.put( THREADCOUNT_KEY, "3" );
472         JUnitCoreParameters params = new JUnitCoreParameters( properties );
473         Concurrency concurrency = resolveConcurrency( params, null );
474         assertFalse( params.isParallelSuites() );
475         assertTrue( params.isParallelClasses() );
476         assertTrue( params.isParallelMethods() );
477         assertThat( concurrency.capacity, is( 3 * cpu ) );
478         assertThat( concurrency.suites, is( 0 ) );
479         assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
480         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
481     }
482 
483     @Theory
484     public void threadCountClassesAndMethods( int cpu ) throws TestSetFailedException
485     {
486         ParallelComputerUtil.overrideAvailableProcessors( cpu );
487         Map<String, String> properties = new HashMap<>();
488         properties.put( PARALLEL_KEY, "classesAndMethods" );
489         properties.put( THREADCOUNT_KEY, "3" );
490         JUnitCoreParameters params = new JUnitCoreParameters( properties );
491         Concurrency concurrency = resolveConcurrency( params, null );
492         assertFalse( params.isParallelSuites() );
493         assertTrue( params.isParallelClasses() );
494         assertTrue( params.isParallelMethods() );
495         assertThat( concurrency.capacity, is( 3 * cpu ) );
496         assertThat( concurrency.suites, is( 0 ) );
497         assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
498         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
499     }
500 
501     @Theory
502     public void threadCountSuitesAndMethods( int cpu ) throws TestSetFailedException
503     {
504         ParallelComputerUtil.overrideAvailableProcessors( cpu );
505         Map<String, String> properties = new HashMap<>();
506         properties.put( PARALLEL_KEY, "suitesAndMethods" );
507         properties.put( THREADCOUNT_KEY, "3" );
508         JUnitCoreParameters params = new JUnitCoreParameters( properties );
509         Concurrency concurrency = resolveConcurrency( params, null );
510         assertTrue( params.isParallelSuites() );
511         assertFalse( params.isParallelClasses() );
512         assertTrue( params.isParallelMethods() );
513         assertThat( concurrency.capacity, is( 3 * cpu ) );
514         assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
515         assertThat( concurrency.classes, is( 0 ) );
516         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
517     }
518 
519     @Theory
520     public void threadCountSuitesAndClasses( int cpu ) throws TestSetFailedException
521     {
522         ParallelComputerUtil.overrideAvailableProcessors( cpu );
523         Map<String, String> properties = new HashMap<>();
524         properties.put( PARALLEL_KEY, "suitesAndClasses" );
525         properties.put( THREADCOUNT_KEY, "3" );
526         JUnitCoreParameters params = new JUnitCoreParameters( properties );
527         Concurrency concurrency = resolveConcurrency( params, null );
528         assertTrue( params.isParallelSuites() );
529         assertTrue( params.isParallelClasses() );
530         assertFalse( params.isParallelMethods() );
531         assertThat( concurrency.capacity, is( 3 * cpu ) );
532         assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
533         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
534         assertThat( concurrency.methods, is( 0 ) );
535     }
536 
537     @Theory
538     public void threadCountAll( int cpu ) throws TestSetFailedException
539     {
540         ParallelComputerUtil.overrideAvailableProcessors( cpu );
541         Map<String, String> properties = new HashMap<>();
542         properties.put( PARALLEL_KEY, "all" );
543         properties.put( THREADCOUNT_KEY, "3" );
544         JUnitCoreParameters params = new JUnitCoreParameters( properties );
545         Concurrency concurrency = resolveConcurrency( params, null );
546         assertTrue( params.isParallelSuites() );
547         assertTrue( params.isParallelClasses() );
548         assertTrue( params.isParallelMethods() );
549         assertThat( concurrency.capacity, is( 3 * cpu ) );
550         assertThat( concurrency.suites, is( cpu ) );
551         assertThat( concurrency.classes, is( cpu ) );
552         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
553     }
554 
555     @Theory
556     public void everyThreadCountSuitesAndClasses( int cpu ) throws TestSetFailedException
557     {
558         ParallelComputerUtil.overrideAvailableProcessors( cpu );
559         Map<String, String> properties = new HashMap<>();
560         properties.put( PARALLEL_KEY, "suitesAndClasses" );
561         properties.put( THREADCOUNT_KEY, "3" );
562         // % percentage ratio
563         properties.put( THREADCOUNTSUITES_KEY, "34" );
564         properties.put( THREADCOUNTCLASSES_KEY, "66" );
565         JUnitCoreParameters params = new JUnitCoreParameters( properties );
566         Concurrency concurrency = resolveConcurrency( params, null );
567         assertTrue( params.isParallelSuites() );
568         assertTrue( params.isParallelClasses() );
569         assertFalse( params.isParallelMethods() );
570         assertThat( concurrency.capacity, is( 3 * cpu ) );
571         int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
572         assertThat( concurrency.suites, is( concurrentSuites ) );
573         assertThat( concurrency.classes, is( concurrency.capacity - concurrentSuites ) );
574         assertThat( concurrency.methods, is( 0 ) );
575     }
576 
577     @Theory
578     public void everyThreadCountSuitesAndMethods( int cpu ) throws TestSetFailedException
579     {
580         ParallelComputerUtil.overrideAvailableProcessors( cpu );
581         Map<String, String> properties = new HashMap<>();
582         properties.put( PARALLEL_KEY, "suitesAndMethods" );
583         properties.put( THREADCOUNT_KEY, "3" );
584         // % percentage ratio
585         properties.put( THREADCOUNTSUITES_KEY, "34" );
586         properties.put( THREADCOUNTMETHODS_KEY, "66" );
587         JUnitCoreParameters params = new JUnitCoreParameters( properties );
588         Concurrency concurrency = resolveConcurrency( params, null );
589         assertTrue( params.isParallelSuites() );
590         assertFalse( params.isParallelClasses() );
591         assertTrue( params.isParallelMethods() );
592         assertThat( concurrency.capacity, is( 3 * cpu ) );
593         int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
594         assertThat( concurrency.suites, is( concurrentSuites ) );
595         assertThat( concurrency.classes, is( 0 ) );
596         assertThat( concurrency.methods, is( concurrency.capacity - concurrentSuites ) );
597     }
598 
599     @Theory
600     public void everyThreadCountClassesAndMethods( int cpu ) throws TestSetFailedException
601     {
602         ParallelComputerUtil.overrideAvailableProcessors( cpu );
603         Map<String, String> properties = new HashMap<>();
604         properties.put( PARALLEL_KEY, "classesAndMethods" );
605         properties.put( THREADCOUNT_KEY, "3" );
606         // % percentage ratio
607         properties.put( THREADCOUNTCLASSES_KEY, "34" );
608         properties.put( THREADCOUNTMETHODS_KEY, "66" );
609         JUnitCoreParameters params = new JUnitCoreParameters( properties );
610         Concurrency concurrency = resolveConcurrency( params, null );
611         assertFalse( params.isParallelSuites() );
612         assertTrue( params.isParallelClasses() );
613         assertTrue( params.isParallelMethods() );
614         assertThat( concurrency.capacity, is( 3 * cpu ) );
615         assertThat( concurrency.suites, is( 0 ) );
616         int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
617         assertThat( concurrency.classes, is( concurrentClasses ) );
618         assertThat( concurrency.methods, is( concurrency.capacity - concurrentClasses ) );
619     }
620 
621     @Theory
622     public void everyThreadCountAll( int cpu ) throws TestSetFailedException
623     {
624         ParallelComputerUtil.overrideAvailableProcessors( cpu );
625         Map<String, String> properties = new HashMap<>();
626         properties.put( PARALLEL_KEY, "all" );
627         properties.put( THREADCOUNT_KEY, "3" );
628         // % percentage ratio
629         properties.put( THREADCOUNTSUITES_KEY, "17" );
630         properties.put( THREADCOUNTCLASSES_KEY, "34" );
631         properties.put( THREADCOUNTMETHODS_KEY, "49" );
632         JUnitCoreParameters params = new JUnitCoreParameters( properties );
633         Concurrency concurrency = resolveConcurrency( params, null );
634         assertTrue( params.isParallelSuites() );
635         assertTrue( params.isParallelClasses() );
636         assertTrue( params.isParallelMethods() );
637         assertThat( concurrency.capacity, is( 3 * cpu ) );
638         int concurrentSuites = (int) ( 0.17d * concurrency.capacity );
639         int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
640         assertThat( concurrency.suites, is( concurrentSuites ) );
641         assertThat( concurrency.classes, is( concurrentClasses ) );
642         assertThat( concurrency.methods, is( concurrency.capacity - concurrentSuites - concurrentClasses ) );
643     }
644 
645     @Theory
646     public void reusableThreadCountSuitesAndClasses( int cpu ) throws TestSetFailedException
647     {
648         // 4 * cpu to 5 * cpu threads to run test classes
649         ParallelComputerUtil.overrideAvailableProcessors( cpu );
650         Map<String, String> properties = new HashMap<>();
651         properties.put( PARALLEL_KEY, "suitesAndClasses" );
652         properties.put( THREADCOUNT_KEY, "6" );
653         properties.put( THREADCOUNTSUITES_KEY, "2" );
654         JUnitCoreParameters params = new JUnitCoreParameters( properties );
655         Concurrency concurrency = resolveConcurrency( params, null );
656         assertTrue( params.isParallelSuites() );
657         assertTrue( params.isParallelClasses() );
658         assertFalse( params.isParallelMethods() );
659         assertThat( concurrency.capacity, is( 6 * cpu ) );
660         assertThat( concurrency.suites, is( 2 * cpu ) );
661         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
662         assertThat( concurrency.methods, is( 0 ) );
663     }
664 
665     @Theory
666     public void reusableThreadCountSuitesAndMethods( int cpu ) throws TestSetFailedException
667     {
668         // 4 * cpu to 5 * cpu threads to run test methods
669         ParallelComputerUtil.overrideAvailableProcessors( cpu );
670         Map<String, String> properties = new HashMap<>();
671         properties.put( PARALLEL_KEY, "suitesAndMethods" );
672         properties.put( THREADCOUNT_KEY, "6" );
673         properties.put( THREADCOUNTSUITES_KEY, "2" );
674         JUnitCoreParameters params = new JUnitCoreParameters( properties );
675         Concurrency concurrency = resolveConcurrency( params, null );
676         assertTrue( params.isParallelSuites() );
677         assertFalse( params.isParallelClasses() );
678         assertTrue( params.isParallelMethods() );
679         assertThat( concurrency.capacity, is( 6 * cpu ) );
680         assertThat( concurrency.suites, is( 2 * cpu ) );
681         assertThat( concurrency.classes, is( 0 ) );
682         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
683     }
684 
685     @Theory
686     public void reusableThreadCountClassesAndMethods( int cpu ) throws TestSetFailedException
687     {
688         // 4 * cpu to 5 * cpu threads to run test methods
689         ParallelComputerUtil.overrideAvailableProcessors( cpu );
690         Map<String, String> properties = new HashMap<>();
691         properties.put( PARALLEL_KEY, "classesAndMethods" );
692         properties.put( THREADCOUNT_KEY, "6" );
693         properties.put( THREADCOUNTCLASSES_KEY, "2" );
694         JUnitCoreParameters params = new JUnitCoreParameters( properties );
695         Concurrency concurrency = resolveConcurrency( params, null );
696         assertFalse( params.isParallelSuites() );
697         assertTrue( params.isParallelClasses() );
698         assertTrue( params.isParallelMethods() );
699         assertThat( concurrency.capacity, is( 6 * cpu ) );
700         assertThat( concurrency.suites, is( 0 ) );
701         assertThat( concurrency.classes, is( 2 * cpu ) );
702         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
703     }
704 
705     @Theory
706     public void reusableThreadCountAll( int cpu ) throws TestSetFailedException
707     {
708         // 8 * cpu to 13 * cpu threads to run test methods
709         ParallelComputerUtil.overrideAvailableProcessors( cpu );
710         Map<String, String> properties = new HashMap<>();
711         properties.put( PARALLEL_KEY, "all" );
712         properties.put( THREADCOUNT_KEY, "14" );
713         properties.put( THREADCOUNTSUITES_KEY, "2" );
714         properties.put( THREADCOUNTCLASSES_KEY, "4" );
715         JUnitCoreParameters params = new JUnitCoreParameters( properties );
716         Concurrency concurrency = resolveConcurrency( params, null );
717         assertTrue( params.isParallelSuites() );
718         assertTrue( params.isParallelClasses() );
719         assertTrue( params.isParallelMethods() );
720         assertThat( concurrency.capacity, is( 14 * cpu ) );
721         assertThat( concurrency.suites, is( 2 * cpu ) );
722         assertThat( concurrency.classes, is( 4 * cpu ) );
723         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
724     }
725 
726     @Theory
727     public void suites( int cpu ) throws TestSetFailedException
728     {
729         ParallelComputerUtil.overrideAvailableProcessors( cpu );
730         Map<String, String> properties = new HashMap<>();
731         properties.put( PARALLEL_KEY, "suites" );
732         properties.put( THREADCOUNTSUITES_KEY, "5" );
733         JUnitCoreParameters params = new JUnitCoreParameters( properties );
734         Concurrency concurrency = resolveConcurrency( params, null );
735         assertTrue( params.isParallelSuites() );
736         assertFalse( params.isParallelClasses() );
737         assertFalse( params.isParallelMethods() );
738         assertThat( concurrency.capacity, is( 5 * cpu ) );
739         assertThat( concurrency.suites, is( 5 * cpu ) );
740         assertThat( concurrency.classes, is( 0 ) );
741         assertThat( concurrency.methods, is( 0 ) );
742     }
743 
744     @Theory
745     public void classes( int cpu ) throws TestSetFailedException
746     {
747         ParallelComputerUtil.overrideAvailableProcessors( cpu );
748         Map<String, String> properties = new HashMap<>();
749         properties.put( PARALLEL_KEY, "classes" );
750         properties.put( THREADCOUNTCLASSES_KEY, "5" );
751         JUnitCoreParameters params = new JUnitCoreParameters( properties );
752         Concurrency concurrency = resolveConcurrency( params, null );
753         assertFalse( params.isParallelSuites() );
754         assertTrue( params.isParallelClasses() );
755         assertFalse( params.isParallelMethods() );
756         assertThat( concurrency.capacity, is( 5 * cpu ) );
757         assertThat( concurrency.suites, is( 0 ) );
758         assertThat( concurrency.classes, is( 5 * cpu ) );
759         assertThat( concurrency.methods, is( 0 ) );
760     }
761 
762     @Theory
763     public void methods( int cpu ) throws TestSetFailedException
764     {
765         ParallelComputerUtil.overrideAvailableProcessors( cpu );
766         Map<String, String> properties = new HashMap<>();
767         properties.put( PARALLEL_KEY, "methods" );
768         properties.put( THREADCOUNTMETHODS_KEY, "5" );
769         JUnitCoreParameters params = new JUnitCoreParameters( properties );
770         Concurrency concurrency = resolveConcurrency( params, null );
771         assertFalse( params.isParallelSuites() );
772         assertFalse( params.isParallelClasses() );
773         assertTrue( params.isParallelMethods() );
774         assertThat( concurrency.capacity, is( 5 * cpu ) );
775         assertThat( concurrency.suites, is( 0 ) );
776         assertThat( concurrency.classes, is( 0 ) );
777         assertThat( concurrency.methods, is( 5 * cpu ) );
778     }
779 
780     @Theory
781     public void suitesAndClasses( int cpu ) throws TestSetFailedException
782     {
783         ParallelComputerUtil.overrideAvailableProcessors( cpu );
784         Map<String, String> properties = new HashMap<>();
785 
786         properties.put( PARALLEL_KEY, "suitesAndClasses" );
787         properties.put( THREADCOUNTSUITES_KEY, "5" );
788         properties.put( THREADCOUNTCLASSES_KEY, "15" );
789         JUnitCoreParameters params = new JUnitCoreParameters( properties );
790         Concurrency concurrency = resolveConcurrency( params, null );
791         assertTrue( params.isParallelSuites() );
792         assertTrue( params.isParallelClasses() );
793         assertFalse( params.isParallelMethods() );
794         assertThat( concurrency.capacity, is( 20 * cpu ) );
795         assertThat( concurrency.suites, is( 5 * cpu ) );
796         assertThat( concurrency.classes, is( 15 * cpu ) );
797         assertThat( concurrency.methods, is( 0 ) );
798 
799         // Warning: this case works but is not enabled in AbstractSurefireMojo
800         // Instead use the 'useUnlimitedThreads' parameter.
801         properties = new HashMap<>();
802         properties.put( PARALLEL_KEY, "suitesAndClasses" );
803         properties.put( THREADCOUNTSUITES_KEY, "5" );
804         params = new JUnitCoreParameters( properties );
805         concurrency = resolveConcurrency( params, null );
806         assertTrue( params.isParallelSuites() );
807         assertTrue( params.isParallelClasses() );
808         assertFalse( params.isParallelMethods() );
809         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
810         assertThat( concurrency.suites, is( 5 * cpu ) );
811         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
812         assertThat( concurrency.methods, is( 0 ) );
813     }
814 
815     @Theory
816     public void suitesAndMethods( int cpu ) throws TestSetFailedException
817     {
818         ParallelComputerUtil.overrideAvailableProcessors( cpu );
819         Map<String, String> properties = new HashMap<>();
820 
821         properties.put( PARALLEL_KEY, "suitesAndMethods" );
822         properties.put( THREADCOUNTSUITES_KEY, "5" );
823         properties.put( THREADCOUNTMETHODS_KEY, "15" );
824         JUnitCoreParameters params = new JUnitCoreParameters( properties );
825         Concurrency concurrency = resolveConcurrency( params, null );
826         assertTrue( params.isParallelSuites() );
827         assertFalse( params.isParallelClasses() );
828         assertTrue( params.isParallelMethods() );
829         assertThat( concurrency.capacity, is( 20 * cpu ) );
830         assertThat( concurrency.suites, is( 5 * cpu ) );
831         assertThat( concurrency.classes, is( 0 ) );
832         assertThat( concurrency.methods, is( 15 * cpu ) );
833 
834         // Warning: this case works but is not enabled in AbstractSurefireMojo
835         // Instead use the 'useUnlimitedThreads' parameter.
836         properties = new HashMap<>();
837         properties.put( PARALLEL_KEY, "suitesAndMethods" );
838         properties.put( THREADCOUNTSUITES_KEY, "5" );
839         params = new JUnitCoreParameters( properties );
840         concurrency = resolveConcurrency( params, null );
841         assertTrue( params.isParallelSuites() );
842         assertFalse( params.isParallelClasses() );
843         assertTrue( params.isParallelMethods() );
844         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
845         assertThat( concurrency.suites, is( 5 * cpu ) );
846         assertThat( concurrency.classes, is( 0 ) );
847         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
848     }
849 
850     @Theory
851     public void classesAndMethods( int cpu ) throws TestSetFailedException
852     {
853         ParallelComputerUtil.overrideAvailableProcessors( cpu );
854         Map<String, String> properties = new HashMap<>();
855 
856         properties.put( PARALLEL_KEY, "classesAndMethods" );
857         properties.put( THREADCOUNTCLASSES_KEY, "5" );
858         properties.put( THREADCOUNTMETHODS_KEY, "15" );
859         JUnitCoreParameters params = new JUnitCoreParameters( properties );
860         Concurrency concurrency = resolveConcurrency( params, null );
861         assertFalse( params.isParallelSuites() );
862         assertTrue( params.isParallelClasses() );
863         assertTrue( params.isParallelMethods() );
864         assertThat( concurrency.capacity, is( 20 * cpu ) );
865         assertThat( concurrency.suites, is( 0 ) );
866         assertThat( concurrency.classes, is( 5 * cpu ) );
867         assertThat( concurrency.methods, is( 15 * cpu ) );
868 
869         // Warning: this case works but is not enabled in AbstractSurefireMojo
870         // Instead use the 'useUnlimitedThreads' parameter.
871         properties = new HashMap<>();
872         properties.put( PARALLEL_KEY, "classesAndMethods" );
873         properties.put( THREADCOUNTCLASSES_KEY, "5" );
874         params = new JUnitCoreParameters( properties );
875         concurrency = resolveConcurrency( params, null );
876         assertFalse( params.isParallelSuites() );
877         assertTrue( params.isParallelClasses() );
878         assertTrue( params.isParallelMethods() );
879         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
880         assertThat( concurrency.suites, is( 0 ) );
881         assertThat( concurrency.classes, is( 5 * cpu ) );
882         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
883     }
884 
885     @Theory
886     public void all( int cpu ) throws TestSetFailedException
887     {
888         ParallelComputerUtil.overrideAvailableProcessors( cpu );
889         Map<String, String> properties = new HashMap<>();
890 
891         properties.put( PARALLEL_KEY, "all" );
892         properties.put( THREADCOUNTSUITES_KEY, "5" );
893         properties.put( THREADCOUNTCLASSES_KEY, "15" );
894         properties.put( THREADCOUNTMETHODS_KEY, "30" );
895         JUnitCoreParameters params = new JUnitCoreParameters( properties );
896         Concurrency concurrency = resolveConcurrency( params, null );
897         assertTrue( params.isParallelSuites() );
898         assertTrue( params.isParallelClasses() );
899         assertTrue( params.isParallelMethods() );
900         assertThat( concurrency.capacity, is( 50 * cpu ) );
901         assertThat( concurrency.suites, is( 5 * cpu ) );
902         assertThat( concurrency.classes, is( 15 * cpu ) );
903         assertThat( concurrency.methods, is( 30 * cpu ) );
904 
905         // Warning: these cases work but they are not enabled in AbstractSurefireMojo
906         // Instead use the 'useUnlimitedThreads' parameter.
907         properties = new HashMap<>();
908         properties.put( PARALLEL_KEY, "all" );
909         properties.put( THREADCOUNTSUITES_KEY, "5" );
910         properties.put( THREADCOUNTCLASSES_KEY, "15" );
911         params = new JUnitCoreParameters( properties );
912         concurrency = resolveConcurrency( params, null );
913         assertTrue( params.isParallelSuites() );
914         assertTrue( params.isParallelClasses() );
915         assertTrue( params.isParallelMethods() );
916         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
917         assertThat( concurrency.suites, is( 5 * cpu ) );
918         assertThat( concurrency.classes, is( 15 * cpu ) );
919         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
920 
921         properties = new HashMap<>();
922         properties.put( PARALLEL_KEY, "all" );
923         properties.put( THREADCOUNTCLASSES_KEY, "15" );
924         params = new JUnitCoreParameters( properties );
925         concurrency = resolveConcurrency( params, null );
926         assertTrue( params.isParallelSuites() );
927         assertTrue( params.isParallelClasses() );
928         assertTrue( params.isParallelMethods() );
929         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
930         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
931         assertThat( concurrency.classes, is( 15 * cpu ) );
932         assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
933     }
934 
935     @Test
936     public void withoutShutdown()
937     {
938         Map<String, String> properties = new HashMap<>();
939         properties.put( PARALLEL_KEY, "methods" );
940         properties.put( THREADCOUNTMETHODS_KEY, "2" );
941         JUnitCoreParameters params = new JUnitCoreParameters( properties );
942         ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
943         ParallelComputer pc = pcBuilder.buildComputer();
944         final JUnitCore core = new JUnitCore();
945         final long t1 = systemMillis();
946         final Result result = core.run( pc, TestClass.class );
947         final long t2 = systemMillis();
948         long timeSpent = t2 - t1;
949         final long deltaTime = 500L;
950 
951         assertTrue( result.wasSuccessful() );
952         assertThat( result.getRunCount(), is( 3 ) );
953         assertThat( result.getFailureCount(), is( 0 ) );
954         assertThat( result.getIgnoreCount(), is( 0 ) );
955         //assertThat( timeSpent, between (timeSpent - deltaTime, timeSpent + deltaTime + 2000L ) );
956         assertEquals( 10000L, timeSpent, deltaTime );
957     }
958 
959     @Test
960     public void shutdown() throws TestSetFailedException
961     {
962         // The JUnitCore returns after 2.5s.
963         // The test-methods in TestClass are NOT interrupted, and return normally after 5s.
964         Map<String, String> properties = new HashMap<>();
965         properties.put( PARALLEL_KEY, "methods" );
966         properties.put( THREADCOUNTMETHODS_KEY, "2" );
967         properties.put( PARALLEL_TIMEOUT_KEY, Double.toString( 2.5d ) );
968         JUnitCoreParameters params = new JUnitCoreParameters( properties );
969         ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
970         ParallelComputer pc = pcBuilder.buildComputer();
971         final JUnitCore core = new JUnitCore();
972         final long t1 = systemMillis();
973         core.run( pc, TestClass.class );
974         final long t2 = systemMillis();
975         final long timeSpent = t2 - t1;
976         final long deltaTime = 500L;
977 
978         assertEquals( 5000L, timeSpent, deltaTime );
979         String description = pc.describeElapsedTimeout();
980         assertTrue( description.contains( "The test run has finished abruptly after timeout of 2.5 seconds." ) );
981         assertTrue( description.contains(
982                 "These tests were executed in prior to the shutdown operation:\n" + TestClass.class.getName() ) );
983     }
984 
985     @Test
986     public void forcedShutdown() throws TestSetFailedException
987     {
988         // The JUnitCore returns after 2.5s, and the test-methods in TestClass are interrupted.
989         Map<String, String> properties = new HashMap<>();
990         properties.put( PARALLEL_KEY, "methods" );
991         properties.put( THREADCOUNTMETHODS_KEY, "2" );
992         properties.put( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 2.5d ) );
993         JUnitCoreParameters params = new JUnitCoreParameters( properties );
994         ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
995         ParallelComputer pc = pcBuilder.buildComputer();
996         final JUnitCore core = new JUnitCore();
997         final long t1 = systemMillis();
998         core.run( pc, TestClass.class );
999         final long t2 = systemMillis();
1000         final long timeSpent = t2 - t1;
1001         final long deltaTime = 500L;
1002 
1003         assertEquals( 2500L, timeSpent, deltaTime );
1004         String description = pc.describeElapsedTimeout();
1005         assertTrue( description.contains( "The test run has finished abruptly after timeout of 2.5 seconds." ) );
1006         assertTrue( description.contains(
1007                 "These tests were executed in prior to the shutdown operation:\n" + TestClass.class.getName() ) );
1008     }
1009 
1010     @Test
1011     public void timeoutAndForcedShutdown() throws TestSetFailedException
1012     {
1013         // The JUnitCore returns after 3.5s and the test-methods in TestClass are timed out after 2.5s.
1014         // No new test methods are scheduled for execution after 2.5s.
1015         // Interruption of test methods after 3.5s.
1016         Map<String, String> properties = new HashMap<>();
1017         properties.put( PARALLEL_KEY, "methods" );
1018         properties.put( THREADCOUNTMETHODS_KEY, "2" );
1019         properties.put( PARALLEL_TIMEOUT_KEY, Double.toString( 2.5d ) );
1020         properties.put( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 3.5d ) );
1021         JUnitCoreParameters params = new JUnitCoreParameters( properties );
1022         ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
1023         ParallelComputer pc = pcBuilder.buildComputer();
1024         final JUnitCore core = new JUnitCore();
1025         final long t1 = systemMillis();
1026         core.run( pc, TestClass.class );
1027         final long t2 = systemMillis();
1028         final long timeSpent = t2 - t1;
1029         final long deltaTime = 500L;
1030 
1031         assertEquals( 3500L, timeSpent, deltaTime );
1032         String description = pc.describeElapsedTimeout();
1033         assertTrue( description.contains( "The test run has finished abruptly after timeout of 2.5 seconds." ) );
1034         assertTrue( description.contains(
1035                 "These tests were executed in prior to the shutdown operation:\n" + TestClass.class.getName() ) );
1036     }
1037 
1038     @Test
1039     public void forcedTimeoutAndShutdown() throws Exception
1040     {
1041         // The JUnitCore returns after 3.5s and the test-methods in TestClass are interrupted after 3.5s.
1042         Map<String, String> properties = new HashMap<>();
1043         properties.put( PARALLEL_KEY, "methods" );
1044         properties.put( THREADCOUNTMETHODS_KEY, "2" );
1045         properties.put( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 3.5d ) );
1046         properties.put( PARALLEL_TIMEOUT_KEY, Double.toString( 4.0d ) );
1047         JUnitCoreParameters params = new JUnitCoreParameters( properties );
1048         ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
1049         ParallelComputer pc = pcBuilder.buildComputer();
1050         final JUnitCore core = new JUnitCore();
1051         final long t1 = systemMillis();
1052         core.run( pc, TestClass.class );
1053         final long t2 = systemMillis();
1054         final long timeSpent = t2 - t1;
1055         final long deltaTime = 500L;
1056 
1057         assertEquals( 3500L, timeSpent, deltaTime );
1058         String description = pc.describeElapsedTimeout();
1059         assertTrue( description.contains( "The test run has finished abruptly after timeout of 3.5 seconds." ) );
1060         assertTrue( description.contains(
1061                 "These tests were executed in prior to the shutdown operation:\n" + TestClass.class.getName() ) );
1062     }
1063 
1064     /**
1065      *
1066      */
1067     public static class TestClass
1068     {
1069         @Test
1070         public void a() throws InterruptedException
1071         {
1072             long t1 = systemMillis();
1073             try
1074             {
1075                 Thread.sleep( 5000L );
1076             }
1077             finally
1078             {
1079                 System.out.println( getClass().getSimpleName() + "#a() spent " + ( systemMillis() - t1 ) );
1080             }
1081         }
1082 
1083         @Test
1084         public void b() throws InterruptedException
1085         {
1086             long t1 = systemMillis();
1087             try
1088             {
1089                 Thread.sleep( 5000L );
1090             }
1091             finally
1092             {
1093                 System.out.println( getClass().getSimpleName() + "#b() spent " + ( systemMillis() - t1 ) );
1094             }
1095         }
1096 
1097         @Test
1098         public void c() throws InterruptedException
1099         {
1100             long t1 = systemMillis();
1101             try
1102             {
1103                 Thread.sleep( 5000L );
1104             }
1105             finally
1106             {
1107                 System.out.println( getClass().getSimpleName() + "#c() spent " + ( systemMillis() - t1 ) );
1108             }
1109         }
1110     }
1111 
1112     private static long systemMillis()
1113     {
1114         return TimeUnit.NANOSECONDS.toMillis( System.nanoTime() );
1115     }
1116 }