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