ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinPool19Test.java
Revision: 1.3
Committed: Fri Nov 25 16:39:48 2022 UTC (17 months, 3 weeks ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +2 -1 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/publicdomain/zero/1.0/
5     */
6    
7     import static java.util.concurrent.TimeUnit.MILLISECONDS;
8    
9     import java.util.HashSet;
10     import java.util.concurrent.CancellationException;
11     import java.util.concurrent.CountedCompleter;
12     import java.util.concurrent.ExecutionException;
13     import java.util.concurrent.ForkJoinPool;
14     import java.util.concurrent.ForkJoinTask;
15     import java.util.concurrent.RecursiveAction;
16     import java.util.concurrent.TimeoutException;
17     import java.util.concurrent.Callable;
18    
19     import junit.framework.Test;
20     import junit.framework.TestSuite;
21    
22     /**
23     * Tests for ForkJoinPool and corresponding ForkJoinTask additions.
24     */
25     public class ForkJoinPool19Test extends JSR166TestCase {
26     public static void main(String[] args) {
27     main(suite(), args);
28     }
29    
30     public static Test suite() {
31     return new TestSuite(ForkJoinPool8Test.class);
32     }
33    
34     /**
35     * SetParallelism sets reported parallellism and returns previous value
36     */
37     public void testSetParallelism() {
38     final ForkJoinPool p = new ForkJoinPool(2);
39     assertEquals(2, p.getParallelism());
40     assertEquals(2, p.setParallelism(3));
41     assertEquals(3, p.setParallelism(2));
42     p.shutdown();
43     }
44 jsr166 1.3
45 dl 1.1 /**
46     * SetParallelism throws exception if argument out of bounds
47     */
48     public void testSetParallelismBadArgs() {
49     final ForkJoinPool p = new ForkJoinPool(2);
50     try {
51     p.setParallelism(0);
52     shouldThrow();
53     } catch (Exception success) {
54     }
55     try {
56     p.setParallelism(Integer.MAX_VALUE);
57     shouldThrow();
58     } catch (Exception success) {
59     }
60     assertEquals(2, p.getParallelism());
61     p.shutdown();
62     }
63    
64 jsr166 1.3
65 dl 1.1 /*
66     * Some test methods adapted from RecursiveAction
67     */
68     private static ForkJoinPool mainPool() {
69     return new ForkJoinPool();
70     }
71    
72     private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
73     try (PoolCleaner cleaner = cleaner(pool)) {
74     checkNotDone(a);
75     assertNull(pool.invoke(a));
76     checkCompletedNormally(a);
77     }
78     }
79    
80     private void checkInvoke(ForkJoinTask<?> a) {
81     checkNotDone(a);
82     assertNull(a.invoke());
83     checkCompletedNormally(a);
84     }
85    
86     void checkNotDone(ForkJoinTask<?> a) {
87     assertFalse(a.isDone());
88     assertFalse(a.isCompletedNormally());
89     assertFalse(a.isCompletedAbnormally());
90     assertFalse(a.isCancelled());
91     assertNull(a.getException());
92     assertNull(a.getRawResult());
93    
94     if (! ForkJoinTask.inForkJoinPool()) {
95     Thread.currentThread().interrupt();
96     try {
97     a.get();
98     shouldThrow();
99     } catch (InterruptedException success) {
100     } catch (Throwable fail) { threadUnexpectedException(fail); }
101    
102     Thread.currentThread().interrupt();
103     try {
104     a.get(randomTimeout(), randomTimeUnit());
105     shouldThrow();
106     } catch (InterruptedException success) {
107     } catch (Throwable fail) { threadUnexpectedException(fail); }
108     }
109    
110     try {
111     a.get(randomExpiredTimeout(), randomTimeUnit());
112     shouldThrow();
113     } catch (TimeoutException success) {
114     } catch (Throwable fail) { threadUnexpectedException(fail); }
115     }
116    
117     void checkCompletedNormally(ForkJoinTask<?> a) {
118     assertTrue(a.isDone());
119     assertFalse(a.isCancelled());
120     assertTrue(a.isCompletedNormally());
121     assertFalse(a.isCompletedAbnormally());
122     assertNull(a.getException());
123     assertNull(a.getRawResult());
124     assertNull(a.join());
125     assertFalse(a.cancel(false));
126     assertFalse(a.cancel(true));
127    
128     Object v1 = null, v2 = null;
129     try {
130     v1 = a.get();
131     v2 = a.get(randomTimeout(), randomTimeUnit());
132     } catch (Throwable fail) { threadUnexpectedException(fail); }
133     assertNull(v1);
134     assertNull(v2);
135     }
136    
137     void checkCancelled(ForkJoinTask<?> a) {
138     assertTrue(a.isDone());
139     assertTrue(a.isCancelled());
140     assertFalse(a.isCompletedNormally());
141     assertTrue(a.isCompletedAbnormally());
142     assertTrue(a.getException() instanceof CancellationException);
143     assertNull(a.getRawResult());
144    
145     try {
146     a.join();
147     shouldThrow();
148     } catch (CancellationException success) {
149     } catch (Throwable fail) { threadUnexpectedException(fail); }
150    
151     try {
152     a.get();
153     shouldThrow();
154     } catch (CancellationException success) {
155     } catch (Throwable fail) { threadUnexpectedException(fail); }
156    
157     try {
158     a.get(randomTimeout(), randomTimeUnit());
159     shouldThrow();
160     } catch (CancellationException success) {
161     } catch (Throwable fail) { threadUnexpectedException(fail); }
162     }
163    
164     void checkCompletedAbnormally(ForkJoinTask<?> a, Throwable t) {
165     assertTrue(a.isDone());
166     assertFalse(a.isCancelled());
167     assertFalse(a.isCompletedNormally());
168     assertTrue(a.isCompletedAbnormally());
169     assertSame(t.getClass(), a.getException().getClass());
170     assertNull(a.getRawResult());
171     assertFalse(a.cancel(false));
172     assertFalse(a.cancel(true));
173    
174     try {
175     a.join();
176     shouldThrow();
177     } catch (Throwable expected) {
178     assertSame(expected.getClass(), t.getClass());
179     }
180    
181     try {
182     a.get();
183     shouldThrow();
184     } catch (ExecutionException success) {
185     assertSame(t.getClass(), success.getCause().getClass());
186     } catch (Throwable fail) { threadUnexpectedException(fail); }
187    
188     try {
189     a.get(randomTimeout(), randomTimeUnit());
190     shouldThrow();
191     } catch (ExecutionException success) {
192     assertSame(t.getClass(), success.getCause().getClass());
193     } catch (Throwable fail) { threadUnexpectedException(fail); }
194     }
195    
196     public static final class FJException extends RuntimeException {
197     public FJException() { super(); }
198     public FJException(Throwable cause) { super(cause); }
199     }
200    
201     /** A simple recursive action for testing. */
202     final class FibAction extends CheckedRecursiveAction {
203     final int number;
204     int result;
205     FibAction(int n) { number = n; }
206     protected void realCompute() {
207     int n = number;
208     if (n <= 1)
209     result = n;
210     else {
211     FibAction f1 = new FibAction(n - 1);
212     FibAction f2 = new FibAction(n - 2);
213     invokeAll(f1, f2);
214     result = f1.result + f2.result;
215     }
216     }
217     }
218    
219     /** A recursive action failing in base case. */
220     static final class FailingFibAction extends RecursiveAction {
221     final int number;
222     int result;
223     FailingFibAction(int n) { number = n; }
224     public void compute() {
225     int n = number;
226     if (n <= 1)
227     throw new FJException();
228     else {
229     FailingFibAction f1 = new FailingFibAction(n - 1);
230     FailingFibAction f2 = new FailingFibAction(n - 2);
231     invokeAll(f1, f2);
232     result = f1.result + f2.result;
233     }
234     }
235     }
236    
237     /**
238     * lazySubmit submits a task that is not executed until new
239     * workers are created or it is explicitly joined by a worker.
240     */
241     public void testLazySubmit() {
242     RecursiveAction a = new CheckedRecursiveAction() {
243     protected void realCompute() {
244     final ForkJoinPool p = mainPool();
245     FibAction f = new FibAction(8);
246     p.lazySubmit(f);
247     checkNotDone(f);
248     FibAction g = new FibAction(8);
249     p.submit(g);
250     g.join();
251     f.join();
252     assertEquals(21, f.result);
253     checkCompletedNormally(f);
254     }};
255     testInvokeOnPool(mainPool(), a);
256     }
257    
258     /**
259     * quietlyInvoke task returns when task completes normally.
260     * isCompletedAbnormally and isCancelled return false for normally
261     * completed tasks
262     */
263     public void testQuietlyInvoke() {
264     RecursiveAction a = new CheckedRecursiveAction() {
265     protected void realCompute() {
266     FibAction f = new FibAction(8);
267     f.quietlyInvoke();
268     assertEquals(21, f.result);
269     checkCompletedNormally(f);
270     }};
271     checkInvoke(a);
272     }
273    
274     /**
275     * join of a forked task returns when task completes
276     */
277     public void testForkJoin() {
278     RecursiveAction a = new CheckedRecursiveAction() {
279     protected void realCompute() {
280     FibAction f = new FibAction(8);
281     assertSame(f, f.fork());
282     assertNull(f.join());
283     assertEquals(21, f.result);
284     checkCompletedNormally(f);
285     }};
286     checkInvoke(a);
287     }
288    
289     /**
290     * timed quietlyJoinUninterruptibly of a forked task succeeds in
291     * the presence of interrupts
292     */
293     public void testTimedQuietlyJoinUninterruptiblyInterrupts() {
294     RecursiveAction a = new CheckedRecursiveAction() {
295     protected void realCompute() {
296     FibAction f;
297     final Thread currentThread = Thread.currentThread();
298    
299     // test quietlyJoin()
300     f = new FibAction(8);
301     assertSame(f, f.fork());
302     currentThread.interrupt();
303     f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
304     Thread.interrupted();
305     assertEquals(21, f.result);
306     checkCompletedNormally(f);
307    
308     f = new FibAction(8);
309     f.cancel(true);
310     assertSame(f, f.fork());
311     currentThread.interrupt();
312     f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
313     Thread.interrupted();
314     checkCancelled(f);
315    
316     f = new FibAction(8);
317     f.completeExceptionally(new FJException());
318     assertSame(f, f.fork());
319     currentThread.interrupt();
320     f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
321     Thread.interrupted();
322     checkCompletedAbnormally(f, f.getException());
323     }};
324     checkInvoke(a);
325     a.reinitialize();
326     checkInvoke(a);
327     }
328    
329     /**
330     * timed quietlyJoin throws IE in the presence of interrupts
331     */
332     public void testTimedQuietlyJoinInterrupts() {
333     RecursiveAction a = new CheckedRecursiveAction() {
334     protected void realCompute() {
335     FibAction f;
336     final Thread currentThread = Thread.currentThread();
337    
338     f = new FibAction(8);
339     assertSame(f, f.fork());
340     currentThread.interrupt();
341     try {
342     f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS);
343     } catch (InterruptedException success) {
344     }
345     Thread.interrupted();
346     f.quietlyJoin();
347    
348     f = new FibAction(8);
349     f.cancel(true);
350     assertSame(f, f.fork());
351     currentThread.interrupt();
352     try {
353     f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS);
354     } catch (InterruptedException success) {
355     }
356     f.quietlyJoin();
357     checkCancelled(f);
358     }};
359     checkInvoke(a);
360     a.reinitialize();
361     checkInvoke(a);
362     }
363    
364     /**
365     * timed quietlyJoin of a forked task returns when task completes
366     */
367     public void testForkTimedQuietlyJoin() {
368     RecursiveAction a = new CheckedRecursiveAction() {
369     protected void realCompute() throws Exception {
370     FibAction f = new FibAction(8);
371     assertSame(f, f.fork());
372     assertTrue(f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS));
373     assertEquals(21, f.result);
374     checkCompletedNormally(f);
375     }};
376     checkInvoke(a);
377     }
378    
379     /**
380     * timed quietlyJoin with null time unit throws NPE
381     */
382     public void testForkTimedQuietlyJoinNPE() {
383     RecursiveAction a = new CheckedRecursiveAction() {
384     protected void realCompute() throws Exception {
385     FibAction f = new FibAction(8);
386     assertSame(f, f.fork());
387     try {
388     f.quietlyJoin(randomTimeout(), null);
389     shouldThrow();
390     } catch (NullPointerException success) {}
391     }};
392     checkInvoke(a);
393     }
394    
395     /**
396     * quietlyInvoke task returns when task completes abnormally
397     */
398     public void testAbnormalTimedQuietlyJoin() {
399     RecursiveAction a = new CheckedRecursiveAction() {
400     protected void realCompute() throws Exception {
401     FailingFibAction f = new FailingFibAction(8);
402     assertSame(f, f.fork());
403     assertTrue(f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS));
404     assertTrue(f.getException() instanceof FJException);
405     checkCompletedAbnormally(f, f.getException());
406     }};
407     checkInvoke(a);
408     }
409    
410     /**
411     * timed quietlyJoinUninterruptibly of a forked task returns when task completes
412     */
413     public void testForkTimedQuietlyJoinUninterruptibly() {
414     RecursiveAction a = new CheckedRecursiveAction() {
415     protected void realCompute() throws Exception {
416     FibAction f = new FibAction(8);
417     assertSame(f, f.fork());
418     assertTrue(f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS));
419     assertEquals(21, f.result);
420     checkCompletedNormally(f);
421     }};
422     checkInvoke(a);
423     }
424    
425     /**
426     * timed quietlyJoinUninterruptibly with null time unit throws NPE
427     */
428     public void testForkTimedQuietlyJoinUninterruptiblyNPE() {
429     RecursiveAction a = new CheckedRecursiveAction() {
430     protected void realCompute() throws Exception {
431     FibAction f = new FibAction(8);
432     assertSame(f, f.fork());
433     try {
434     f.quietlyJoinUninterruptibly(randomTimeout(), null);
435     shouldThrow();
436     } catch (NullPointerException success) {}
437     }};
438     checkInvoke(a);
439     }
440    
441     /**
442     * quietlyInvoke task returns when task completes abnormally
443     */
444     public void testAbnormalTimedQuietlyJoinUninterruptibly() {
445     RecursiveAction a = new CheckedRecursiveAction() {
446     protected void realCompute() {
447     FailingFibAction f = new FailingFibAction(8);
448     assertSame(f, f.fork());
449     assertTrue(f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS));
450     assertTrue(f.getException() instanceof FJException);
451     checkCompletedAbnormally(f, f.getException());
452     }};
453     checkInvoke(a);
454     }
455    
456     /**
457     * adaptInterruptible(callable).toString() contains toString of wrapped task
458     */
459     public void testAdaptInterruptible_Callable_toString() {
460     if (testImplementationDetails) {
461     Callable<String> c = () -> "";
462     ForkJoinTask<String> task = ForkJoinTask.adaptInterruptible(c);
463     assertEquals(
464     identityString(task) + "[Wrapped task = " + c.toString() + "]",
465     task.toString());
466     }
467     }
468    
469 dl 1.2 /**
470     * Implictly closing a new pool using try-with-resources terminates it
471     */
472     public void testClose() {
473     ForkJoinTask f = new FibAction(8);
474     ForkJoinPool pool = null;
475     try (ForkJoinPool p = new ForkJoinPool()) {
476     pool = p;
477     p.execute(f);
478     }
479     checkCompletedNormally(f);
480     assertTrue(pool != null && pool.isTerminated());
481     }
482    
483     /**
484     * Implictly closing commonpool using try-with-resources does not
485     * terminate it
486     */
487     public void testCloseCommonPool() {
488     ForkJoinTask f = new FibAction(8);
489     ForkJoinPool pool;
490     try (ForkJoinPool p = ForkJoinPool.commonPool()) {
491     pool = p;
492     p.execute(f);
493     }
494     assertFalse(pool.isTerminated());
495     }
496 dl 1.1 }