• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.
7  *
8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  */
22 
23 /*
24  * This file is available under and governed by the GNU General Public
25  * License version 2 only, as published by the Free Software Foundation.
26  * However, the following notice accompanied the original version of this
27  * file:
28  *
29  * Written by Doug Lea with assistance from members of JCP JSR-166
30  * Expert Group and released to the public domain, as explained at
31  * http://creativecommons.org/publicdomain/zero/1.0/
32  */
33 
34 package test.java.util.concurrent.tck;
35 
36 import static java.util.concurrent.TimeUnit.MILLISECONDS;
37 import static org.junit.Assert.assertEquals;
38 import static org.junit.Assert.assertFalse;
39 import static org.junit.Assert.assertNull;
40 import static org.junit.Assert.assertSame;
41 import static org.junit.Assert.assertTrue;
42 
43 import java.util.HashSet;
44 import java.util.concurrent.CancellationException;
45 import java.util.concurrent.CountedCompleter;
46 import java.util.concurrent.ExecutionException;
47 import java.util.concurrent.ForkJoinPool;
48 import java.util.concurrent.ForkJoinTask;
49 import java.util.concurrent.RecursiveAction;
50 import java.util.concurrent.TimeoutException;
51 import java.util.concurrent.Callable;
52 
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.junit.runners.JUnit4;
56 
57 /**
58  * Tests for ForkJoinPool and corresponding ForkJoinTask additions.
59  */
60 // Android-changed: Use JUnit4.
61 @RunWith(JUnit4.class)
62 public class ForkJoinPool19Test extends JSR166TestCase {
63     // Android-changed: Use JUnitCore.main.
main(String[] args)64     public static void main(String[] args) {
65         // main(suite(), args);
66         org.junit.runner.JUnitCore.main("test.java.util.concurrent.tck.ForkJoinPool19Test");
67     }
68 
69     // public static Test suite() {
70     //     return new TestSuite(ForkJoinPool19Test.class);
71     // }
72 
73     /**
74      * SetParallelism sets reported parallellism and returns previous value
75      */
76     @Test
testSetParallelism()77     public void testSetParallelism() {
78         final ForkJoinPool p = new ForkJoinPool(2);
79         assertEquals(2, p.getParallelism());
80         assertEquals(2, p.setParallelism(3));
81         assertEquals(3, p.setParallelism(2));
82         p.shutdown();
83     }
84     /**
85      * SetParallelism throws exception if argument out of bounds
86      */
87     @Test
testSetParallelismBadArgs()88     public void testSetParallelismBadArgs() {
89         final ForkJoinPool p = new ForkJoinPool(2);
90         try {
91             p.setParallelism(0);
92             shouldThrow();
93         } catch (Exception success) {
94         }
95         try {
96             p.setParallelism(Integer.MAX_VALUE);
97             shouldThrow();
98         } catch (Exception success) {
99         }
100         assertEquals(2, p.getParallelism());
101         p.shutdown();
102     }
103 
104 
105     /*
106      * Some test methods adapted from RecursiveAction
107      */
mainPool()108     private static ForkJoinPool mainPool() {
109         return new ForkJoinPool();
110     }
111 
testInvokeOnPool(ForkJoinPool pool, RecursiveAction a)112     private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
113         try (PoolCleaner cleaner = cleaner(pool)) {
114             checkNotDone(a);
115             assertNull(pool.invoke(a));
116             checkCompletedNormally(a);
117         }
118     }
119 
checkInvoke(ForkJoinTask<?> a)120     private void checkInvoke(ForkJoinTask<?> a) {
121         checkNotDone(a);
122         assertNull(a.invoke());
123         checkCompletedNormally(a);
124     }
125 
checkNotDone(ForkJoinTask<?> a)126     void checkNotDone(ForkJoinTask<?> a) {
127         assertFalse(a.isDone());
128         assertFalse(a.isCompletedNormally());
129         assertFalse(a.isCompletedAbnormally());
130         assertFalse(a.isCancelled());
131         assertNull(a.getException());
132         assertNull(a.getRawResult());
133 
134         if (! ForkJoinTask.inForkJoinPool()) {
135             Thread.currentThread().interrupt();
136             try {
137                 a.get();
138                 shouldThrow();
139             } catch (InterruptedException success) {
140             } catch (Throwable fail) { threadUnexpectedException(fail); }
141 
142             Thread.currentThread().interrupt();
143             try {
144                 a.get(randomTimeout(), randomTimeUnit());
145                 shouldThrow();
146             } catch (InterruptedException success) {
147             } catch (Throwable fail) { threadUnexpectedException(fail); }
148         }
149 
150         try {
151             a.get(randomExpiredTimeout(), randomTimeUnit());
152             shouldThrow();
153         } catch (TimeoutException success) {
154         } catch (Throwable fail) { threadUnexpectedException(fail); }
155     }
156 
checkCompletedNormally(ForkJoinTask<?> a)157     void checkCompletedNormally(ForkJoinTask<?> a) {
158         assertTrue(a.isDone());
159         assertFalse(a.isCancelled());
160         assertTrue(a.isCompletedNormally());
161         assertFalse(a.isCompletedAbnormally());
162         assertNull(a.getException());
163         assertNull(a.getRawResult());
164         assertNull(a.join());
165         assertFalse(a.cancel(false));
166         assertFalse(a.cancel(true));
167 
168         Object v1 = null, v2 = null;
169         try {
170             v1 = a.get();
171             v2 = a.get(randomTimeout(), randomTimeUnit());
172         } catch (Throwable fail) { threadUnexpectedException(fail); }
173         assertNull(v1);
174         assertNull(v2);
175     }
176 
checkCancelled(ForkJoinTask<?> a)177     void checkCancelled(ForkJoinTask<?> a) {
178         assertTrue(a.isDone());
179         assertTrue(a.isCancelled());
180         assertFalse(a.isCompletedNormally());
181         assertTrue(a.isCompletedAbnormally());
182         assertTrue(a.getException() instanceof CancellationException);
183         assertNull(a.getRawResult());
184 
185         try {
186             a.join();
187             shouldThrow();
188         } catch (CancellationException success) {
189         } catch (Throwable fail) { threadUnexpectedException(fail); }
190 
191         try {
192             a.get();
193             shouldThrow();
194         } catch (CancellationException success) {
195         } catch (Throwable fail) { threadUnexpectedException(fail); }
196 
197         try {
198             a.get(randomTimeout(), randomTimeUnit());
199             shouldThrow();
200         } catch (CancellationException success) {
201         } catch (Throwable fail) { threadUnexpectedException(fail); }
202     }
203 
checkCompletedAbnormally(ForkJoinTask<?> a, Throwable t)204     void checkCompletedAbnormally(ForkJoinTask<?> a, Throwable t) {
205         assertTrue(a.isDone());
206         assertFalse(a.isCancelled());
207         assertFalse(a.isCompletedNormally());
208         assertTrue(a.isCompletedAbnormally());
209         assertSame(t.getClass(), a.getException().getClass());
210         assertNull(a.getRawResult());
211         assertFalse(a.cancel(false));
212         assertFalse(a.cancel(true));
213 
214         try {
215             a.join();
216             shouldThrow();
217         } catch (Throwable expected) {
218             assertSame(expected.getClass(), t.getClass());
219         }
220 
221         try {
222             a.get();
223             shouldThrow();
224         } catch (ExecutionException success) {
225             assertSame(t.getClass(), success.getCause().getClass());
226         } catch (Throwable fail) { threadUnexpectedException(fail); }
227 
228         try {
229             a.get(randomTimeout(), randomTimeUnit());
230             shouldThrow();
231         } catch (ExecutionException success) {
232             assertSame(t.getClass(), success.getCause().getClass());
233         } catch (Throwable fail) { threadUnexpectedException(fail); }
234     }
235 
236     public static final class FJException extends RuntimeException {
FJException()237         public FJException() { super(); }
FJException(Throwable cause)238         public FJException(Throwable cause) { super(cause); }
239     }
240 
241     /** A simple recursive action for testing. */
242     final class FibAction extends CheckedRecursiveAction {
243         final int number;
244         int result;
FibAction(int n)245         FibAction(int n) { number = n; }
realCompute()246         protected void realCompute() {
247             int n = number;
248             if (n <= 1)
249                 result = n;
250             else {
251                 FibAction f1 = new FibAction(n - 1);
252                 FibAction f2 = new FibAction(n - 2);
253                 invokeAll(f1, f2);
254                 result = f1.result + f2.result;
255             }
256         }
257     }
258 
259     /** A recursive action failing in base case. */
260     static final class FailingFibAction extends RecursiveAction {
261         final int number;
262         int result;
FailingFibAction(int n)263         FailingFibAction(int n) { number = n; }
compute()264         public void compute() {
265             int n = number;
266             if (n <= 1)
267                 throw new FJException();
268             else {
269                 FailingFibAction f1 = new FailingFibAction(n - 1);
270                 FailingFibAction f2 = new FailingFibAction(n - 2);
271                 invokeAll(f1, f2);
272                 result = f1.result + f2.result;
273             }
274         }
275     }
276 
277     /**
278      * lazySubmit submits a task that is not executed until new
279      * workers are created or it is explicitly joined by a worker.
280      */
281     @SuppressWarnings("removal")
282     @Test
testLazySubmit()283     public void testLazySubmit() {
284         ForkJoinPool p;
285         try {
286             p = new ForkJoinPool();
287         } catch (java.security.AccessControlException e) {
288             return;
289         }
290         FibAction f = new FibAction(8);
291         RecursiveAction j = new RecursiveAction() {
292                 protected void compute() {
293                     f.join();
294                 }};
295         RecursiveAction a = new CheckedRecursiveAction() {
296             protected void realCompute() {
297                 p.invoke(new FibAction(8));
298                 p.lazySubmit(f);
299                 p.invoke(new FibAction(8));
300                 p.invoke(j);
301                 assertEquals(21, f.result);
302                 checkCompletedNormally(f);
303             }};
304         testInvokeOnPool(p, a);
305     }
306 
307     /**
308      * quietlyInvoke task returns when task completes normally.
309      * isCompletedAbnormally and isCancelled return false for normally
310      * completed tasks
311      */
312     @Test
testQuietlyInvoke()313     public void testQuietlyInvoke() {
314         RecursiveAction a = new CheckedRecursiveAction() {
315             protected void realCompute() {
316                 FibAction f = new FibAction(8);
317                 f.quietlyInvoke();
318                 assertEquals(21, f.result);
319                 checkCompletedNormally(f);
320             }};
321         checkInvoke(a);
322     }
323 
324     /**
325      * join of a forked task returns when task completes
326      */
327     @Test
testForkJoin()328     public void testForkJoin() {
329         RecursiveAction a = new CheckedRecursiveAction() {
330             protected void realCompute() {
331                 FibAction f = new FibAction(8);
332                 assertSame(f, f.fork());
333                 assertNull(f.join());
334                 assertEquals(21, f.result);
335                 checkCompletedNormally(f);
336             }};
337         checkInvoke(a);
338     }
339 
340     /**
341      * timed quietlyJoinUninterruptibly of a forked task succeeds in
342      * the presence of interrupts
343      */
344     @Test
testTimedQuietlyJoinUninterruptiblyInterrupts()345     public void testTimedQuietlyJoinUninterruptiblyInterrupts() {
346         RecursiveAction a = new CheckedRecursiveAction() {
347             protected void realCompute() {
348                 FibAction f;
349                 final Thread currentThread = Thread.currentThread();
350 
351                 // test quietlyJoin()
352                 f = new FibAction(8);
353                 assertSame(f, f.fork());
354                 currentThread.interrupt();
355                 f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
356                 Thread.interrupted();
357                 assertEquals(21, f.result);
358                 checkCompletedNormally(f);
359 
360                 f = new FibAction(8);
361                 f.cancel(true);
362                 assertSame(f, f.fork());
363                 currentThread.interrupt();
364                 f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
365                 Thread.interrupted();
366                 checkCancelled(f);
367 
368                 f = new FibAction(8);
369                 f.completeExceptionally(new FJException());
370                 assertSame(f, f.fork());
371                 currentThread.interrupt();
372                 f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
373                 Thread.interrupted();
374                 checkCompletedAbnormally(f, f.getException());
375             }};
376         checkInvoke(a);
377         a.reinitialize();
378         checkInvoke(a);
379     }
380 
381     /**
382      * timed quietlyJoin throws IE in the presence of interrupts
383      */
384     @Test
testTimedQuietlyJoinInterrupts()385     public void testTimedQuietlyJoinInterrupts() {
386         RecursiveAction a = new CheckedRecursiveAction() {
387             protected void realCompute() {
388                 FibAction f;
389                 final Thread currentThread = Thread.currentThread();
390 
391                 f = new FibAction(8);
392                 assertSame(f, f.fork());
393                 currentThread.interrupt();
394                 try {
395                     f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS);
396                 } catch (InterruptedException success) {
397                 }
398                 Thread.interrupted();
399                 f.quietlyJoin();
400 
401                 f = new FibAction(8);
402                 f.cancel(true);
403                 assertSame(f, f.fork());
404                 currentThread.interrupt();
405                 try {
406                     f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS);
407                 } catch (InterruptedException success) {
408                 }
409                 f.quietlyJoin();
410                 checkCancelled(f);
411             }};
412         checkInvoke(a);
413         a.reinitialize();
414         checkInvoke(a);
415     }
416 
417     /**
418      * timed quietlyJoin of a forked task returns when task completes
419      */
420     @Test
testForkTimedQuietlyJoin()421     public void testForkTimedQuietlyJoin() {
422         RecursiveAction a = new CheckedRecursiveAction() {
423             protected void realCompute() throws Exception {
424                 FibAction f = new FibAction(8);
425                 assertSame(f, f.fork());
426                 assertTrue(f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS));
427                 assertEquals(21, f.result);
428                 checkCompletedNormally(f);
429             }};
430         checkInvoke(a);
431     }
432 
433     /**
434      * timed quietlyJoin with null time unit throws NPE
435      */
436     @Test
testForkTimedQuietlyJoinNPE()437     public void testForkTimedQuietlyJoinNPE() {
438         RecursiveAction a = new CheckedRecursiveAction() {
439             protected void realCompute() throws Exception {
440                 FibAction f = new FibAction(8);
441                 assertSame(f, f.fork());
442                 try {
443                     f.quietlyJoin(randomTimeout(), null);
444                     shouldThrow();
445                 } catch (NullPointerException success) {}
446             }};
447         checkInvoke(a);
448     }
449 
450     /**
451      * quietlyInvoke task returns when task completes abnormally
452      */
453     @Test
testAbnormalTimedQuietlyJoin()454     public void testAbnormalTimedQuietlyJoin() {
455         RecursiveAction a = new CheckedRecursiveAction() {
456             protected void realCompute() throws Exception {
457                 FailingFibAction f = new FailingFibAction(8);
458                 assertSame(f, f.fork());
459                 assertTrue(f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS));
460                 assertTrue(f.getException() instanceof FJException);
461                 checkCompletedAbnormally(f, f.getException());
462             }};
463         checkInvoke(a);
464     }
465 
466     /**
467      * timed quietlyJoinUninterruptibly of a forked task returns when task completes
468      */
469     @Test
testForkTimedQuietlyJoinUninterruptibly()470     public void testForkTimedQuietlyJoinUninterruptibly() {
471         RecursiveAction a = new CheckedRecursiveAction() {
472             protected void realCompute() throws Exception {
473                 FibAction f = new FibAction(8);
474                 assertSame(f, f.fork());
475                 assertTrue(f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS));
476                 assertEquals(21, f.result);
477                 checkCompletedNormally(f);
478             }};
479         checkInvoke(a);
480     }
481 
482     /**
483      * timed quietlyJoinUninterruptibly with null time unit throws NPE
484      */
485     @Test
testForkTimedQuietlyJoinUninterruptiblyNPE()486     public void testForkTimedQuietlyJoinUninterruptiblyNPE() {
487         RecursiveAction a = new CheckedRecursiveAction() {
488             protected void realCompute() throws Exception {
489                 FibAction f = new FibAction(8);
490                 assertSame(f, f.fork());
491                 try {
492                     f.quietlyJoinUninterruptibly(randomTimeout(), null);
493                     shouldThrow();
494                 } catch (NullPointerException success) {}
495             }};
496         checkInvoke(a);
497     }
498 
499     /**
500      * quietlyInvoke task returns when task completes abnormally
501      */
502     @Test
testAbnormalTimedQuietlyJoinUninterruptibly()503     public void testAbnormalTimedQuietlyJoinUninterruptibly() {
504         RecursiveAction a = new CheckedRecursiveAction() {
505             protected void realCompute() {
506                 FailingFibAction f = new FailingFibAction(8);
507                 assertSame(f, f.fork());
508                 assertTrue(f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS));
509                 assertTrue(f.getException() instanceof FJException);
510                 checkCompletedAbnormally(f, f.getException());
511             }};
512         checkInvoke(a);
513     }
514 
515     /**
516      * adaptInterruptible(callable).toString() contains toString of wrapped task
517      */
518     @Test
testAdaptInterruptible_Callable_toString()519     public void testAdaptInterruptible_Callable_toString() {
520         if (testImplementationDetails) {
521             Callable<String> c = () -> "";
522             ForkJoinTask<String> task = ForkJoinTask.adaptInterruptible(c);
523             assertEquals(
524                 identityString(task) + "[Wrapped task = " + c.toString() + "]",
525                 task.toString());
526         }
527     }
528 
529     /**
530      * Implicitly closing a new pool using try-with-resources terminates it
531      */
532     @Test
testClose()533     public void testClose() {
534         ForkJoinTask f = new FibAction(8);
535         ForkJoinPool pool = null;
536         try (ForkJoinPool p = new ForkJoinPool()) {
537             pool = p;
538             p.execute(f);
539         }
540         checkCompletedNormally(f);
541         assertTrue(pool != null && pool.isTerminated());
542     }
543 
544     /**
545      * Implicitly closing common pool using try-with-resources has no effect.
546      */
547     @Test
testCloseCommonPool()548     public void testCloseCommonPool() {
549         ForkJoinTask f = new FibAction(8);
550         ForkJoinPool pool;
551         try (ForkJoinPool p = pool = ForkJoinPool.commonPool()) {
552             p.execute(f);
553         }
554 
555         assertFalse(pool.isShutdown());
556         assertFalse(pool.isTerminating());
557         assertFalse(pool.isTerminated());
558 
559         String prop = System.getProperty(
560             "java.util.concurrent.ForkJoinPool.common.parallelism");
561         if (! "0".equals(prop)) {
562             f.join();
563             checkCompletedNormally(f);
564         }
565     }
566 
567 }
568