1 package org.apache.maven.surefire.junitcore.pc;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import net.jcip.annotations.NotThreadSafe;
23 import org.apache.maven.surefire.report.ConsoleStream;
24 import org.apache.maven.surefire.report.DefaultDirectConsoleReporter;
25 import org.junit.After;
26 import org.junit.AfterClass;
27 import org.junit.Before;
28 import org.junit.BeforeClass;
29 import org.junit.Test;
30 import org.junit.runner.Description;
31 import org.junit.runner.JUnitCore;
32 import org.junit.runner.Result;
33 import org.junit.runner.RunWith;
34 import org.junit.runner.notification.RunNotifier;
35 import org.junit.runners.ParentRunner;
36 import org.junit.runners.Suite;
37 import org.junit.runners.model.InitializationError;
38
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.Comparator;
44 import java.util.Date;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.concurrent.ConcurrentLinkedQueue;
48 import java.util.concurrent.TimeUnit;
49
50 import static org.hamcrest.core.AnyOf.anyOf;
51 import static org.hamcrest.core.Is.is;
52 import static org.hamcrest.core.IsNot.not;
53 import static org.apache.maven.surefire.junitcore.pc.RangeMatcher.between;
54 import static org.junit.Assert.*;
55
56
57
58
59
60 public class ParallelComputerBuilderTest
61 {
62 private static final int DELAY_MULTIPLIER = 7;
63
64 private static final Object class1Lock = new Object();
65
66 private static volatile boolean beforeShutdown;
67
68 private static volatile Runnable shutdownTask;
69
70 private static final ConsoleStream logger = new DefaultDirectConsoleReporter( System.out );
71
72 private static void testKeepBeforeAfter( ParallelComputerBuilder builder, Class<?>... classes )
73 {
74 JUnitCore core = new JUnitCore();
75 for ( int round = 0; round < 5; round++ )
76 {
77 NothingDoingTest1.methods.clear();
78 Result result = core.run( builder.buildComputer(), classes );
79 assertTrue( result.wasSuccessful() );
80 Iterator<String> methods = NothingDoingTest1.methods.iterator();
81 for ( Class<?> clazz : classes )
82 {
83 String a = clazz.getName() + "#a()";
84 String b = clazz.getName() + "#b()";
85 assertThat( methods.next(), is( "init" ) );
86 assertThat( methods.next(), anyOf( is( a ), is( b ) ) );
87 assertThat( methods.next(), anyOf( is( a ), is( b ) ) );
88 assertThat( methods.next(), is( "deinit" ) );
89 }
90 }
91 }
92
93 @BeforeClass
94 public static void cleanup() throws InterruptedException
95 {
96 System.gc();
97 Thread.sleep( 500L );
98 }
99
100 @Before
101 public void beforeTest()
102 {
103 Class1.maxConcurrentMethods = 0;
104 Class1.concurrentMethods = 0;
105 shutdownTask = null;
106 NotThreadSafeTest1.t = null;
107 NotThreadSafeTest2.t = null;
108 NotThreadSafeTest3.t = null;
109 NormalTest1.t = null;
110 NormalTest2.t = null;
111 }
112
113 @Test
114 public void testsWithoutChildrenShouldAlsoBeRun()
115 {
116 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
117 ParallelComputerBuilder.PC computer = ( ParallelComputerBuilder.PC ) parallelComputerBuilder.buildComputer();
118 Result result = new JUnitCore().run( computer, TestWithoutPrecalculatedChildren.class );
119 assertThat( result.getRunCount(), is( 1 ) );
120 }
121
122 @Test
123 public void parallelMethodsReuseOneOrTwoThreads()
124 {
125 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
126 parallelComputerBuilder.useOnePool( 4 );
127
128
129 parallelComputerBuilder.parallelSuites( 5 );
130
131
132 parallelComputerBuilder.parallelClasses( 5 );
133
134
135
136 parallelComputerBuilder.parallelMethods( 3 );
137
138 assertFalse( parallelComputerBuilder.isOptimized() );
139
140 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
141 final JUnitCore core = new JUnitCore();
142 final long t1 = systemMillis();
143 final Result result = core.run( computer, TestSuite.class );
144 final long t2 = systemMillis();
145 final long timeSpent = t2 - t1;
146
147 assertThat( computer.getSuites().size(), is( 1 ) );
148 assertThat( computer.getClasses().size(), is( 0 ) );
149 assertThat( computer.getNestedClasses().size(), is( 2 ) );
150 assertThat( computer.getNestedSuites().size(), is( 0 ) );
151 assertFalse( computer.isSplitPool() );
152 assertThat( computer.getPoolCapacity(), is( 4 ) );
153 assertTrue( result.wasSuccessful() );
154 if ( Class1.maxConcurrentMethods == 1 )
155 {
156 assertThat( timeSpent, between( 2000 * DELAY_MULTIPLIER - 50, 2250 * DELAY_MULTIPLIER ) );
157 }
158 else if ( Class1.maxConcurrentMethods == 2 )
159 {
160 assertThat( timeSpent, between( 1500 * DELAY_MULTIPLIER - 50, 1750 * DELAY_MULTIPLIER ) );
161 }
162 else
163 {
164 fail();
165 }
166 }
167
168 @Test
169 public void suiteAndClassInOnePool()
170 {
171 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
172 parallelComputerBuilder.useOnePool( 5 );
173 parallelComputerBuilder.parallelSuites( 5 );
174 parallelComputerBuilder.parallelClasses( 5 );
175 parallelComputerBuilder.parallelMethods( 3 );
176 assertFalse( parallelComputerBuilder.isOptimized() );
177
178 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
179 final JUnitCore core = new JUnitCore();
180 final long t1 = systemMillis();
181 final Result result = core.run( computer, TestSuite.class, Class1.class );
182 final long t2 = systemMillis();
183 final long timeSpent = t2 - t1;
184
185 assertThat( computer.getSuites().size(), is( 1 ) );
186 assertThat( computer.getClasses().size(), is( 1 ) );
187 assertThat( computer.getNestedClasses().size(), is( 2 ) );
188 assertThat( computer.getNestedSuites().size(), is( 0 ) );
189 assertFalse( computer.isSplitPool() );
190 assertThat( computer.getPoolCapacity(), is( 5 ) );
191 assertTrue( result.wasSuccessful() );
192 assertThat( Class1.maxConcurrentMethods, is( 2 ) );
193 assertThat( timeSpent, anyOf(
194 between( 1500 * DELAY_MULTIPLIER - 50, 1750 * DELAY_MULTIPLIER ),
195 between( 2000 * DELAY_MULTIPLIER - 50, 2250 * DELAY_MULTIPLIER ),
196 between( 2500 * DELAY_MULTIPLIER - 50, 2750 * DELAY_MULTIPLIER )
197 ) );
198 }
199
200 @Test
201 public void onePoolWithUnlimitedParallelMethods()
202 {
203
204 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
205 parallelComputerBuilder.useOnePool( 8 );
206 parallelComputerBuilder.parallelSuites( 2 );
207 parallelComputerBuilder.parallelClasses( 4 );
208 parallelComputerBuilder.parallelMethods();
209 assertFalse( parallelComputerBuilder.isOptimized() );
210
211 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
212 final JUnitCore core = new JUnitCore();
213 final long t1 = systemMillis();
214 final Result result = core.run( computer, TestSuite.class, Class1.class );
215 final long t2 = systemMillis();
216 final long timeSpent = t2 - t1;
217
218 assertThat( computer.getSuites().size(), is( 1 ) );
219 assertThat( computer.getClasses().size(), is( 1 ) );
220 assertThat( computer.getNestedClasses().size(), is( 2 ) );
221 assertThat( computer.getNestedSuites().size(), is( 0 ) );
222 assertFalse( computer.isSplitPool() );
223 assertThat( computer.getPoolCapacity(), is( 8 ) );
224 assertTrue( result.wasSuccessful() );
225 assertThat( Class1.maxConcurrentMethods, is( 4 ) );
226 assertThat( timeSpent, between( 1000 * DELAY_MULTIPLIER - 50, 1250 * DELAY_MULTIPLIER ) );
227 }
228
229 @Test
230 public void underflowParallelism()
231 {
232 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
233 parallelComputerBuilder.useOnePool( 3 );
234
235
236 parallelComputerBuilder.parallelSuites( 5 );
237
238
239 parallelComputerBuilder.parallelClasses( 1 );
240
241
242 parallelComputerBuilder.parallelMethods( 3 );
243
244 assertFalse( parallelComputerBuilder.isOptimized() );
245
246 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
247 final JUnitCore core = new JUnitCore();
248 final long t1 = systemMillis();
249 final Result result = core.run( computer, TestSuite.class );
250 final long t2 = systemMillis();
251 final long timeSpent = t2 - t1;
252
253 assertThat( computer.getSuites().size(), is( 1 ) );
254 assertThat( computer.getClasses().size(), is( 0 ) );
255 assertThat( computer.getNestedClasses().size(), is( 2 ) );
256 assertThat( computer.getNestedSuites().size(), is( 0 ) );
257 assertFalse( computer.isSplitPool() );
258 assertThat( computer.getPoolCapacity(), is( 3 ) );
259 assertTrue( result.wasSuccessful() );
260 assertThat( Class1.maxConcurrentMethods, is( 1 ) );
261 assertThat( timeSpent, between( 2000 * DELAY_MULTIPLIER - 50, 2250 * DELAY_MULTIPLIER ) );
262 }
263
264 @Test
265 public void separatePoolsWithSuite()
266 {
267 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
268 parallelComputerBuilder.parallelSuites( 5 );
269 parallelComputerBuilder.parallelClasses( 5 );
270 parallelComputerBuilder.parallelMethods( 3 );
271 assertFalse( parallelComputerBuilder.isOptimized() );
272
273 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
274 final JUnitCore core = new JUnitCore();
275 final long t1 = systemMillis();
276 final Result result = core.run( computer, TestSuite.class );
277 final long t2 = systemMillis();
278 final long timeSpent = t2 - t1;
279
280 assertThat( computer.getSuites().size(), is( 1 ) );
281 assertThat( computer.getClasses().size(), is( 0 ) );
282 assertThat( computer.getNestedClasses().size(), is( 2 ) );
283 assertThat( computer.getNestedSuites().size(), is( 0 ) );
284 assertTrue( computer.isSplitPool() );
285 assertThat( computer.getPoolCapacity(), is( ParallelComputerBuilder.TOTAL_POOL_SIZE_UNDEFINED ) );
286 assertTrue( result.wasSuccessful() );
287 assertThat( Class1.maxConcurrentMethods, is( 3 ) );
288 assertThat( timeSpent, between( 1000 * DELAY_MULTIPLIER - 50, 1250 * DELAY_MULTIPLIER ) );
289 }
290
291 @Test
292 public void separatePoolsWithSuiteAndClass()
293 {
294 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
295 parallelComputerBuilder.parallelSuites( 5 );
296 parallelComputerBuilder.parallelClasses( 5 );
297 parallelComputerBuilder.parallelMethods( 3 );
298 assertFalse( parallelComputerBuilder.isOptimized() );
299
300
301
302
303 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
304 final JUnitCore core = new JUnitCore();
305 final long t1 = systemMillis();
306 final Result result = core.run( computer, TestSuite.class, Class1.class );
307 final long t2 = systemMillis();
308 final long timeSpent = t2 - t1;
309
310 assertThat( computer.getSuites().size(), is( 1 ) );
311 assertThat( computer.getClasses().size(), is( 1 ) );
312 assertThat( computer.getNestedClasses().size(), is( 2 ) );
313 assertThat( computer.getNestedSuites().size(), is( 0 ) );
314 assertTrue( computer.isSplitPool() );
315 assertThat( computer.getPoolCapacity(), is( ParallelComputerBuilder.TOTAL_POOL_SIZE_UNDEFINED ) );
316 assertTrue( result.wasSuccessful() );
317 assertThat( Class1.maxConcurrentMethods, is( 3 ) );
318 assertThat( timeSpent, between( 1000 * DELAY_MULTIPLIER - 50, 1250 * DELAY_MULTIPLIER ) );
319 }
320
321 @Test
322 public void separatePoolsWithSuiteAndSequentialClasses()
323 {
324 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
325 parallelComputerBuilder.parallelSuites( 5 );
326 parallelComputerBuilder.parallelClasses( 1 );
327 parallelComputerBuilder.parallelMethods( 3 );
328 assertFalse( parallelComputerBuilder.isOptimized() );
329
330 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
331 final JUnitCore core = new JUnitCore();
332 final long t1 = systemMillis();
333 final Result result = core.run( computer, TestSuite.class, Class1.class );
334 final long t2 = systemMillis();
335 final long timeSpent = t2 - t1;
336
337 assertThat( computer.getSuites().size(), is( 1 ) );
338 assertThat( computer.getClasses().size(), is( 1 ) );
339 assertThat( computer.getNestedClasses().size(), is( 2 ) );
340 assertThat( computer.getNestedSuites().size(), is( 0 ) );
341 assertTrue( computer.isSplitPool() );
342 assertThat( computer.getPoolCapacity(), is( ParallelComputerBuilder.TOTAL_POOL_SIZE_UNDEFINED ) );
343 assertTrue( result.wasSuccessful() );
344 assertThat( Class1.maxConcurrentMethods, is( 2 ) );
345 assertThat( timeSpent, between( 1500 * DELAY_MULTIPLIER - 50, 1750 * DELAY_MULTIPLIER ) );
346 }
347
348 @Test( timeout = 2000 * DELAY_MULTIPLIER )
349 public void shutdown()
350 {
351 final long t1 = systemMillis();
352 final Result result = new ShutdownTest().run( false );
353 final long t2 = systemMillis();
354 final long timeSpent = t2 - t1;
355 assertTrue( result.wasSuccessful() );
356 assertTrue( beforeShutdown );
357 assertThat( timeSpent, between( 500 * DELAY_MULTIPLIER - 50, 1250 * DELAY_MULTIPLIER ) );
358 }
359
360 @Test( timeout = 2000 * DELAY_MULTIPLIER )
361 public void shutdownWithInterrupt()
362 {
363 final long t1 = systemMillis();
364 new ShutdownTest().run( true );
365 final long t2 = systemMillis();
366 final long timeSpent = t2 - t1;
367 assertTrue( beforeShutdown );
368 assertThat( timeSpent, between( 500 * DELAY_MULTIPLIER - 50, 1250 * DELAY_MULTIPLIER ) );
369 }
370
371 @Test
372 public void nothingParallel()
373 {
374 JUnitCore core = new JUnitCore();
375 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger );
376 assertFalse( builder.isOptimized() );
377
378 Result result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingTest2.class );
379 assertTrue( result.wasSuccessful() );
380
381 result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingSuite.class );
382 assertTrue( result.wasSuccessful() );
383
384 builder.useOnePool( 1 );
385 assertFalse( builder.isOptimized() );
386 result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingTest2.class );
387 assertTrue( result.wasSuccessful() );
388
389 builder.useOnePool( 1 );
390 assertFalse( builder.isOptimized() );
391 result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingSuite.class );
392 assertTrue( result.wasSuccessful() );
393
394 builder.useOnePool( 2 );
395 assertFalse( builder.isOptimized() );
396 result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingSuite.class );
397 assertTrue( result.wasSuccessful() );
398
399 Class<?>[] classes = { NothingDoingTest1.class, NothingDoingSuite.class };
400
401 builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses( 1 );
402 assertFalse( builder.isOptimized() );
403 result = core.run( builder.buildComputer(), classes );
404 assertTrue( result.wasSuccessful() );
405
406 builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses();
407 assertFalse( builder.isOptimized() );
408 result = core.run( builder.buildComputer(), classes );
409 assertTrue( result.wasSuccessful() );
410
411 classes = new Class<?>[]{ NothingDoingSuite.class, NothingDoingSuite.class, NothingDoingTest1.class,
412 NothingDoingTest2.class, NothingDoingTest3.class };
413
414 builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses( 1 );
415 assertFalse( builder.isOptimized() );
416 result = core.run( builder.buildComputer(), classes );
417 assertTrue( result.wasSuccessful() );
418
419 builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses();
420 assertFalse( builder.isOptimized() );
421 result = core.run( builder.buildComputer(), classes );
422 assertTrue( result.wasSuccessful() );
423 }
424
425 @Test
426 public void keepBeforeAfterOneClass()
427 {
428 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger );
429 builder.parallelMethods();
430 assertFalse( builder.isOptimized() );
431 testKeepBeforeAfter( builder, NothingDoingTest1.class );
432 }
433
434 @Test
435 public void keepBeforeAfterTwoClasses()
436 {
437 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger );
438 builder.useOnePool( 5 ).parallelClasses( 1 ).parallelMethods( 2 );
439 assertFalse( builder.isOptimized() );
440 testKeepBeforeAfter( builder, NothingDoingTest1.class, NothingDoingTest2.class );
441 }
442
443 @Test
444 public void keepBeforeAfterTwoParallelClasses()
445 {
446 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger );
447 builder.useOnePool( 8 ).parallelClasses( 2 ).parallelMethods( 2 );
448 assertFalse( builder.isOptimized() );
449 JUnitCore core = new JUnitCore();
450 NothingDoingTest1.methods.clear();
451 Class<?>[] classes = { NothingDoingTest1.class, NothingDoingTest2.class, NothingDoingTest3.class };
452 Result result = core.run( builder.buildComputer(), classes );
453 assertTrue( result.wasSuccessful() );
454 ArrayList<String> methods = new ArrayList<>( NothingDoingTest1.methods );
455 assertThat( methods.size(), is( 12 ) );
456 assertThat( methods.subList( 9, 12 ), is( not( Arrays.asList( "deinit", "deinit", "deinit" ) ) ) );
457 }
458
459 @Test
460 public void notThreadSafeTest()
461 {
462 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger )
463 .useOnePool( 6 ).optimize( true ).parallelClasses( 3 ).parallelMethods( 3 );
464 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) builder.buildComputer();
465 Result result = new JUnitCore().run( computer, NotThreadSafeTest1.class, NotThreadSafeTest2.class );
466 assertTrue( result.wasSuccessful() );
467 assertThat( result.getRunCount(), is( 2 ) );
468 assertNotNull( NotThreadSafeTest1.t );
469 assertNotNull( NotThreadSafeTest2.t );
470 assertSame( NotThreadSafeTest1.t, NotThreadSafeTest2.t );
471 assertThat( computer.getNotParallelRunners().size(), is( 2 ) );
472 assertTrue( computer.getSuites().isEmpty() );
473 assertTrue( computer.getClasses().isEmpty() );
474 assertTrue( computer.getNestedClasses().isEmpty() );
475 assertTrue( computer.getNestedSuites().isEmpty() );
476 assertFalse( computer.isSplitPool() );
477 assertThat( computer.getPoolCapacity(), is( 6 ) );
478 }
479
480 @Test
481 public void mixedThreadSafety()
482 {
483 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger )
484 .useOnePool( 6 ).optimize( true ).parallelClasses( 3 ).parallelMethods( 3 );
485 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) builder.buildComputer();
486 Result result = new JUnitCore().run( computer, NotThreadSafeTest1.class, NormalTest1.class );
487 assertTrue( result.wasSuccessful() );
488 assertThat( result.getRunCount(), is( 2 ) );
489 assertNotNull( NotThreadSafeTest1.t );
490 assertNotNull( NormalTest1.t );
491 assertThat( NormalTest1.t.getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
492 assertNotSame( NotThreadSafeTest1.t, NormalTest1.t );
493 assertThat( computer.getNotParallelRunners().size(), is( 1 ) );
494 assertTrue( computer.getSuites().isEmpty() );
495 assertThat( computer.getClasses().size(), is( 1 ) );
496 assertTrue( computer.getNestedClasses().isEmpty() );
497 assertTrue( computer.getNestedSuites().isEmpty() );
498 assertFalse( computer.isSplitPool() );
499 assertThat( computer.getPoolCapacity(), is( 6 ) );
500 }
501
502 @Test
503 public void notThreadSafeTestsInSuite()
504 {
505 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger )
506 .useOnePool( 5 ).parallelMethods( 3 );
507 assertFalse( builder.isOptimized() );
508 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) builder.buildComputer();
509 Result result = new JUnitCore().run( computer, NotThreadSafeTestSuite.class );
510 assertTrue( result.wasSuccessful() );
511 assertNotNull( NormalTest1.t );
512 assertNotNull( NormalTest2.t );
513 assertSame( NormalTest1.t, NormalTest2.t );
514 assertThat( NormalTest1.t.getName(), is( "maven-surefire-plugin@NotThreadSafe" ) );
515 assertThat( NormalTest2.t.getName(), is( "maven-surefire-plugin@NotThreadSafe" ) );
516 assertThat( computer.getNotParallelRunners().size(), is( 1 ) );
517 assertTrue( computer.getSuites().isEmpty() );
518 assertTrue( computer.getClasses().isEmpty() );
519 assertTrue( computer.getNestedClasses().isEmpty() );
520 assertTrue( computer.getNestedSuites().isEmpty() );
521 assertFalse( computer.isSplitPool() );
522 assertThat( computer.getPoolCapacity(), is( 5 ) );
523 }
524
525 @Test
526 public void mixedThreadSafetyInSuite()
527 {
528 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger )
529 .useOnePool( 10 ).optimize( true ).parallelSuites( 2 ).parallelClasses( 3 ).parallelMethods( 3 );
530 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) builder.buildComputer();
531 Result result = new JUnitCore().run( computer, MixedSuite.class );
532 assertTrue( result.wasSuccessful() );
533 assertThat( result.getRunCount(), is( 2 ) );
534 assertNotNull( NotThreadSafeTest1.t );
535 assertNotNull( NormalTest1.t );
536 assertThat( NormalTest1.t.getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
537 assertNotSame( NotThreadSafeTest1.t, NormalTest1.t );
538 assertTrue( computer.getNotParallelRunners().isEmpty() );
539 assertThat( computer.getSuites().size(), is( 1 ) );
540 assertTrue( computer.getClasses().isEmpty() );
541 assertThat( computer.getNestedClasses().size(), is( 1 ) );
542 assertTrue( computer.getNestedSuites().isEmpty() );
543 assertFalse( computer.isSplitPool() );
544 assertThat( computer.getPoolCapacity(), is( 10 ) );
545 }
546
547 @Test
548 public void inheritanceWithNotThreadSafe()
549 {
550 ParallelComputerBuilder builder = new ParallelComputerBuilder( logger )
551 .useOnePool( 10 ).optimize( true ).parallelSuites( 2 ).parallelClasses( 3 ).parallelMethods( 3 );
552 ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) builder.buildComputer();
553 Result result = new JUnitCore().run( computer, OverMixedSuite.class );
554 assertTrue( result.wasSuccessful() );
555 assertThat( result.getRunCount(), is( 2 ) );
556 assertNotNull( NotThreadSafeTest3.t );
557 assertNotNull( NormalTest1.t );
558 assertThat( NormalTest1.t.getName(), is( "maven-surefire-plugin@NotThreadSafe" ) );
559 assertSame( NotThreadSafeTest3.t, NormalTest1.t );
560 assertThat( computer.getNotParallelRunners().size(), is( 1 ) );
561 assertTrue( computer.getSuites().isEmpty() );
562 assertTrue( computer.getClasses().isEmpty() );
563 assertTrue( computer.getNestedClasses().isEmpty() );
564 assertTrue( computer.getNestedSuites().isEmpty() );
565 assertFalse( computer.isSplitPool() );
566 assertThat( computer.getPoolCapacity(), is( 10 ) );
567 }
568
569 @Test
570 public void beforeAfterThreadChanges()
571 throws InterruptedException
572 {
573
574 for ( int i = 0; i < 5; i++ )
575 {
576 System.gc();
577 TimeUnit.MILLISECONDS.sleep( 500L );
578 }
579 Collection<Thread> expectedThreads = jvmThreads();
580 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger );
581 parallelComputerBuilder.parallelMethods( 3 );
582 ParallelComputer computer = parallelComputerBuilder.buildComputer();
583 Result result = new JUnitCore().run( computer, TestWithBeforeAfter.class );
584 assertTrue( result.wasSuccessful() );
585
586 for ( int i = 0; i < 5 && expectedThreads.size() != jvmThreads().size(); i++ )
587 {
588 System.gc();
589 TimeUnit.MILLISECONDS.sleep( 500L );
590 }
591 assertThat( jvmThreads(), is( expectedThreads ) );
592 }
593
594 private static Collection<Thread> jvmThreads()
595 {
596 Thread[] t = new Thread[1000];
597 Thread.enumerate( t );
598 ArrayList<Thread> appThreads = new ArrayList<>( t.length );
599 Collections.addAll( appThreads, t );
600 appThreads.removeAll( Collections.singleton( (Thread) null ) );
601 Collections.sort( appThreads, new Comparator<Thread>()
602 {
603 @Override
604 public int compare( Thread t1, Thread t2 )
605 {
606 return (int) Math.signum( t1.getId() - t2.getId() );
607 }
608 } );
609 return appThreads;
610 }
611
612 private static class ShutdownTest
613 {
614 Result run( final boolean useInterrupt )
615 {
616 ParallelComputerBuilder parallelComputerBuilder = new ParallelComputerBuilder( logger )
617 .useOnePool( 8 )
618 .parallelSuites( 2 )
619 .parallelClasses( 3 )
620 .parallelMethods( 3 );
621
622 assertFalse( parallelComputerBuilder.isOptimized() );
623
624 final ParallelComputerBuilder.PC computer =
625 (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
626 shutdownTask = new Runnable()
627 {
628 @Override
629 public void run()
630 {
631 Collection<Description> startedTests = computer.describeStopped( useInterrupt ).getTriggeredTests();
632 assertThat( startedTests.size(), is( not( 0 ) ) );
633 }
634 };
635 return new JUnitCore().run( computer, TestSuite.class, Class2.class, Class3.class );
636 }
637 }
638
639 public static class Class1
640 {
641 static volatile int concurrentMethods = 0;
642
643 static volatile int maxConcurrentMethods = 0;
644
645 @Test
646 public void test1()
647 throws InterruptedException
648 {
649 synchronized ( class1Lock )
650 {
651 ++concurrentMethods;
652 class1Lock.wait( DELAY_MULTIPLIER * 500L );
653 maxConcurrentMethods = Math.max( maxConcurrentMethods, concurrentMethods-- );
654 }
655 }
656
657 @Test
658 public void test2()
659 throws InterruptedException
660 {
661 test1();
662 Runnable shutdownTask = ParallelComputerBuilderTest.shutdownTask;
663 if ( shutdownTask != null )
664 {
665 beforeShutdown = true;
666 shutdownTask.run();
667 }
668 }
669 }
670
671 public static class Class2
672 extends Class1
673 {
674 }
675
676 public static class Class3
677 extends Class1
678 {
679 }
680
681 public static class NothingDoingTest1
682 {
683 static final Collection<String> methods = new ConcurrentLinkedQueue<>();
684
685 @BeforeClass
686 public static void init()
687 {
688 methods.add( "init" );
689 }
690
691 @AfterClass
692 public static void deinit()
693 {
694 methods.add( "deinit" );
695 }
696
697 @Test
698 public void a()
699 throws InterruptedException
700 {
701 Thread.sleep( 5 );
702 methods.add( getClass().getName() + "#a()" );
703 }
704
705 @Test
706 public void b()
707 throws InterruptedException
708 {
709 Thread.sleep( 5 );
710 methods.add( getClass().getName() + "#b()" );
711 }
712 }
713
714 public static class NothingDoingTest2
715 extends NothingDoingTest1
716 {
717 }
718
719 public static class NothingDoingTest3
720 extends NothingDoingTest1
721 {
722 }
723
724 @RunWith( Suite.class )
725 @Suite.SuiteClasses( { NothingDoingTest1.class, NothingDoingTest2.class } )
726 public static class NothingDoingSuite
727 {
728 }
729
730 @RunWith( Suite.class )
731 @Suite.SuiteClasses( { Class2.class, Class1.class } )
732 public static class TestSuite
733 {
734 }
735
736 public static class Test2
737 {
738 @Test
739 public void test()
740 {
741
742 }
743 }
744
745 @RunWith( ReportOneTestAtRuntimeRunner.class )
746 public static class TestWithoutPrecalculatedChildren {}
747
748 public static class ReportOneTestAtRuntimeRunner
749 extends ParentRunner
750 {
751 private final Class<?> testClass;
752 private final Description suiteDescription;
753 private final Description myTestMethodDescr;
754
755 @SuppressWarnings( "unchecked" )
756 public ReportOneTestAtRuntimeRunner( Class<?> testClass ) throws InitializationError
757 {
758 super( Object.class );
759 this.testClass = testClass;
760 suiteDescription = Description.createSuiteDescription( testClass );
761 myTestMethodDescr = Description.createTestDescription( testClass, "my_test" );
762
763 }
764
765 protected List getChildren()
766 {
767 throw new UnsupportedOperationException( "workflow from ParentRunner not supported" );
768 }
769
770 protected Description describeChild( Object child )
771 {
772 throw new UnsupportedOperationException( "workflow from ParentRunner not supported" );
773 }
774
775 protected void runChild( Object child, RunNotifier notifier )
776 {
777 throw new UnsupportedOperationException( "workflow from ParentRunner not supported" );
778 }
779
780 public Description getDescription()
781 {
782 return suiteDescription;
783 }
784
785 public void run( RunNotifier notifier )
786 {
787 notifier.fireTestStarted( myTestMethodDescr );
788 notifier.fireTestFinished( Description.createTestDescription( testClass, "my_test" ) );
789 }
790 }
791
792 @NotThreadSafe
793 public static class NotThreadSafeTest1
794 {
795 static volatile Thread t;
796
797 @BeforeClass
798 public static void beforeSuite()
799 {
800 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
801 }
802
803 @AfterClass
804 public static void afterSuite()
805 {
806 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
807 }
808
809 @Test
810 public void test()
811 {
812 t = Thread.currentThread();
813 assertThat( t.getName(), is( "maven-surefire-plugin@NotThreadSafe" ) );
814 }
815 }
816
817 @NotThreadSafe
818 public static class NotThreadSafeTest2
819 {
820 static volatile Thread t;
821
822 @BeforeClass
823 public static void beforeSuite()
824 {
825 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
826 }
827
828 @AfterClass
829 public static void afterSuite()
830 {
831 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
832 }
833
834 @Test
835 public void test()
836 {
837 t = Thread.currentThread();
838 assertThat( t.getName(), is( "maven-surefire-plugin@NotThreadSafe" ) );
839 }
840 }
841
842 @NotThreadSafe
843 public static class NotThreadSafeTest3
844 {
845 static volatile Thread t;
846
847 @Test
848 public void test()
849 {
850 t = Thread.currentThread();
851 assertThat( t.getName(), is( "maven-surefire-plugin@NotThreadSafe" ) );
852 }
853 }
854
855 @RunWith( Suite.class )
856 @Suite.SuiteClasses( { NormalTest1.class, NormalTest2.class } )
857 @NotThreadSafe
858 public static class NotThreadSafeTestSuite
859 {
860 @BeforeClass
861 public static void beforeSuite()
862 {
863 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
864 }
865
866 @AfterClass
867 public static void afterSuite()
868 {
869 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
870 }
871 }
872
873 public static class NormalTest1
874 {
875 static volatile Thread t;
876
877 @Test
878 public void test()
879 {
880 t = Thread.currentThread();
881 }
882 }
883
884 public static class NormalTest2
885 {
886 static volatile Thread t;
887
888 @Test
889 public void test()
890 {
891 t = Thread.currentThread();
892 }
893 }
894
895 @RunWith( Suite.class )
896 @Suite.SuiteClasses( { NotThreadSafeTest1.class, NormalTest1.class } )
897 public static class MixedSuite
898 {
899 @BeforeClass
900 public static void beforeSuite()
901 {
902 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
903 }
904
905 @AfterClass
906 public static void afterSuite()
907 {
908 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
909 }
910 }
911
912 @RunWith( Suite.class )
913 @Suite.SuiteClasses( { NotThreadSafeTest3.class, NormalTest1.class } )
914 @NotThreadSafe
915 public static class OverMixedSuite
916 {
917 @BeforeClass
918 public static void beforeSuite()
919 {
920 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
921 }
922
923 @AfterClass
924 public static void afterSuite()
925 {
926 assertThat( Thread.currentThread().getName(), is( not( "maven-surefire-plugin@NotThreadSafe" ) ) );
927 }
928 }
929
930 public static class TestWithBeforeAfter
931 {
932 @BeforeClass
933 public static void beforeClass()
934 throws InterruptedException
935 {
936 System.out.println( new Date() + " BEG: beforeClass" );
937 sleepSeconds( 1 );
938 System.out.println( new Date() + " END: beforeClass" );
939 }
940
941 @Before
942 public void before()
943 throws InterruptedException
944 {
945 System.out.println( new Date() + " BEG: before" );
946 sleepSeconds( 1 );
947 System.out.println( new Date() + " END: before" );
948 }
949
950 @Test
951 public void test()
952 throws InterruptedException
953 {
954 System.out.println( new Date() + " BEG: test" );
955 sleepSeconds( 1 );
956 System.out.println( new Date() + " END: test" );
957 }
958
959 @After
960 public void after()
961 throws InterruptedException
962 {
963 System.out.println( new Date() + " BEG: after" );
964 sleepSeconds( 1 );
965 System.out.println( new Date() + " END: after" );
966 }
967
968 @AfterClass
969 public static void afterClass()
970 throws InterruptedException
971 {
972 System.out.println( new Date() + " BEG: afterClass" );
973 sleepSeconds( 1 );
974 System.out.println( new Date() + " END: afterClass" );
975 }
976 }
977
978 private static long systemMillis()
979 {
980 return TimeUnit.NANOSECONDS.toMillis( System.nanoTime() );
981 }
982
983 private static void sleepSeconds( int seconds )
984 throws InterruptedException
985 {
986 TimeUnit.SECONDS.sleep( seconds );
987 }
988 }