Added jsr166 tck tests as part of the libcore testsuite.
Change-Id: I6094d734f818fa043f2b277cf2b4ec7fec68e26e
diff --git a/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java b/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java
new file mode 100644
index 0000000..48b6470
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java
@@ -0,0 +1,1020 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import java.util.HashSet;
+
+public class RecursiveTaskTest extends JSR166TestCase {
+
+ private static ForkJoinPool mainPool() {
+ return new ForkJoinPool();
+ }
+
+ private static ForkJoinPool singletonPool() {
+ return new ForkJoinPool(1);
+ }
+
+ private static ForkJoinPool asyncSingletonPool() {
+ return new ForkJoinPool(1,
+ ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+ null, true);
+ }
+
+ private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) {
+ try {
+ checkNotDone(a);
+
+ T result = pool.invoke(a);
+
+ checkCompletedNormally(a, result);
+ return result;
+ } finally {
+ joinPool(pool);
+ }
+ }
+
+ void checkNotDone(RecursiveTask a) {
+ assertFalse(a.isDone());
+ assertFalse(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+
+ if (! ForkJoinTask.inForkJoinPool()) {
+ Thread.currentThread().interrupt();
+ try {
+ a.get();
+ shouldThrow();
+ } catch (InterruptedException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ Thread.currentThread().interrupt();
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ try {
+ a.get(0L, SECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ <T> void checkCompletedNormally(RecursiveTask<T> a, T expected) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertTrue(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertNull(a.getException());
+ assertSame(expected, a.getRawResult());
+ assertSame(expected, a.join());
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+ try {
+ assertSame(expected, a.get());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ try {
+ assertSame(expected, a.get(5L, SECONDS));
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ /**
+ * Waits for the task to complete, and checks that when it does,
+ * it will have an Integer result equals to the given int.
+ */
+ void checkCompletesNormally(RecursiveTask<Integer> a, int expected) {
+ Integer r = a.join();
+ assertEquals(expected, (int) r);
+ checkCompletedNormally(a, r);
+ }
+
+ /**
+ * Like checkCompletesNormally, but verifies that the task has
+ * already completed.
+ */
+ void checkCompletedNormally(RecursiveTask<Integer> a, int expected) {
+ Integer r = a.getRawResult();
+ assertEquals(expected, (int) r);
+ checkCompletedNormally(a, r);
+ }
+
+ void checkCancelled(RecursiveTask a) {
+ assertTrue(a.isDone());
+ assertTrue(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertTrue(a.getException() instanceof CancellationException);
+ assertNull(a.getRawResult());
+
+ try {
+ a.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCompletedAbnormally(RecursiveTask a, Throwable t) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertSame(t.getClass(), a.getException().getClass());
+ assertNull(a.getRawResult());
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+
+ try {
+ a.join();
+ shouldThrow();
+ } catch (Throwable expected) {
+ assertSame(t.getClass(), expected.getClass());
+ }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ public static final class FJException extends RuntimeException {
+ public FJException() { super(); }
+ }
+
+ // An invalid return value for Fib
+ static final Integer NoResult = Integer.valueOf(-17);
+
+ // A simple recursive task for testing
+ final class FibTask extends CheckedRecursiveTask<Integer> {
+ final int number;
+ FibTask(int n) { number = n; }
+ public Integer realCompute() {
+ int n = number;
+ if (n <= 1)
+ return n;
+ FibTask f1 = new FibTask(n - 1);
+ f1.fork();
+ return (new FibTask(n - 2)).compute() + f1.join();
+ }
+
+ public void publicSetRawResult(Integer result) {
+ setRawResult(result);
+ }
+ }
+
+ // A recursive action failing in base case
+ final class FailingFibTask extends RecursiveTask<Integer> {
+ final int number;
+ int result;
+ FailingFibTask(int n) { number = n; }
+ public Integer compute() {
+ int n = number;
+ if (n <= 1)
+ throw new FJException();
+ FailingFibTask f1 = new FailingFibTask(n - 1);
+ f1.fork();
+ return (new FibTask(n - 2)).compute() + f1.join();
+ }
+ }
+
+ /**
+ * invoke returns value when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks. getRawResult of a completed non-null task
+ * returns value;
+ */
+ public void testInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ Integer r = f.invoke();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks
+ */
+ public void testQuietlyInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ f.quietlyInvoke();
+ checkCompletedNormally(f, 21);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * join of a forked task returns when task completes
+ */
+ public void testForkJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ Integer r = f.join();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * get of a forked task returns when task completes
+ */
+ public void testForkGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ Integer r = f.get();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * timed get of a forked task returns when task completes
+ */
+ public void testForkTimedGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ Integer r = f.get(5L, SECONDS);
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes
+ */
+ public void testForkQuietlyJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ Integer r = f.getRawResult();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * helpQuiesce returns when tasks are complete.
+ * getQueuedTaskCount returns 0 when quiescent
+ */
+ public void testForkHelpQuiesce() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ helpQuiesce();
+ assertEquals(0, getQueuedTaskCount());
+ checkCompletedNormally(f, 21);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invoke task throws exception when task completes abnormally
+ */
+ public void testAbnormalInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes abnormally
+ */
+ public void testAbnormalQuietlyInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ f.quietlyInvoke();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * join of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FailingFibTask f = new FailingFibTask(8);
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * timed get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkTimedGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FailingFibTask f = new FailingFibTask(8);
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.get(5L, SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes abnormally
+ */
+ public void testAbnormalForkQuietlyJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invoke task throws exception when task cancelled
+ */
+ public void testCancelledInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ try {
+ Integer r = f.invoke();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * join of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * timed get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkTimedGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task cancelled
+ */
+ public void testCancelledForkQuietlyJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ checkCancelled(f);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * getPool of executing task returns its pool
+ */
+ public void testGetPool() {
+ final ForkJoinPool mainPool = mainPool();
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ assertSame(mainPool, getPool());
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool, a));
+ }
+
+ /**
+ * getPool of non-FJ task returns null
+ */
+ public void testGetPool2() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ assertNull(getPool());
+ return NoResult;
+ }};
+ assertSame(NoResult, a.invoke());
+ }
+
+ /**
+ * inForkJoinPool of executing task returns true
+ */
+ public void testInForkJoinPool() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ assertTrue(inForkJoinPool());
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * inForkJoinPool of non-FJ task returns false
+ */
+ public void testInForkJoinPool2() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ assertFalse(inForkJoinPool());
+ return NoResult;
+ }};
+ assertSame(NoResult, a.invoke());
+ }
+
+ /**
+ * The value set by setRawResult is returned by getRawResult
+ */
+ public void testSetRawResult() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ setRawResult(NoResult);
+ assertSame(NoResult, getRawResult());
+ return NoResult;
+ }
+ };
+ assertSame(NoResult, a.invoke());
+ }
+
+ /**
+ * A reinitialized normally completed task may be re-invoked
+ */
+ public void testReinitialize() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ checkNotDone(f);
+
+ for (int i = 0; i < 3; i++) {
+ Integer r = f.invoke();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ f.reinitialize();
+ f.publicSetRawResult(null);
+ checkNotDone(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * A reinitialized abnormally completed task may be re-invoked
+ */
+ public void testReinitializeAbnormal() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ checkNotDone(f);
+
+ for (int i = 0; i < 3; i++) {
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ f.reinitialize();
+ checkNotDone(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invoke task throws exception after invoking completeExceptionally
+ */
+ public void testCompleteExceptionally() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ f.completeExceptionally(new FJException());
+ try {
+ Integer r = f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invoke task suppresses execution invoking complete
+ */
+ public void testComplete() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ f.complete(NoResult);
+ Integer r = f.invoke();
+ assertSame(NoResult, r);
+ checkCompletedNormally(f, NoResult);
+ return r;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(t1, t2) invokes all task arguments
+ */
+ public void testInvokeAll2() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FibTask g = new FibTask(9);
+ invokeAll(f, g);
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument invokes task
+ */
+ public void testInvokeAll1() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ invokeAll(f);
+ checkCompletedNormally(f, 21);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument invokes tasks
+ */
+ public void testInvokeAll3() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FibTask g = new FibTask(9);
+ FibTask h = new FibTask(7);
+ invokeAll(f, g, h);
+ assertTrue(f.isDone());
+ assertTrue(g.isDone());
+ assertTrue(h.isDone());
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ checkCompletedNormally(h, 13);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(collection) invokes all tasks in the collection
+ */
+ public void testInvokeAllCollection() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FibTask g = new FibTask(9);
+ FibTask h = new FibTask(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ invokeAll(set);
+ assertTrue(f.isDone());
+ assertTrue(g.isDone());
+ assertTrue(h.isDone());
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ checkCompletedNormally(h, 13);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with any null task throws NPE
+ */
+ public void testInvokeAllNPE() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FibTask g = new FibTask(9);
+ FibTask h = null;
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(t1, t2) throw exception if any task does
+ */
+ public void testAbnormalInvokeAll2() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FailingFibTask g = new FailingFibTask(9);
+ try {
+ invokeAll(f, g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument throws exception if task does
+ */
+ public void testAbnormalInvokeAll1() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask g = new FailingFibTask(9);
+ try {
+ invokeAll(g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument throws exception if any task does
+ */
+ public void testAbnormalInvokeAll3() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FailingFibTask g = new FailingFibTask(9);
+ FibTask h = new FibTask(7);
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(collection) throws exception if any task does
+ */
+ public void testAbnormalInvokeAllCollection() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ FibTask g = new FibTask(9);
+ FibTask h = new FibTask(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ try {
+ invokeAll(set);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * tryUnfork returns true for most recent unexecuted task,
+ * and suppresses execution
+ */
+ public void testTryUnfork() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertTrue(f.tryUnfork());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * getSurplusQueuedTaskCount returns > 0 when
+ * there are more tasks than threads
+ */
+ public void testGetSurplusQueuedTaskCount() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask h = new FibTask(7);
+ assertSame(h, h.fork());
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertTrue(getSurplusQueuedTaskCount() > 0);
+ helpQuiesce();
+ assertEquals(0, getSurplusQueuedTaskCount());
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ checkCompletedNormally(h, 13);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * peekNextLocalTask returns most recent unexecuted task.
+ */
+ public void testPeekNextLocalTask() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(f, peekNextLocalTask());
+ checkCompletesNormally(f, 21);
+ helpQuiesce();
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * pollNextLocalTask returns most recent unexecuted task
+ * without executing it
+ */
+ public void testPollNextLocalTask() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollNextLocalTask());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it
+ */
+ public void testPollTask() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollTask());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * peekNextLocalTask returns least recent unexecuted task in async mode
+ */
+ public void testPeekNextLocalTaskAsync() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(g, peekNextLocalTask());
+ assertEquals(21, (int) f.join());
+ helpQuiesce();
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+ }
+
+ /**
+ * pollNextLocalTask returns least recent unexecuted task without
+ * executing it, in async mode
+ */
+ public void testPollNextLocalTaskAsync() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollNextLocalTask());
+ helpQuiesce();
+ checkCompletedNormally(f, 21);
+ checkNotDone(g);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it, in
+ * async mode
+ */
+ public void testPollTaskAsync() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollTask());
+ helpQuiesce();
+ checkCompletedNormally(f, 21);
+ checkNotDone(g);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+ }
+
+}