--- jsr166/src/test/tck/CompletableFutureTest.java 2014/06/01 21:17:05 1.34 +++ jsr166/src/test/tck/CompletableFutureTest.java 2014/06/01 22:22:49 1.35 @@ -16,6 +16,7 @@ import java.util.concurrent.ExecutionExc import java.util.concurrent.Future; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -328,9 +329,15 @@ public class CompletableFutureTest exten public void accept(Integer x) { value = x.intValue() + 1; } } static final class SubtractAction implements BiConsumer { + // Handle null values as well + public int subtract(Integer x, Integer y) { + return ((x == null) ? 42 : x.intValue()) + - ((y == null) ? 99 : y.intValue()); + } int value; + public boolean ran() { return value != 0; } public void accept(Integer x, Integer y) { - value = x.intValue() - y.intValue(); + value = subtract(x, y); } } static final class Noop implements Runnable { @@ -405,6 +412,85 @@ public class CompletableFutureTest exten } /** + * Permits the testing of parallel code for the 3 different + * execution modes without repeating all the testing code. + */ + enum ExecutionMode { + DEFAULT { + public CompletableFuture runAfterBoth + (CompletableFuture f, CompletableFuture g, Runnable a) { + return f.runAfterBoth(g, a); + } + public CompletableFuture thenAcceptBoth + (CompletableFuture f, + CompletionStage g, + BiConsumer a) { + return f.thenAcceptBoth(g, a); + } + }, + +// /** Experimental way to do more testing */ +// REVERSE_DEFAULT { +// public CompletableFuture runAfterBoth +// (CompletableFuture f, CompletableFuture g, Runnable a) { +// return g.runAfterBoth(f, a); +// } +// public CompletableFuture thenAcceptBoth +// (CompletableFuture f, +// CompletionStage g, +// BiConsumer a) { +// return DEFAULT.thenAcceptBoth(f, g, a); +// } +// }, + + DEFAULT_ASYNC { + public CompletableFuture runAfterBoth + (CompletableFuture f, CompletableFuture g, Runnable a) { + return f.runAfterBothAsync(g, a); + } + public CompletableFuture thenAcceptBoth + (CompletableFuture f, + CompletionStage g, + BiConsumer a) { + return f.thenAcceptBothAsync(g, a); + } + }, + +// REVERSE_DEFAULT_ASYNC { +// public CompletableFuture runAfterBoth +// (CompletableFuture f, CompletableFuture g, Runnable a) { +// return f.runAfterBothAsync(g, a); +// } +// public CompletableFuture thenAcceptBoth +// (CompletableFuture f, +// CompletionStage g, +// BiConsumer a) { +// return DEFAULT_ASYNC.thenAcceptBoth(f, g, a); +// } +// }, + + EXECUTOR { + public CompletableFuture runAfterBoth + (CompletableFuture f, CompletableFuture g, Runnable a) { + return f.runAfterBothAsync(g, a, new ThreadExecutor()); + } + public CompletableFuture thenAcceptBoth + (CompletableFuture f, + CompletionStage g, + BiConsumer a) { + return f.thenAcceptBothAsync(g, a, new ThreadExecutor()); + } + }; + + public abstract CompletableFuture runAfterBoth + (CompletableFuture f, CompletableFuture g, Runnable a); + public abstract CompletableFuture thenAcceptBoth + (CompletableFuture f, + CompletionStage g, + BiConsumer a); + } + + /** * exceptionally action completes with function value on source * exception; otherwise with source value */ @@ -811,169 +897,302 @@ public class CompletableFutureTest exten * thenAcceptBoth result completes normally after normal * completion of sources */ - public void testThenAcceptBoth() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; + public void testThenAcceptBoth_normalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBoth(g, r = new SubtractAction()); - f.complete(3); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + f.complete(v1); checkIncomplete(h); - g.complete(1); + assertEquals(r.value, 0); + g.complete(v2); + checkCompletedNormally(h, null); - assertEquals(r.value, 2); + assertEquals(r.value, r.subtract(v1, v2)); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBoth(g, r = new SubtractAction()); - g.complete(1); + public void testThenAcceptBoth_normalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + g.complete(v2); checkIncomplete(h); - f.complete(3); + assertEquals(r.value, 0); + f.complete(v1); + checkCompletedNormally(h, null); - assertEquals(r.value, 2); + assertEquals(r.value, r.subtract(v1, v2)); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testThenAcceptBoth_normalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + + g.complete(v2); + f.complete(v1); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - g.complete(1); - f.complete(3); - h = f.thenAcceptBoth(g, r = new SubtractAction()); checkCompletedNormally(h, null); - assertEquals(r.value, 2); + assertEquals(r.value, r.subtract(v1, v2)); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testThenAcceptBoth_normalCompletion4() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + + f.complete(v1); + g.complete(v2); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + checkCompletedNormally(h, null); + assertEquals(r.value, r.subtract(v1, v2)); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } } /** * thenAcceptBoth result completes exceptionally after exceptional * completion of either source */ - public void testThenAcceptBoth2() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; + public void testThenAcceptBoth_exceptionalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBoth(g, r = new SubtractAction()); - f.completeExceptionally(new CFException()); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); checkIncomplete(h); - g.complete(1); - checkCompletedWithWrappedCFException(h); + g.complete(v1); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBoth(g, r = new SubtractAction()); - g.completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(h, ex); + checkCompletedWithWrappedCFException(f, ex); + assertFalse(r.ran()); + checkCompletedNormally(g, v1); + } + } + + public void testThenAcceptBoth_exceptionalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); checkIncomplete(h); - f.complete(3); - checkCompletedWithWrappedCFException(h); + f.complete(v1); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - g.completeExceptionally(new CFException()); - h = f.thenAcceptBoth(g, r = new SubtractAction()); - checkCompletedWithWrappedCFException(h); + checkCompletedWithWrappedCFException(h, ex); + checkCompletedWithWrappedCFException(g, ex); + assertFalse(r.ran()); + checkCompletedNormally(f, v1); + } + } - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.completeExceptionally(new CFException()); - g.complete(3); - h = f.thenAcceptBoth(g, r = new SubtractAction()); - checkCompletedWithWrappedCFException(h); + public void testThenAcceptBoth_exceptionalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); + f.complete(v1); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + checkCompletedWithWrappedCFException(h, ex); + checkCompletedWithWrappedCFException(g, ex); + assertFalse(r.ran()); + checkCompletedNormally(f, v1); + } + } + + public void testThenAcceptBoth_exceptionalCompletion4() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); + g.complete(v1); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + checkCompletedWithWrappedCFException(h, ex); + checkCompletedWithWrappedCFException(f, ex); + assertFalse(r.ran()); + checkCompletedNormally(g, v1); + } } /** * thenAcceptBoth result completes exceptionally if action does */ - public void testThenAcceptBoth3() { - CompletableFuture f, g; - CompletableFuture h; - FailingBiConsumer r; + public void testThenAcceptBoth_actionFailed1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBoth(g, r = new FailingBiConsumer()); - f.complete(3); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingBiConsumer r = new FailingBiConsumer(); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + f.complete(v1); checkIncomplete(h); - g.complete(1); + g.complete(v2); + checkCompletedWithWrappedCFException(h); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testThenAcceptBoth_actionFailed2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingBiConsumer r = new FailingBiConsumer(); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + g.complete(v2); + checkIncomplete(h); + f.complete(v1); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - g.complete(1); - h = f.thenAcceptBoth(g, r = new FailingBiConsumer()); checkCompletedWithWrappedCFException(h); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } } /** * thenAcceptBoth result completes exceptionally if either source cancelled */ - public void testThenAcceptBoth4() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; + public void testThenAcceptBoth_sourceCancelled1() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBoth(g, r = new SubtractAction()); - assertTrue(f.cancel(true)); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + assertTrue(f.cancel(mayInterruptIfRunning)); checkIncomplete(h); - g.complete(1); + g.complete(v1); + checkCompletedWithWrappedCancellationException(h); + checkCancelled(f); + assertFalse(r.ran()); + checkCompletedNormally(g, v1); + } + } - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBoth(g, r = new SubtractAction()); - assertTrue(g.cancel(true)); + public void testThenAcceptBoth_sourceCancelled2() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); + + assertTrue(g.cancel(mayInterruptIfRunning)); checkIncomplete(h); - f.complete(3); - checkCompletedWithWrappedCancellationException(h); + f.complete(v1); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - assertTrue(g.cancel(true)); - h = f.thenAcceptBoth(g, r = new SubtractAction()); checkCompletedWithWrappedCancellationException(h); + checkCancelled(g); + assertFalse(r.ran()); + checkCompletedNormally(f, v1); + } + } + + public void testThenAcceptBoth_sourceCancelled3() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); + + assertTrue(g.cancel(mayInterruptIfRunning)); + f.complete(v1); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - assertTrue(f.cancel(true)); - g.complete(3); - h = f.thenAcceptBoth(g, r = new SubtractAction()); checkCompletedWithWrappedCancellationException(h); + checkCancelled(g); + assertFalse(r.ran()); + checkCompletedNormally(f, v1); + } } - /** - * Permits the testing of parallel code for the 3 different - * execution modes without repeating all the testing code. - */ - enum ExecutionMode { - DEFAULT { - public CompletableFuture runAfterBoth - (CompletableFuture f, CompletableFuture g, Runnable r) { - return f.runAfterBoth(g, r); - } - }, + public void testThenAcceptBoth_sourceCancelled4() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { - DEFAULT_ASYNC { - public CompletableFuture runAfterBoth - (CompletableFuture f, CompletableFuture g, Runnable r) { - return f.runAfterBothAsync(g, r); - } - }, + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final SubtractAction r = new SubtractAction(); - EXECUTOR { - public CompletableFuture runAfterBoth - (CompletableFuture f, CompletableFuture g, Runnable r) { - return f.runAfterBothAsync(g, r, new ThreadExecutor()); - } - }; + assertTrue(f.cancel(mayInterruptIfRunning)); + g.complete(v1); + final CompletableFuture h = m.thenAcceptBoth(f, g, r); - public abstract CompletableFuture runAfterBoth - (CompletableFuture f, CompletableFuture g, Runnable r); + checkCompletedWithWrappedCancellationException(h); + checkCancelled(f); + assertFalse(r.ran()); + checkCompletedNormally(g, v1); + } } /** @@ -1828,145 +2047,6 @@ public class CompletableFutureTest exten } /** - * thenAcceptBothAsync result completes normally after normal - * completion of sources - */ - public void testThenAcceptBothAsync() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - f.complete(3); - checkIncomplete(h); - g.complete(1); - checkCompletedNormally(h, null); - assertEquals(r.value, 2); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - g.complete(1); - checkIncomplete(h); - f.complete(3); - checkCompletedNormally(h, null); - assertEquals(r.value, 2); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - g.complete(1); - f.complete(3); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - checkCompletedNormally(h, null); - assertEquals(r.value, 2); - } - - /** - * thenAcceptBothAsync result completes exceptionally after exceptional - * completion of source - */ - public void testThenAcceptBothAsync2() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - f.completeExceptionally(new CFException()); - checkIncomplete(h); - g.complete(1); - checkCompletedWithWrappedCFException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - g.completeExceptionally(new CFException()); - checkIncomplete(h); - f.complete(3); - checkCompletedWithWrappedCFException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - g.completeExceptionally(new CFException()); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - checkCompletedWithWrappedCFException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.completeExceptionally(new CFException()); - g.complete(3); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - checkCompletedWithWrappedCFException(h); - } - - /** - * thenAcceptBothAsync result completes exceptionally if action does - */ - public void testThenAcceptBothAsync3() { - CompletableFuture f, g; - CompletableFuture h; - FailingBiConsumer r; - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer()); - f.complete(3); - checkIncomplete(h); - g.complete(1); - checkCompletedWithWrappedCFException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - g.complete(1); - h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer()); - checkCompletedWithWrappedCFException(h); - } - - /** - * thenAcceptBothAsync result completes exceptionally if either source cancelled - */ - public void testThenAcceptBothAsync4() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - assertTrue(f.cancel(true)); - checkIncomplete(h); - g.complete(1); - checkCompletedWithWrappedCancellationException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - assertTrue(g.cancel(true)); - checkIncomplete(h); - f.complete(3); - checkCompletedWithWrappedCancellationException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - assertTrue(g.cancel(true)); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - checkCompletedWithWrappedCancellationException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - assertTrue(f.cancel(true)); - g.complete(3); - h = f.thenAcceptBothAsync(g, r = new SubtractAction()); - checkCompletedWithWrappedCancellationException(h); - } - - /** * applyToEitherAsync result completes normally after normal * completion of sources */ @@ -2532,157 +2612,6 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); assertEquals(0, e.count.get()); - } - - /** - * thenAcceptBothAsync result completes normally after normal - * completion of sources - */ - public void testThenAcceptBothAsyncE() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; - ThreadExecutor e = new ThreadExecutor(); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - f.complete(3); - checkIncomplete(h); - g.complete(1); - checkCompletedNormally(h, null); - assertEquals(r.value, 2); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - g.complete(1); - checkIncomplete(h); - f.complete(3); - checkCompletedNormally(h, null); - assertEquals(r.value, 2); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - g.complete(1); - f.complete(3); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - checkCompletedNormally(h, null); - assertEquals(r.value, 2); - - assertEquals(3, e.count.get()); - } - - /** - * thenAcceptBothAsync result completes exceptionally after exceptional - * completion of source - */ - public void testThenAcceptBothAsync2E() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; - ThreadExecutor e = new ThreadExecutor(); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - f.completeExceptionally(new CFException()); - checkIncomplete(h); - g.complete(1); - checkCompletedWithWrappedCFException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - g.completeExceptionally(new CFException()); - checkIncomplete(h); - f.complete(3); - checkCompletedWithWrappedCFException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - g.completeExceptionally(new CFException()); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - checkCompletedWithWrappedCFException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.completeExceptionally(new CFException()); - g.complete(3); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - checkCompletedWithWrappedCFException(h); - - assertEquals(0, e.count.get()); - } - - /** - * thenAcceptBothAsync result completes exceptionally if action does - */ - public void testThenAcceptBothAsync3E() { - CompletableFuture f, g; - CompletableFuture h; - FailingBiConsumer r; - ThreadExecutor e = new ThreadExecutor(); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer(), e); - f.complete(3); - checkIncomplete(h); - g.complete(1); - checkCompletedWithWrappedCFException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - g.complete(1); - h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer(), e); - checkCompletedWithWrappedCFException(h); - - assertEquals(2, e.count.get()); - } - - /** - * thenAcceptBothAsync result completes exceptionally if either source cancelled - */ - public void testThenAcceptBothAsync4E() { - CompletableFuture f, g; - CompletableFuture h; - SubtractAction r; - ThreadExecutor e = new ThreadExecutor(); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - assertTrue(f.cancel(true)); - checkIncomplete(h); - g.complete(1); - checkCompletedWithWrappedCancellationException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - assertTrue(g.cancel(true)); - checkIncomplete(h); - f.complete(3); - checkCompletedWithWrappedCancellationException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.complete(3); - assertTrue(g.cancel(true)); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - checkCompletedWithWrappedCancellationException(h); - - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - assertTrue(f.cancel(true)); - g.complete(3); - h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e); - checkCompletedWithWrappedCancellationException(h); - - assertEquals(0, e.count.get()); } /**