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