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