ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinPool19Test.java
Revision: 1.1
Committed: Tue Mar 22 16:26:18 2022 UTC (2 years, 1 month ago) by dl
Branch: MAIN
Log Message:
Test additions

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