--- jsr166/src/test/tck/CompletableFutureTest.java 2013/03/27 19:45:42 1.9 +++ jsr166/src/test/tck/CompletableFutureTest.java 2013/07/15 03:50:08 1.29 @@ -53,7 +53,10 @@ public class CompletableFutureTest exten catch (Throwable fail) { threadUnexpectedException(fail); } } - void checkCompletedNormally(CompletableFuture f, Object value) { + void checkCompletedNormally(CompletableFuture f, T value) { + try { + assertEquals(value, f.get(LONG_DELAY_MS, MILLISECONDS)); + } catch (Throwable fail) { threadUnexpectedException(fail); } try { assertEquals(value, f.join()); } catch (Throwable fail) { threadUnexpectedException(fail); } @@ -63,16 +66,20 @@ public class CompletableFutureTest exten try { assertEquals(value, f.get()); } catch (Throwable fail) { threadUnexpectedException(fail); } - try { - assertEquals(value, f.get(0L, SECONDS)); - } catch (Throwable fail) { threadUnexpectedException(fail); } assertTrue(f.isDone()); assertFalse(f.isCancelled()); + assertFalse(f.isCompletedExceptionally()); assertTrue(f.toString().contains("[Completed normally]")); } void checkCompletedWithWrappedCFException(CompletableFuture f) { try { + f.get(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (ExecutionException success) { + assertTrue(success.getCause() instanceof CFException); + } catch (Throwable fail) { threadUnexpectedException(fail); } + try { f.join(); shouldThrow(); } catch (CompletionException success) { @@ -90,18 +97,18 @@ public class CompletableFutureTest exten } catch (ExecutionException success) { assertTrue(success.getCause() instanceof CFException); } catch (Throwable fail) { threadUnexpectedException(fail); } - try { - f.get(0L, SECONDS); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof CFException); - } catch (Throwable fail) { threadUnexpectedException(fail); } assertTrue(f.isDone()); assertFalse(f.isCancelled()); + assertTrue(f.toString().contains("[Completed exceptionally]")); } void checkCancelled(CompletableFuture f) { try { + f.get(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (CancellationException success) { + } catch (Throwable fail) { threadUnexpectedException(fail); } + try { f.join(); shouldThrow(); } catch (CancellationException success) {} @@ -114,17 +121,20 @@ public class CompletableFutureTest exten shouldThrow(); } catch (CancellationException success) { } catch (Throwable fail) { threadUnexpectedException(fail); } - try { - f.get(0L, SECONDS); - shouldThrow(); - } catch (CancellationException success) { - } catch (Throwable fail) { threadUnexpectedException(fail); } assertTrue(f.isDone()); + assertTrue(f.isCompletedExceptionally()); assertTrue(f.isCancelled()); + assertTrue(f.toString().contains("[Completed exceptionally]")); } void checkCompletedWithWrappedCancellationException(CompletableFuture f) { try { + f.get(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (ExecutionException success) { + assertTrue(success.getCause() instanceof CancellationException); + } catch (Throwable fail) { threadUnexpectedException(fail); } + try { f.join(); shouldThrow(); } catch (CompletionException success) { @@ -142,14 +152,10 @@ public class CompletableFutureTest exten } catch (ExecutionException success) { assertTrue(success.getCause() instanceof CancellationException); } catch (Throwable fail) { threadUnexpectedException(fail); } - try { - f.get(0L, SECONDS); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof CancellationException); - } catch (Throwable fail) { threadUnexpectedException(fail); } assertTrue(f.isDone()); assertFalse(f.isCancelled()); + assertTrue(f.isCompletedExceptionally()); + assertTrue(f.toString().contains("[Completed exceptionally]")); } /** @@ -157,7 +163,7 @@ public class CompletableFutureTest exten * by methods isDone, isCancelled, and getNow */ public void testConstructor() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); checkIncomplete(f); } @@ -166,7 +172,7 @@ public class CompletableFutureTest exten * isCancelled, join, get, and getNow */ public void testComplete() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); checkIncomplete(f); f.complete(one); checkCompletedNormally(f, one); @@ -177,7 +183,7 @@ public class CompletableFutureTest exten * methods isDone, isCancelled, join, get, and getNow */ public void testCompleteExceptionally() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); checkIncomplete(f); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(f); @@ -188,7 +194,7 @@ public class CompletableFutureTest exten * methods isDone, isCancelled, join, get, and getNow */ public void testCancel() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); checkIncomplete(f); assertTrue(f.cancel(true)); checkCancelled(f); @@ -198,7 +204,7 @@ public class CompletableFutureTest exten * obtrudeValue forces completion with given value */ public void testObtrudeValue() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); checkIncomplete(f); f.complete(one); checkCompletedNormally(f, one); @@ -206,10 +212,10 @@ public class CompletableFutureTest exten checkCompletedNormally(f, three); f.obtrudeValue(two); checkCompletedNormally(f, two); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.obtrudeValue(three); checkCompletedNormally(f, three); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.completeExceptionally(new CFException()); f.obtrudeValue(four); checkCompletedNormally(f, four); @@ -219,16 +225,16 @@ public class CompletableFutureTest exten * obtrudeException forces completion with given exception */ public void testObtrudeException() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); checkIncomplete(f); f.complete(one); checkCompletedNormally(f, one); f.obtrudeException(new CFException()); checkCompletedWithWrappedCFException(f); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.obtrudeException(new CFException()); checkCompletedWithWrappedCFException(f); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.completeExceptionally(new CFException()); f.obtrudeValue(four); checkCompletedNormally(f, four); @@ -240,7 +246,7 @@ public class CompletableFutureTest exten * getNumberOfDependents returns number of dependent tasks */ public void testGetNumberOfDependents() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); assertEquals(f.getNumberOfDependents(), 0); CompletableFuture g = f.thenRun(new Noop()); assertEquals(f.getNumberOfDependents(), 1); @@ -253,7 +259,6 @@ public class CompletableFutureTest exten assertEquals(g.getNumberOfDependents(), 0); } - /** * toString indicates current completion state */ @@ -272,27 +277,29 @@ public class CompletableFutureTest exten } /** - * completedFuture returns a completed CompletableFuture with give value + * completedFuture returns a completed CompletableFuture with given value */ public void testCompletedFuture() { CompletableFuture f = CompletableFuture.completedFuture("test"); checkCompletedNormally(f, "test"); } + // Choose non-commutative actions for better coverage + static final Supplier supplyOne = () -> Integer.valueOf(1); static final Function inc = (Integer x) -> Integer.valueOf(x.intValue() + 1); - static final BiFunction add = - (Integer x, Integer y) -> Integer.valueOf(x.intValue() + y.intValue()); + static final BiFunction subtract = + (Integer x, Integer y) -> Integer.valueOf(x.intValue() - y.intValue()); static final class IncAction implements Consumer { int value; public void accept(Integer x) { value = x.intValue() + 1; } } - static final class AddAction implements BiConsumer { + static final class SubtractAction implements BiConsumer { int value; public void accept(Integer x, Integer y) { - value = x.intValue() + y.intValue(); + value = x.intValue() - y.intValue(); } } static final class Noop implements Runnable { @@ -325,15 +332,19 @@ public class CompletableFutureTest exten public void run() { ran = true; throw new CFException(); } } - static final class CompletableFutureInc implements Function> { + static final class CompletableFutureInc + implements Function> { + boolean ran; public CompletableFuture apply(Integer x) { - CompletableFuture f = new CompletableFuture(); + ran = true; + CompletableFuture f = new CompletableFuture<>(); f.complete(Integer.valueOf(x.intValue() + 1)); return f; } } - static final class FailingCompletableFutureFunction implements Function> { + static final class FailingCompletableFutureFunction + implements Function> { boolean ran; public CompletableFuture apply(Integer x) { ran = true; throw new CFException(); @@ -342,7 +353,10 @@ public class CompletableFutureTest exten // Used for explicit executor tests static final class ThreadExecutor implements Executor { + AtomicInteger count = new AtomicInteger(0); + public void execute(Runnable r) { + count.getAndIncrement(); new Thread(r).start(); } } @@ -352,24 +366,25 @@ public class CompletableFutureTest exten } static final class IntegerHandler implements BiFunction { + boolean ran; public Integer apply(Integer x, Throwable t) { + ran = true; return (t == null) ? two : three; } } - /** * exceptionally action completes with function value on source * exception; otherwise with source value */ public void testExceptionally() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); ExceptionToInteger r = new ExceptionToInteger(); CompletableFuture g = f.exceptionally(r); f.completeExceptionally(new CFException()); checkCompletedNormally(g, three); - f = new CompletableFuture(); + f = new CompletableFuture<>(); r = new ExceptionToInteger(); g = f.exceptionally(r); f.complete(one); @@ -381,16 +396,33 @@ public class CompletableFutureTest exten * normal or exceptional completion of source */ public void testHandle() { - CompletableFuture f = new CompletableFuture(); - IntegerHandler r = new IntegerHandler(); - CompletableFuture g = f.handle(r); + CompletableFuture f, g; + IntegerHandler r; + + f = new CompletableFuture<>(); + f.completeExceptionally(new CFException()); + g = f.handle(r = new IntegerHandler()); + assertTrue(r.ran); + checkCompletedNormally(g, three); + + f = new CompletableFuture<>(); + g = f.handle(r = new IntegerHandler()); + assertFalse(r.ran); f.completeExceptionally(new CFException()); checkCompletedNormally(g, three); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + f.complete(one); + g = f.handle(r = new IntegerHandler()); + assertTrue(r.ran); + checkCompletedNormally(g, two); - f = new CompletableFuture(); - r = new IntegerHandler(); - g = f.handle(r); + f = new CompletableFuture<>(); + g = f.handle(r = new IntegerHandler()); + assertFalse(r.ran); f.complete(one); + assertTrue(r.ran); checkCompletedNormally(g, two); } @@ -402,6 +434,7 @@ public class CompletableFutureTest exten CompletableFuture f = CompletableFuture.runAsync(r); assertNull(f.join()); assertTrue(r.ran); + checkCompletedNormally(f, null); } /** @@ -409,9 +442,12 @@ public class CompletableFutureTest exten */ public void testRunAsync2() { Noop r = new Noop(); - CompletableFuture f = CompletableFuture.runAsync(r, new ThreadExecutor()); + ThreadExecutor exec = new ThreadExecutor(); + CompletableFuture f = CompletableFuture.runAsync(r, exec); assertNull(f.join()); assertTrue(r.ran); + checkCompletedNormally(f, null); + assertEquals(1, exec.count.get()); } /** @@ -428,16 +464,20 @@ public class CompletableFutureTest exten * supplyAsync completes with result of supplier */ public void testSupplyAsync() { - CompletableFuture f = CompletableFuture.supplyAsync(supplyOne); + CompletableFuture f; + f = CompletableFuture.supplyAsync(supplyOne); assertEquals(f.join(), one); + checkCompletedNormally(f, one); } /** * supplyAsync with executor completes with result of supplier */ public void testSupplyAsync2() { - CompletableFuture f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor()); + CompletableFuture f; + f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor()); assertEquals(f.join(), one); + checkCompletedNormally(f, one); } /** @@ -456,17 +496,21 @@ public class CompletableFutureTest exten * thenRun result completes normally after normal completion of source */ public void testThenRun() { - CompletableFuture f = new CompletableFuture(); - Noop r = new Noop(); - CompletableFuture g = f.thenRun(r); + CompletableFuture f; + CompletableFuture g; + Noop r; + + f = new CompletableFuture<>(); + g = f.thenRun(r = new Noop()); f.complete(null); checkCompletedNormally(g, null); - // reordered version - f = new CompletableFuture(); + assertTrue(r.ran); + + f = new CompletableFuture<>(); f.complete(null); - r = new Noop(); - g = f.thenRun(r); + g = f.thenRun(r = new Noop()); checkCompletedNormally(g, null); + assertTrue(r.ran); } /** @@ -474,40 +518,66 @@ public class CompletableFutureTest exten * completion of source */ public void testThenRun2() { - CompletableFuture f = new CompletableFuture(); - Noop r = new Noop(); - CompletableFuture g = f.thenRun(r); + CompletableFuture f; + CompletableFuture g; + Noop r; + + f = new CompletableFuture<>(); + g = f.thenRun(r = new Noop()); + f.completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(g); + assertFalse(r.ran); + + f = new CompletableFuture<>(); f.completeExceptionally(new CFException()); + g = f.thenRun(r = new Noop()); checkCompletedWithWrappedCFException(g); + assertFalse(r.ran); } /** * thenRun result completes exceptionally if action does */ public void testThenRun3() { - CompletableFuture f = new CompletableFuture(); - FailingNoop r = new FailingNoop(); - CompletableFuture g = f.thenRun(r); + CompletableFuture f; + CompletableFuture g; + FailingNoop r; + + f = new CompletableFuture<>(); + g = f.thenRun(r = new FailingNoop()); f.complete(null); checkCompletedWithWrappedCFException(g); + + f = new CompletableFuture<>(); + f.complete(null); + g = f.thenRun(r = new FailingNoop()); + checkCompletedWithWrappedCFException(g); } /** * thenRun result completes exceptionally if source cancelled */ public void testThenRun4() { - CompletableFuture f = new CompletableFuture(); - Noop r = new Noop(); - CompletableFuture g = f.thenRun(r); + CompletableFuture f; + CompletableFuture g; + Noop r; + + f = new CompletableFuture<>(); + g = f.thenRun(r = new Noop()); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); + + f = new CompletableFuture<>(); + assertTrue(f.cancel(true)); + g = f.thenRun(r = new Noop()); + checkCompletedWithWrappedCancellationException(g); } /** * thenApply result completes normally after normal completion of source */ public void testThenApply() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApply(inc); f.complete(one); checkCompletedNormally(g, two); @@ -518,7 +588,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenApply2() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApply(inc); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); @@ -528,7 +598,7 @@ public class CompletableFutureTest exten * thenApply result completes exceptionally if action does */ public void testThenApply3() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApply(new FailingFunction()); f.complete(one); checkCompletedWithWrappedCFException(g); @@ -538,7 +608,7 @@ public class CompletableFutureTest exten * thenApply result completes exceptionally if source cancelled */ public void testThenApply4() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApply(inc); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); @@ -548,7 +618,7 @@ public class CompletableFutureTest exten * thenAccept result completes normally after normal completion of source */ public void testThenAccept() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAccept(r); f.complete(one); @@ -561,7 +631,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenAccept2() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAccept(r); f.completeExceptionally(new CFException()); @@ -572,7 +642,7 @@ public class CompletableFutureTest exten * thenAccept result completes exceptionally if action does */ public void testThenAccept3() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); FailingConsumer r = new FailingConsumer(); CompletableFuture g = f.thenAccept(r); f.complete(one); @@ -584,33 +654,42 @@ public class CompletableFutureTest exten * thenAccept result completes exceptionally if source cancelled */ public void testThenAccept4() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAccept(r); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); } - /** - * thenCombine result completes normally after normal completion of sources + * thenCombine result completes normally after normal completion + * of sources */ public void testThenCombine() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombine(f2, add); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, three); + CompletableFuture f, g, h; - f = new CompletableFuture(); - f.complete(one); - f2 = new CompletableFuture(); - g = f.thenCombine(f2, add); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, three); + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombine(g, subtract); + f.complete(3); + checkIncomplete(h); + g.complete(1); + checkCompletedNormally(h, 2); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombine(g, subtract); + g.complete(1); + checkIncomplete(h); + f.complete(3); + checkCompletedNormally(h, 2); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + g.complete(1); + f.complete(3); + h = f.thenCombine(g, subtract); + checkCompletedNormally(h, 2); } /** @@ -618,51 +697,83 @@ public class CompletableFutureTest exten * completion of either source */ public void testThenCombine2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombine(f2, add); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + CompletableFuture f, g, h; - f = new CompletableFuture(); - f.complete(one); - f2 = new CompletableFuture(); - g = f.thenCombine(f2, add); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombine(g, subtract); + f.completeExceptionally(new CFException()); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCFException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombine(g, subtract); + 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.thenCombine(g, subtract); + checkCompletedWithWrappedCFException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + f.completeExceptionally(new CFException()); + g.complete(3); + h = f.thenCombine(g, subtract); + checkCompletedWithWrappedCFException(h); } /** * thenCombine result completes exceptionally if action does */ public void testThenCombine3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingBiFunction r = new FailingBiFunction(); CompletableFuture g = f.thenCombine(f2, r); f.complete(one); checkIncomplete(g); + assertFalse(r.ran); f2.complete(two); checkCompletedWithWrappedCFException(g); + assertTrue(r.ran); } /** * thenCombine result completes exceptionally if either source cancelled */ public void testThenCombine4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombine(f2, add); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenCombine(f2, add); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + CompletableFuture f, g, h; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombine(g, subtract); + assertTrue(f.cancel(true)); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombine(g, subtract); + assertTrue(g.cancel(true)); + checkIncomplete(h); + f.complete(3); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + assertTrue(f.cancel(true)); + assertTrue(g.cancel(true)); + h = f.thenCombine(g, subtract); + checkCompletedWithWrappedCancellationException(h); } /** @@ -670,25 +781,35 @@ public class CompletableFutureTest exten * completion of sources */ public void testThenAcceptBoth() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBoth(f2, r); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, null); - assertEquals(r.value, 3); + CompletableFuture f, g; + CompletableFuture h; + SubtractAction r; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenAcceptBoth(g, r = new SubtractAction()); + f.complete(3); + checkIncomplete(h); + g.complete(1); + checkCompletedNormally(h, null); + assertEquals(r.value, 2); - r = new AddAction(); - f = new CompletableFuture(); - f.complete(one); - f2 = new CompletableFuture(); - g = f.thenAcceptBoth(f2, r); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, null); - assertEquals(r.value, 3); + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenAcceptBoth(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.thenAcceptBoth(g, r = new SubtractAction()); + checkCompletedNormally(h, null); + assertEquals(r.value, 2); } /** @@ -696,55 +817,102 @@ public class CompletableFutureTest exten * completion of either source */ public void testThenAcceptBoth2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBoth(f2, r); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); - - r = new AddAction(); - f = new CompletableFuture(); - f.complete(one); - f2 = new CompletableFuture(); - g = f.thenAcceptBoth(f2, r); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); + CompletableFuture f, g; + CompletableFuture h; + SubtractAction r; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenAcceptBoth(g, r = new SubtractAction()); + f.completeExceptionally(new CFException()); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCFException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenAcceptBoth(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.thenAcceptBoth(g, r = new SubtractAction()); + checkCompletedWithWrappedCFException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + f.completeExceptionally(new CFException()); + g.complete(3); + h = f.thenAcceptBoth(g, r = new SubtractAction()); + checkCompletedWithWrappedCFException(h); } /** * thenAcceptBoth result completes exceptionally if action does */ public void testThenAcceptBoth3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - FailingBiConsumer r = new FailingBiConsumer(); - CompletableFuture g = f.thenAcceptBoth(f2, r); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + CompletableFuture f, g; + CompletableFuture h; + FailingBiConsumer r; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenAcceptBoth(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.thenAcceptBoth(g, r = new FailingBiConsumer()); + checkCompletedWithWrappedCFException(h); } /** * thenAcceptBoth result completes exceptionally if either source cancelled */ public void testThenAcceptBoth4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBoth(f2, r); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); - r = new AddAction(); - g = f.thenAcceptBoth(f2, r); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + CompletableFuture f, g; + CompletableFuture h; + SubtractAction r; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenAcceptBoth(g, r = new SubtractAction()); + assertTrue(f.cancel(true)); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenAcceptBoth(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.thenAcceptBoth(g, r = new SubtractAction()); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + assertTrue(f.cancel(true)); + g.complete(3); + h = f.thenAcceptBoth(g, r = new SubtractAction()); + checkCompletedWithWrappedCancellationException(h); } /** @@ -752,24 +920,34 @@ public class CompletableFutureTest exten * completion of sources */ public void testRunAfterBoth() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBoth(f2, r); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, null); + CompletableFuture f, g; + CompletableFuture h; + Noop r; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.runAfterBoth(g, r = new Noop()); + f.complete(3); + checkIncomplete(h); + g.complete(1); + checkCompletedNormally(h, null); assertTrue(r.ran); - r = new Noop(); - f = new CompletableFuture(); - f.complete(one); - f2 = new CompletableFuture(); - g = f.runAfterBoth(f2, r); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, null); + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.runAfterBoth(g, r = new Noop()); + g.complete(1); + checkIncomplete(h); + f.complete(3); + checkCompletedNormally(h, null); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + g.complete(1); + f.complete(3); + h = f.runAfterBoth(g, r = new Noop()); + checkCompletedNormally(h, null); assertTrue(r.ran); } @@ -778,29 +956,51 @@ public class CompletableFutureTest exten * completion of either source */ public void testRunAfterBoth2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBoth(f2, r); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); - - r = new Noop(); - f = new CompletableFuture(); - f.complete(one); - f2 = new CompletableFuture(); - g = f.runAfterBoth(f2, r); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); + CompletableFuture f, g; + CompletableFuture h; + Noop r; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.runAfterBoth(g, r = new Noop()); + f.completeExceptionally(new CFException()); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCFException(h); + assertFalse(r.ran); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.runAfterBoth(g, r = new Noop()); + g.completeExceptionally(new CFException()); + checkIncomplete(h); + f.complete(3); + checkCompletedWithWrappedCFException(h); + assertFalse(r.ran); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + g.completeExceptionally(new CFException()); + f.complete(3); + h = f.runAfterBoth(g, r = new Noop()); + checkCompletedWithWrappedCFException(h); + assertFalse(r.ran); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + f.completeExceptionally(new CFException()); + g.complete(1); + h = f.runAfterBoth(g, r = new Noop()); + checkCompletedWithWrappedCFException(h); + assertFalse(r.ran); } /** * runAfterBoth result completes exceptionally if action does */ public void testRunAfterBoth3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingNoop r = new FailingNoop(); CompletableFuture g = f.runAfterBoth(f2, r); f.complete(one); @@ -813,15 +1013,15 @@ public class CompletableFutureTest exten * runAfterBoth result completes exceptionally if either source cancelled */ public void testRunAfterBoth4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterBoth(f2, r); assertTrue(f.cancel(true)); f2.complete(two); checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); r = new Noop(); g = f.runAfterBoth(f2, r); f.complete(one); @@ -834,17 +1034,17 @@ public class CompletableFutureTest exten * of either source */ public void testApplyToEither() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEither(f2, inc); f.complete(one); checkCompletedNormally(g, two); f2.complete(one); checkCompletedNormally(g, two); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.applyToEither(f2, inc); checkCompletedNormally(g, two); } @@ -854,15 +1054,15 @@ public class CompletableFutureTest exten * completion of either source */ public void testApplyToEither2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEither(f2, inc); f.completeExceptionally(new CFException()); f2.complete(one); checkCompletedWithWrappedCFException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.applyToEither(f2, inc); checkCompletedWithWrappedCFException(g); @@ -872,8 +1072,8 @@ public class CompletableFutureTest exten * applyToEither result completes exceptionally if action does */ public void testApplyToEither3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingFunction r = new FailingFunction(); CompletableFuture g = f.applyToEither(f2, r); f2.complete(two); @@ -884,13 +1084,13 @@ public class CompletableFutureTest exten * applyToEither result completes exceptionally if either source cancelled */ public void testApplyToEither4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEither(f2, inc); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); checkCompletedWithWrappedCancellationException(g); } @@ -900,8 +1100,8 @@ public class CompletableFutureTest exten * of either source */ public void testAcceptEither() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEither(f2, r); f.complete(one); @@ -911,9 +1111,9 @@ public class CompletableFutureTest exten assertEquals(r.value, 2); r = new IncAction(); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.acceptEither(f2, r); checkCompletedNormally(g, null); assertEquals(r.value, 2); @@ -924,8 +1124,8 @@ public class CompletableFutureTest exten * completion of either source */ public void testAcceptEither2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEither(f2, r); f.completeExceptionally(new CFException()); @@ -933,8 +1133,8 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(g); r = new IncAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.acceptEither(f2, r); checkCompletedWithWrappedCFException(g); @@ -944,8 +1144,8 @@ public class CompletableFutureTest exten * acceptEither result completes exceptionally if action does */ public void testAcceptEither3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingConsumer r = new FailingConsumer(); CompletableFuture g = f.acceptEither(f2, r); f2.complete(two); @@ -956,26 +1156,25 @@ public class CompletableFutureTest exten * acceptEither result completes exceptionally if either source cancelled */ public void testAcceptEither4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEither(f2, r); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); checkCompletedWithWrappedCancellationException(g); } - /** * runAfterEither result completes normally after normal completion * of either source */ public void testRunAfterEither() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEither(f2, r); f.complete(one); @@ -985,9 +1184,9 @@ public class CompletableFutureTest exten assertTrue(r.ran); r = new Noop(); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.runAfterEither(f2, r); checkCompletedNormally(g, null); assertTrue(r.ran); @@ -998,8 +1197,8 @@ public class CompletableFutureTest exten * completion of either source */ public void testRunAfterEither2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEither(f2, r); f.completeExceptionally(new CFException()); @@ -1007,8 +1206,8 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.runAfterEither(f2, r); checkCompletedWithWrappedCFException(g); @@ -1018,8 +1217,8 @@ public class CompletableFutureTest exten * runAfterEither result completes exceptionally if action does */ public void testRunAfterEither3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingNoop r = new FailingNoop(); CompletableFuture g = f.runAfterEither(f2, r); f2.complete(two); @@ -1030,14 +1229,14 @@ public class CompletableFutureTest exten * runAfterEither result completes exceptionally if either source cancelled */ public void testRunAfterEither4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEither(f2, r); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); checkCompletedWithWrappedCancellationException(g); } @@ -1046,11 +1245,20 @@ public class CompletableFutureTest exten * thenCompose result completes normally after normal completion of source */ public void testThenCompose() { - CompletableFuture f = new CompletableFuture(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenCompose(r); + CompletableFuture f, g; + CompletableFutureInc r; + + f = new CompletableFuture<>(); + g = f.thenCompose(r = new CompletableFutureInc()); f.complete(one); checkCompletedNormally(g, two); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + f.complete(one); + g = f.thenCompose(r = new CompletableFutureInc()); + checkCompletedNormally(g, two); + assertTrue(r.ran); } /** @@ -1058,21 +1266,35 @@ public class CompletableFutureTest exten * completion of source */ public void testThenCompose2() { - CompletableFuture f = new CompletableFuture(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenCompose(r); + CompletableFuture f, g; + CompletableFutureInc r; + + f = new CompletableFuture<>(); + g = f.thenCompose(r = new CompletableFutureInc()); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); + + f = new CompletableFuture<>(); + f.completeExceptionally(new CFException()); + g = f.thenCompose(r = new CompletableFutureInc()); + checkCompletedWithWrappedCFException(g); } /** * thenCompose result completes exceptionally if action does */ public void testThenCompose3() { - CompletableFuture f = new CompletableFuture(); - FailingCompletableFutureFunction r = new FailingCompletableFutureFunction(); - CompletableFuture g = f.thenCompose(r); + CompletableFuture f, g; + FailingCompletableFutureFunction r; + + f = new CompletableFuture<>(); + g = f.thenCompose(r = new FailingCompletableFutureFunction()); + f.complete(one); + checkCompletedWithWrappedCFException(g); + + f = new CompletableFuture<>(); f.complete(one); + g = f.thenCompose(r = new FailingCompletableFutureFunction()); checkCompletedWithWrappedCFException(g); } @@ -1080,13 +1302,19 @@ public class CompletableFutureTest exten * thenCompose result completes exceptionally if source cancelled */ public void testThenCompose4() { - CompletableFuture f = new CompletableFuture(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenCompose(r); + CompletableFuture f, g; + CompletableFutureInc r; + + f = new CompletableFuture<>(); + g = f.thenCompose(r = new CompletableFutureInc()); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); - } + f = new CompletableFuture<>(); + assertTrue(f.cancel(true)); + g = f.thenCompose(r = new CompletableFutureInc()); + checkCompletedWithWrappedCancellationException(g); + } // asyncs @@ -1094,14 +1322,14 @@ public class CompletableFutureTest exten * thenRunAsync result completes normally after normal completion of source */ public void testThenRunAsync() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.thenRunAsync(r); f.complete(null); checkCompletedNormally(g, null); // reordered version - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(null); r = new Noop(); g = f.thenRunAsync(r); @@ -1113,15 +1341,14 @@ public class CompletableFutureTest exten * completion of source */ public void testThenRunAsync2() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.thenRunAsync(r); f.completeExceptionally(new CFException()); try { g.join(); shouldThrow(); - } catch (Exception ok) { - } + } catch (CompletionException success) {} checkCompletedWithWrappedCFException(g); } @@ -1129,7 +1356,7 @@ public class CompletableFutureTest exten * thenRunAsync result completes exceptionally if action does */ public void testThenRunAsync3() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); FailingNoop r = new FailingNoop(); CompletableFuture g = f.thenRunAsync(r); f.complete(null); @@ -1140,7 +1367,7 @@ public class CompletableFutureTest exten * thenRunAsync result completes exceptionally if source cancelled */ public void testThenRunAsync4() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.thenRunAsync(r); assertTrue(f.cancel(true)); @@ -1151,7 +1378,7 @@ public class CompletableFutureTest exten * thenApplyAsync result completes normally after normal completion of source */ public void testThenApplyAsync() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApplyAsync(inc); f.complete(one); checkCompletedNormally(g, two); @@ -1162,7 +1389,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenApplyAsync2() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApplyAsync(inc); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); @@ -1172,7 +1399,7 @@ public class CompletableFutureTest exten * thenApplyAsync result completes exceptionally if action does */ public void testThenApplyAsync3() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); FailingFunction r = new FailingFunction(); CompletableFuture g = f.thenApplyAsync(r); f.complete(null); @@ -1183,7 +1410,7 @@ public class CompletableFutureTest exten * thenApplyAsync result completes exceptionally if source cancelled */ public void testThenApplyAsync4() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApplyAsync(inc); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); @@ -1194,7 +1421,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenAcceptAsync() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAcceptAsync(r); f.complete(one); @@ -1207,7 +1434,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenAcceptAsync2() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAcceptAsync(r); f.completeExceptionally(new CFException()); @@ -1218,7 +1445,7 @@ public class CompletableFutureTest exten * thenAcceptAsync result completes exceptionally if action does */ public void testThenAcceptAsync3() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); FailingConsumer r = new FailingConsumer(); CompletableFuture g = f.thenAcceptAsync(r); f.complete(null); @@ -1229,77 +1456,126 @@ public class CompletableFutureTest exten * thenAcceptAsync result completes exceptionally if source cancelled */ public void testThenAcceptAsync4() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAcceptAsync(r); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); } + /** * thenCombineAsync result completes normally after normal * completion of sources */ public void testThenCombineAsync() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombineAsync(f2, add); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, three); + CompletableFuture f, g, h; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract); + f.complete(3); + checkIncomplete(h); + g.complete(1); + checkCompletedNormally(h, 2); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract); + g.complete(1); + checkIncomplete(h); + f.complete(3); + checkCompletedNormally(h, 2); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + g.complete(1); + f.complete(3); + h = f.thenCombineAsync(g, subtract); + checkCompletedNormally(h, 2); } /** * thenCombineAsync result completes exceptionally after exceptional - * completion of source + * completion of either source */ public void testThenCombineAsync2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombineAsync(f2, add); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + CompletableFuture f, g, h; - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenCombineAsync(f2, add); - f.complete(one); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract); + f.completeExceptionally(new CFException()); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCFException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract); + g.completeExceptionally(new CFException()); + checkIncomplete(h); + f.complete(3); + checkCompletedWithWrappedCFException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + g.completeExceptionally(new CFException()); + f.complete(3); + h = f.thenCombineAsync(g, subtract); + checkCompletedWithWrappedCFException(h); } /** * thenCombineAsync result completes exceptionally if action does */ public void testThenCombineAsync3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingBiFunction r = new FailingBiFunction(); CompletableFuture g = f.thenCombineAsync(f2, r); f.complete(one); checkIncomplete(g); + assertFalse(r.ran); f2.complete(two); checkCompletedWithWrappedCFException(g); + assertTrue(r.ran); } /** * thenCombineAsync result completes exceptionally if either source cancelled */ public void testThenCombineAsync4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombineAsync(f2, add); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); + CompletableFuture f, g, h; - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenCombineAsync(f2, add); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract); + assertTrue(f.cancel(true)); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract); + assertTrue(g.cancel(true)); + checkIncomplete(h); + f.complete(3); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + g.complete(3); + assertTrue(f.cancel(true)); + h = f.thenCombineAsync(g, subtract); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + f.complete(3); + assertTrue(g.cancel(true)); + h = f.thenCombineAsync(g, subtract); + checkCompletedWithWrappedCancellationException(h); } /** @@ -1307,15 +1583,35 @@ public class CompletableFutureTest exten * completion of sources */ public void testThenAcceptBothAsync() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBothAsync(f2, r); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, null); - assertEquals(r.value, 3); + 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); } /** @@ -1323,56 +1619,102 @@ public class CompletableFutureTest exten * completion of source */ public void testThenAcceptBothAsync2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBothAsync(f2, r); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); - - r = new AddAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenAcceptBothAsync(f2, r); - f.complete(one); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); + 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 = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - FailingBiConsumer r = new FailingBiConsumer(); - CompletableFuture g = f.thenAcceptBothAsync(f2, r); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + 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 = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBothAsync(f2, r); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); - - r = new AddAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenAcceptBothAsync(f2, r); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + 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); } /** @@ -1380,8 +1722,8 @@ public class CompletableFutureTest exten * completion of sources */ public void testRunAfterBothAsync() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterBothAsync(f2, r); f.complete(one); @@ -1396,8 +1738,8 @@ public class CompletableFutureTest exten * completion of source */ public void testRunAfterBothAsync2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterBothAsync(f2, r); f.completeExceptionally(new CFException()); @@ -1405,8 +1747,8 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); g = f.runAfterBothAsync(f2, r); f.complete(one); f2.completeExceptionally(new CFException()); @@ -1417,8 +1759,8 @@ public class CompletableFutureTest exten * runAfterBothAsync result completes exceptionally if action does */ public void testRunAfterBothAsync3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingNoop r = new FailingNoop(); CompletableFuture g = f.runAfterBothAsync(f2, r); f.complete(one); @@ -1431,8 +1773,8 @@ public class CompletableFutureTest exten * runAfterBothAsync result completes exceptionally if either source cancelled */ public void testRunAfterBothAsync4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterBothAsync(f2, r); assertTrue(f.cancel(true)); @@ -1440,8 +1782,8 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); g = f.runAfterBothAsync(f2, r); f.complete(one); assertTrue(f2.cancel(true)); @@ -1453,15 +1795,15 @@ public class CompletableFutureTest exten * completion of sources */ public void testApplyToEitherAsync() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEitherAsync(f2, inc); f.complete(one); checkCompletedNormally(g, two); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.applyToEitherAsync(f2, inc); checkCompletedNormally(g, two); } @@ -1471,14 +1813,14 @@ public class CompletableFutureTest exten * completion of source */ public void testApplyToEitherAsync2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEitherAsync(f2, inc); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.applyToEitherAsync(f2, inc); f.complete(one); @@ -1489,8 +1831,8 @@ public class CompletableFutureTest exten * applyToEitherAsync result completes exceptionally if action does */ public void testApplyToEitherAsync3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingFunction r = new FailingFunction(); CompletableFuture g = f.applyToEitherAsync(f2, r); f.complete(one); @@ -1501,14 +1843,14 @@ public class CompletableFutureTest exten * applyToEitherAsync result completes exceptionally if either source cancelled */ public void testApplyToEitherAsync4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEitherAsync(f2, inc); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); g = f.applyToEitherAsync(f2, inc); checkCompletedWithWrappedCancellationException(g); @@ -1519,8 +1861,8 @@ public class CompletableFutureTest exten * completion of sources */ public void testAcceptEitherAsync() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEitherAsync(f2, r); f.complete(one); @@ -1528,9 +1870,9 @@ public class CompletableFutureTest exten assertEquals(r.value, 2); r = new IncAction(); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.acceptEitherAsync(f2, r); checkCompletedNormally(g, null); assertEquals(r.value, 2); @@ -1541,16 +1883,16 @@ public class CompletableFutureTest exten * completion of source */ public void testAcceptEitherAsync2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEitherAsync(f2, r); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); r = new IncAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.acceptEitherAsync(f2, r); f.complete(one); @@ -1561,8 +1903,8 @@ public class CompletableFutureTest exten * acceptEitherAsync result completes exceptionally if action does */ public void testAcceptEitherAsync3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingConsumer r = new FailingConsumer(); CompletableFuture g = f.acceptEitherAsync(f2, r); f.complete(one); @@ -1574,16 +1916,16 @@ public class CompletableFutureTest exten * source cancelled */ public void testAcceptEitherAsync4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEitherAsync(f2, r); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); r = new IncAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); g = f.acceptEitherAsync(f2, r); checkCompletedWithWrappedCancellationException(g); @@ -1594,8 +1936,8 @@ public class CompletableFutureTest exten * completion of sources */ public void testRunAfterEitherAsync() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEitherAsync(f2, r); f.complete(one); @@ -1603,9 +1945,9 @@ public class CompletableFutureTest exten assertTrue(r.ran); r = new Noop(); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.runAfterEitherAsync(f2, r); checkCompletedNormally(g, null); assertTrue(r.ran); @@ -1616,16 +1958,16 @@ public class CompletableFutureTest exten * completion of source */ public void testRunAfterEitherAsync2() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEitherAsync(f2, r); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.runAfterEitherAsync(f2, r); f.complete(one); @@ -1636,8 +1978,8 @@ public class CompletableFutureTest exten * runAfterEitherAsync result completes exceptionally if action does */ public void testRunAfterEitherAsync3() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingNoop r = new FailingNoop(); CompletableFuture g = f.runAfterEitherAsync(f2, r); f.complete(one); @@ -1649,16 +1991,16 @@ public class CompletableFutureTest exten * source cancelled */ public void testRunAfterEitherAsync4() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEitherAsync(f2, r); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); g = f.runAfterEitherAsync(f2, r); checkCompletedWithWrappedCancellationException(g); @@ -1669,10 +2011,17 @@ public class CompletableFutureTest exten * completion of source */ public void testThenComposeAsync() { - CompletableFuture f = new CompletableFuture(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenComposeAsync(r); + CompletableFuture f, g; + CompletableFutureInc r; + + f = new CompletableFuture<>(); + g = f.thenComposeAsync(r = new CompletableFutureInc()); + f.complete(one); + checkCompletedNormally(g, two); + + f = new CompletableFuture<>(); f.complete(one); + g = f.thenComposeAsync(r = new CompletableFutureInc()); checkCompletedNormally(g, two); } @@ -1681,35 +2030,57 @@ public class CompletableFutureTest exten * exceptional completion of source */ public void testThenComposeAsync2() { - CompletableFuture f = new CompletableFuture(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenComposeAsync(r); + CompletableFuture f, g; + CompletableFutureInc r; + + f = new CompletableFuture<>(); + g = f.thenComposeAsync(r = new CompletableFutureInc()); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); + assertFalse(r.ran); + + f = new CompletableFuture<>(); + f.completeExceptionally(new CFException()); + g = f.thenComposeAsync(r = new CompletableFutureInc()); + checkCompletedWithWrappedCFException(g); + assertFalse(r.ran); } /** * thenComposeAsync result completes exceptionally if action does */ public void testThenComposeAsync3() { - CompletableFuture f = new CompletableFuture(); - FailingCompletableFutureFunction r = new FailingCompletableFutureFunction(); - CompletableFuture g = f.thenComposeAsync(r); + CompletableFuture f, g; + FailingCompletableFutureFunction r; + + f = new CompletableFuture<>(); + g = f.thenComposeAsync(r = new FailingCompletableFutureFunction()); f.complete(one); checkCompletedWithWrappedCFException(g); + + f = new CompletableFuture<>(); + f.complete(one); + g = f.thenComposeAsync(r = new FailingCompletableFutureFunction()); + checkCompletedWithWrappedCFException(g); } /** * thenComposeAsync result completes exceptionally if source cancelled */ public void testThenComposeAsync4() { - CompletableFuture f = new CompletableFuture(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenComposeAsync(r); + CompletableFuture f, g; + CompletableFutureInc r; + + f = new CompletableFuture<>(); + g = f.thenComposeAsync(r = new CompletableFutureInc()); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); - } + f = new CompletableFuture<>(); + assertTrue(f.cancel(true)); + g = f.thenComposeAsync(r = new CompletableFutureInc()); + checkCompletedWithWrappedCancellationException(g); + } // async with explicit executors @@ -1717,14 +2088,14 @@ public class CompletableFutureTest exten * thenRunAsync result completes normally after normal completion of source */ public void testThenRunAsyncE() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.thenRunAsync(r, new ThreadExecutor()); f.complete(null); checkCompletedNormally(g, null); // reordered version - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(null); r = new Noop(); g = f.thenRunAsync(r, new ThreadExecutor()); @@ -1736,15 +2107,14 @@ public class CompletableFutureTest exten * completion of source */ public void testThenRunAsync2E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.thenRunAsync(r, new ThreadExecutor()); f.completeExceptionally(new CFException()); try { g.join(); shouldThrow(); - } catch (Exception ok) { - } + } catch (CompletionException success) {} checkCompletedWithWrappedCFException(g); } @@ -1752,7 +2122,7 @@ public class CompletableFutureTest exten * thenRunAsync result completes exceptionally if action does */ public void testThenRunAsync3E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); FailingNoop r = new FailingNoop(); CompletableFuture g = f.thenRunAsync(r, new ThreadExecutor()); f.complete(null); @@ -1763,7 +2133,7 @@ public class CompletableFutureTest exten * thenRunAsync result completes exceptionally if source cancelled */ public void testThenRunAsync4E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.thenRunAsync(r, new ThreadExecutor()); assertTrue(f.cancel(true)); @@ -1774,7 +2144,7 @@ public class CompletableFutureTest exten * thenApplyAsync result completes normally after normal completion of source */ public void testThenApplyAsyncE() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApplyAsync(inc, new ThreadExecutor()); f.complete(one); checkCompletedNormally(g, two); @@ -1785,7 +2155,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenApplyAsync2E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApplyAsync(inc, new ThreadExecutor()); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); @@ -1795,7 +2165,7 @@ public class CompletableFutureTest exten * thenApplyAsync result completes exceptionally if action does */ public void testThenApplyAsync3E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); FailingFunction r = new FailingFunction(); CompletableFuture g = f.thenApplyAsync(r, new ThreadExecutor()); f.complete(null); @@ -1806,7 +2176,7 @@ public class CompletableFutureTest exten * thenApplyAsync result completes exceptionally if source cancelled */ public void testThenApplyAsync4E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFuture g = f.thenApplyAsync(inc, new ThreadExecutor()); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); @@ -1817,7 +2187,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenAcceptAsyncE() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAcceptAsync(r, new ThreadExecutor()); f.complete(one); @@ -1830,7 +2200,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenAcceptAsync2E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAcceptAsync(r, new ThreadExecutor()); f.completeExceptionally(new CFException()); @@ -1841,7 +2211,7 @@ public class CompletableFutureTest exten * thenAcceptAsync result completes exceptionally if action does */ public void testThenAcceptAsync3E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); FailingConsumer r = new FailingConsumer(); CompletableFuture g = f.thenAcceptAsync(r, new ThreadExecutor()); f.complete(null); @@ -1852,77 +2222,140 @@ public class CompletableFutureTest exten * thenAcceptAsync result completes exceptionally if source cancelled */ public void testThenAcceptAsync4E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.thenAcceptAsync(r, new ThreadExecutor()); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); } + /** * thenCombineAsync result completes normally after normal * completion of sources */ public void testThenCombineAsyncE() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombineAsync(f2, add, new ThreadExecutor()); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, three); + CompletableFuture f, g, h; + ThreadExecutor e = new ThreadExecutor(); + int count = 0; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract, e); + f.complete(3); + checkIncomplete(h); + g.complete(1); + checkCompletedNormally(h, 2); + assertEquals(++count, e.count.get()); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract, e); + g.complete(1); + checkIncomplete(h); + f.complete(3); + checkCompletedNormally(h, 2); + assertEquals(++count, e.count.get()); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + g.complete(1); + f.complete(3); + h = f.thenCombineAsync(g, subtract, e); + checkCompletedNormally(h, 2); + assertEquals(++count, e.count.get()); } /** * thenCombineAsync result completes exceptionally after exceptional - * completion of source + * completion of either source */ public void testThenCombineAsync2E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombineAsync(f2, add, new ThreadExecutor()); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + CompletableFuture f, g, h; + ThreadExecutor e = new ThreadExecutor(); + int count = 0; + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract, e); + f.completeExceptionally(new CFException()); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCFException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract, e); + g.completeExceptionally(new CFException()); + checkIncomplete(h); + f.complete(3); + checkCompletedWithWrappedCFException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + g.completeExceptionally(new CFException()); + h = f.thenCombineAsync(g, subtract, e); + checkIncomplete(h); + f.complete(3); + checkCompletedWithWrappedCFException(h); - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenCombineAsync(f2, add, new ThreadExecutor()); - f.complete(one); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); + assertEquals(0, e.count.get()); } /** * thenCombineAsync result completes exceptionally if action does */ public void testThenCombineAsync3E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingBiFunction r = new FailingBiFunction(); CompletableFuture g = f.thenCombineAsync(f2, r, new ThreadExecutor()); f.complete(one); checkIncomplete(g); + assertFalse(r.ran); f2.complete(two); checkCompletedWithWrappedCFException(g); + assertTrue(r.ran); } /** * thenCombineAsync result completes exceptionally if either source cancelled */ public void testThenCombineAsync4E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - CompletableFuture g = f.thenCombineAsync(f2, add, new ThreadExecutor()); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); + CompletableFuture f, g, h; + ThreadExecutor e = new ThreadExecutor(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenCombineAsync(f2, add, new ThreadExecutor()); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract, e); + assertTrue(f.cancel(true)); + checkIncomplete(h); + g.complete(1); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + h = f.thenCombineAsync(g, subtract, e); + assertTrue(g.cancel(true)); + checkIncomplete(h); + f.complete(3); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + assertTrue(g.cancel(true)); + h = f.thenCombineAsync(g, subtract, e); + checkIncomplete(h); + f.complete(3); + checkCompletedWithWrappedCancellationException(h); + + f = new CompletableFuture<>(); + g = new CompletableFuture<>(); + assertTrue(f.cancel(true)); + assertTrue(g.cancel(true)); + h = f.thenCombineAsync(g, subtract, e); + checkCompletedWithWrappedCancellationException(h); + + assertEquals(0, e.count.get()); } /** @@ -1930,15 +2363,38 @@ public class CompletableFutureTest exten * completion of sources */ public void testThenAcceptBothAsyncE() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, null); - assertEquals(r.value, 3); + 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()); } /** @@ -1946,56 +2402,111 @@ public class CompletableFutureTest exten * completion of source */ public void testThenAcceptBothAsync2E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor()); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + 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); - r = new AddAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor()); - f.complete(one); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); + assertEquals(0, e.count.get()); } /** * thenAcceptBothAsync result completes exceptionally if action does */ public void testThenAcceptBothAsync3E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - FailingBiConsumer r = new FailingBiConsumer(); - CompletableFuture g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + 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 = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); - AddAction r = new AddAction(); - CompletableFuture g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor()); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); + 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); - r = new AddAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); - g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor()); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + assertEquals(0, e.count.get()); } /** @@ -2003,8 +2514,8 @@ public class CompletableFutureTest exten * completion of sources */ public void testRunAfterBothAsyncE() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2019,8 +2530,8 @@ public class CompletableFutureTest exten * completion of source */ public void testRunAfterBothAsync2E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); f.completeExceptionally(new CFException()); @@ -2028,8 +2539,8 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); f.complete(one); f2.completeExceptionally(new CFException()); @@ -2040,8 +2551,8 @@ public class CompletableFutureTest exten * runAfterBothAsync result completes exceptionally if action does */ public void testRunAfterBothAsync3E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingNoop r = new FailingNoop(); CompletableFuture g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2054,8 +2565,8 @@ public class CompletableFutureTest exten * runAfterBothAsync result completes exceptionally if either source cancelled */ public void testRunAfterBothAsync4E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); assertTrue(f.cancel(true)); @@ -2063,8 +2574,8 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); f.complete(one); assertTrue(f2.cancel(true)); @@ -2076,15 +2587,15 @@ public class CompletableFutureTest exten * completion of sources */ public void testApplyToEitherAsyncE() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); f.complete(one); checkCompletedNormally(g, two); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); checkCompletedNormally(g, two); } @@ -2094,14 +2605,14 @@ public class CompletableFutureTest exten * completion of source */ public void testApplyToEitherAsync2E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); f.complete(one); @@ -2112,8 +2623,8 @@ public class CompletableFutureTest exten * applyToEitherAsync result completes exceptionally if action does */ public void testApplyToEitherAsync3E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingFunction r = new FailingFunction(); CompletableFuture g = f.applyToEitherAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2124,14 +2635,14 @@ public class CompletableFutureTest exten * applyToEitherAsync result completes exceptionally if either source cancelled */ public void testApplyToEitherAsync4E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); CompletableFuture g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); checkCompletedWithWrappedCancellationException(g); @@ -2142,8 +2653,8 @@ public class CompletableFutureTest exten * completion of sources */ public void testAcceptEitherAsyncE() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2151,9 +2662,9 @@ public class CompletableFutureTest exten assertEquals(r.value, 2); r = new IncAction(); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); checkCompletedNormally(g, null); assertEquals(r.value, 2); @@ -2164,16 +2675,16 @@ public class CompletableFutureTest exten * completion of source */ public void testAcceptEitherAsync2E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); r = new IncAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2184,8 +2695,8 @@ public class CompletableFutureTest exten * acceptEitherAsync result completes exceptionally if action does */ public void testAcceptEitherAsync3E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingConsumer r = new FailingConsumer(); CompletableFuture g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2197,16 +2708,16 @@ public class CompletableFutureTest exten * source cancelled */ public void testAcceptEitherAsync4E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); IncAction r = new IncAction(); CompletableFuture g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); r = new IncAction(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); checkCompletedWithWrappedCancellationException(g); @@ -2217,8 +2728,8 @@ public class CompletableFutureTest exten * completion of sources */ public void testRunAfterEitherAsyncE() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2226,9 +2737,9 @@ public class CompletableFutureTest exten assertTrue(r.ran); r = new Noop(); - f = new CompletableFuture(); + f = new CompletableFuture<>(); f.complete(one); - f2 = new CompletableFuture(); + f2 = new CompletableFuture<>(); g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); checkCompletedNormally(g, null); assertTrue(r.ran); @@ -2239,16 +2750,16 @@ public class CompletableFutureTest exten * completion of source */ public void testRunAfterEitherAsync2E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); f2.completeExceptionally(new CFException()); g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2259,8 +2770,8 @@ public class CompletableFutureTest exten * runAfterEitherAsync result completes exceptionally if action does */ public void testRunAfterEitherAsync3E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); FailingNoop r = new FailingNoop(); CompletableFuture g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); f.complete(one); @@ -2272,16 +2783,16 @@ public class CompletableFutureTest exten * source cancelled */ public void testRunAfterEitherAsync4E() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture f2 = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture f2 = new CompletableFuture<>(); Noop r = new Noop(); CompletableFuture g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); assertTrue(f.cancel(true)); checkCompletedWithWrappedCancellationException(g); r = new Noop(); - f = new CompletableFuture(); - f2 = new CompletableFuture(); + f = new CompletableFuture<>(); + f2 = new CompletableFuture<>(); assertTrue(f2.cancel(true)); g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); checkCompletedWithWrappedCancellationException(g); @@ -2292,7 +2803,7 @@ public class CompletableFutureTest exten * completion of source */ public void testThenComposeAsyncE() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFutureInc r = new CompletableFutureInc(); CompletableFuture g = f.thenComposeAsync(r, new ThreadExecutor()); f.complete(one); @@ -2304,7 +2815,7 @@ public class CompletableFutureTest exten * exceptional completion of source */ public void testThenComposeAsync2E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFutureInc r = new CompletableFutureInc(); CompletableFuture g = f.thenComposeAsync(r, new ThreadExecutor()); f.completeExceptionally(new CFException()); @@ -2315,7 +2826,7 @@ public class CompletableFutureTest exten * thenComposeAsync result completes exceptionally if action does */ public void testThenComposeAsync3E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); FailingCompletableFutureFunction r = new FailingCompletableFutureFunction(); CompletableFuture g = f.thenComposeAsync(r, new ThreadExecutor()); f.complete(one); @@ -2326,7 +2837,7 @@ public class CompletableFutureTest exten * thenComposeAsync result completes exceptionally if source cancelled */ public void testThenComposeAsync4E() { - CompletableFuture f = new CompletableFuture(); + CompletableFuture f = new CompletableFuture<>(); CompletableFutureInc r = new CompletableFutureInc(); CompletableFuture g = f.thenComposeAsync(r, new ThreadExecutor()); assertTrue(f.cancel(true)); @@ -2340,24 +2851,27 @@ public class CompletableFutureTest exten * with the value null */ public void testAllOf_empty() throws Exception { - CompletableFuture f = CompletableFuture.allOf(); + CompletableFuture f = CompletableFuture.allOf(); checkCompletedNormally(f, null); } /** - * allOf returns a future completed when all components complete + * allOf returns a future completed normally with the value null + * when all components complete normally */ - public void testAllOf() throws Exception { + public void testAllOf_normal() throws Exception { for (int k = 1; k < 20; ++k) { - CompletableFuture[] fs = new CompletableFuture[k]; + CompletableFuture[] fs = (CompletableFuture[]) new CompletableFuture[k]; for (int i = 0; i < k; ++i) - fs[i] = new CompletableFuture(); + fs[i] = new CompletableFuture<>(); CompletableFuture f = CompletableFuture.allOf(fs); for (int i = 0; i < k; ++i) { checkIncomplete(f); + checkIncomplete(CompletableFuture.allOf(fs)); fs[i].complete(one); } checkCompletedNormally(f, null); + checkCompletedNormally(CompletableFuture.allOf(fs), null); } } @@ -2365,23 +2879,43 @@ public class CompletableFutureTest exten * anyOf(no component futures) returns an incomplete future */ public void testAnyOf_empty() throws Exception { - CompletableFuture f = CompletableFuture.anyOf(); + CompletableFuture f = CompletableFuture.anyOf(); checkIncomplete(f); } /** - * allOf returns a future completed when any components complete + * anyOf returns a future completed normally with a value when + * a component future does */ - public void testAnyOf() throws Exception { - for (int k = 1; k < 20; ++k) { + public void testAnyOf_normal() throws Exception { + for (int k = 0; k < 10; ++k) { CompletableFuture[] fs = new CompletableFuture[k]; for (int i = 0; i < k; ++i) - fs[i] = new CompletableFuture(); + fs[i] = new CompletableFuture<>(); CompletableFuture f = CompletableFuture.anyOf(fs); checkIncomplete(f); for (int i = 0; i < k; ++i) { fs[i].complete(one); checkCompletedNormally(f, one); + checkCompletedNormally(CompletableFuture.anyOf(fs), one); + } + } + } + + /** + * anyOf result completes exceptionally when any component does. + */ + public void testAnyOf_exceptional() throws Exception { + for (int k = 0; k < 10; ++k) { + CompletableFuture[] fs = new CompletableFuture[k]; + for (int i = 0; i < k; ++i) + fs[i] = new CompletableFuture<>(); + CompletableFuture f = CompletableFuture.anyOf(fs); + checkIncomplete(f); + for (int i = 0; i < k; ++i) { + fs[i].completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(f); + checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs)); } } } @@ -2390,41 +2924,337 @@ public class CompletableFutureTest exten * Completion methods throw NullPointerException with null arguments */ public void testNPE() { - CompletableFuture f = new CompletableFuture(); - CompletableFuture g = new CompletableFuture(); - CompletableFuture h; - try { h = f.thenApply(null); } catch (NullPointerException ok) {} - try { h = f.thenAccept(null); } catch (NullPointerException ok) {} - try { h = f.thenRun(null); } catch (NullPointerException ok) {} - try { h = f.thenCombine(g, null); } catch (NullPointerException ok) {} - try { h = f.thenCombine(null, null); } catch (NullPointerException ok) {} - try { h = f.applyToEither(g, null); } catch (NullPointerException ok) {} - try { h = f.applyToEither(null, null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptBoth(g, null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptBoth(null, null); } catch (NullPointerException ok) {} - try { h = f.runAfterEither(g, null); } catch (NullPointerException ok) {} - try { h = f.runAfterEither(null, null); } catch (NullPointerException ok) {} - try { h = f.runAfterBoth(g, null); } catch (NullPointerException ok) {} - try { h = f.runAfterBoth(null, null); } catch (NullPointerException ok) {} - try { h = f.exceptionally(null); } catch (NullPointerException ok) {} - try { h = f.handle(null); } catch (NullPointerException ok) {} - try { h = f.thenCompose(null); } catch (NullPointerException ok) {} - - try { h = f.thenApplyAsync(null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptAsync(null); } catch (NullPointerException ok) {} - try { h = f.thenRunAsync(null); } catch (NullPointerException ok) {} - try { h = f.thenCombineAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.thenCombineAsync(null, null); } catch (NullPointerException ok) {} - try { h = f.applyToEitherAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.applyToEitherAsync(null, null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptBothAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptBothAsync(null, null); } catch (NullPointerException ok) {} - try { h = f.runAfterEitherAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.runAfterEitherAsync(null, null); } catch (NullPointerException ok) {} - try { h = f.runAfterBothAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.runAfterBothAsync(null, null); } catch (NullPointerException ok) {} + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = new CompletableFuture<>(); + CompletableFuture nullFuture = (CompletableFuture)null; + CompletableFuture h; + ThreadExecutor exec = new ThreadExecutor(); + + Runnable[] throwingActions = { + () -> { CompletableFuture.supplyAsync(null); }, + () -> { CompletableFuture.supplyAsync(null, exec); }, + () -> { CompletableFuture.supplyAsync(supplyOne, null); }, + + () -> { CompletableFuture.runAsync(null); }, + () -> { CompletableFuture.runAsync(null, exec); }, + () -> { CompletableFuture.runAsync(() -> {}, null); }, + + () -> { f.completeExceptionally(null); }, + + () -> { f.thenApply(null); }, + () -> { f.thenApplyAsync(null); }, + () -> { f.thenApplyAsync((x) -> x, null); }, + () -> { f.thenApplyAsync(null, exec); }, + + () -> { f.thenAccept(null); }, + () -> { f.thenAcceptAsync(null); }, + () -> { f.thenAcceptAsync((x) -> { ; }, null); }, + () -> { f.thenAcceptAsync(null, exec); }, + + () -> { f.thenRun(null); }, + () -> { f.thenRunAsync(null); }, + () -> { f.thenRunAsync(() -> { ; }, null); }, + () -> { f.thenRunAsync(null, exec); }, + + () -> { f.thenCombine(g, null); }, + () -> { f.thenCombineAsync(g, null); }, + () -> { f.thenCombineAsync(g, null, exec); }, + () -> { f.thenCombine(nullFuture, (x, y) -> x); }, + () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); }, + () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); }, + () -> { f.thenCombineAsync(g, (x, y) -> x, null); }, + + () -> { f.thenAcceptBoth(g, null); }, + () -> { f.thenAcceptBothAsync(g, null); }, + () -> { f.thenAcceptBothAsync(g, null, exec); }, + () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); }, + () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); }, + () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); }, + () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); }, + + () -> { f.runAfterBoth(g, null); }, + () -> { f.runAfterBothAsync(g, null); }, + () -> { f.runAfterBothAsync(g, null, exec); }, + () -> { f.runAfterBoth(nullFuture, () -> {}); }, + () -> { f.runAfterBothAsync(nullFuture, () -> {}); }, + () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); }, + () -> { f.runAfterBothAsync(g, () -> {}, null); }, + + () -> { f.applyToEither(g, null); }, + () -> { f.applyToEitherAsync(g, null); }, + () -> { f.applyToEitherAsync(g, null, exec); }, + () -> { f.applyToEither(nullFuture, (x) -> x); }, + () -> { f.applyToEitherAsync(nullFuture, (x) -> x); }, + () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); }, + () -> { f.applyToEitherAsync(g, (x) -> x, null); }, + + () -> { f.acceptEither(g, null); }, + () -> { f.acceptEitherAsync(g, null); }, + () -> { f.acceptEitherAsync(g, null, exec); }, + () -> { f.acceptEither(nullFuture, (x) -> {}); }, + () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); }, + () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); }, + () -> { f.acceptEitherAsync(g, (x) -> {}, null); }, + + () -> { f.runAfterEither(g, null); }, + () -> { f.runAfterEitherAsync(g, null); }, + () -> { f.runAfterEitherAsync(g, null, exec); }, + () -> { f.runAfterEither(nullFuture, () -> {}); }, + () -> { f.runAfterEitherAsync(nullFuture, () -> {}); }, + () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); }, + () -> { f.runAfterEitherAsync(g, () -> {}, null); }, + + () -> { f.thenCompose(null); }, + () -> { f.thenComposeAsync(null); }, + () -> { f.thenComposeAsync(new CompletableFutureInc(), null); }, + () -> { f.thenComposeAsync(null, exec); }, + + () -> { f.exceptionally(null); }, + + () -> { f.handle(null); }, + + () -> { CompletableFuture.allOf((CompletableFuture)null); }, + () -> { CompletableFuture.allOf((CompletableFuture[])null); }, + () -> { CompletableFuture.allOf(f, null); }, + () -> { CompletableFuture.allOf(null, f); }, + + () -> { CompletableFuture.anyOf((CompletableFuture)null); }, + () -> { CompletableFuture.anyOf((CompletableFuture[])null); }, + () -> { CompletableFuture.anyOf(f, null); }, + () -> { CompletableFuture.anyOf(null, f); }, + }; + + assertThrows(NullPointerException.class, throwingActions); + assertEquals(0, exec.count.get()); + } + + /** + * toCompletableFuture returns this CompletableFuture. + */ + public void testToCompletableFuture() { + CompletableFuture f = new CompletableFuture<>(); + assertSame(f, f.toCompletableFuture()); + } + + /** + * whenComplete action executes on normal completion, propagating + * source result. + */ + public void testWhenComplete1() { + final AtomicInteger a = new AtomicInteger(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenComplete((Integer x, Throwable t) -> a.getAndIncrement()); + f.complete(three); + checkCompletedNormally(f, three); + checkCompletedNormally(g, three); + assertEquals(a.get(), 1); + } + + /** + * whenComplete action executes on exceptional completion, propagating + * source result. + */ + public void testWhenComplete2() { + final AtomicInteger a = new AtomicInteger(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenComplete((Integer x, Throwable t) -> a.getAndIncrement()); + f.completeExceptionally(new CFException()); + assertTrue(f.isCompletedExceptionally()); + assertTrue(g.isCompletedExceptionally()); + assertEquals(a.get(), 1); + } + /** + * If a whenComplete action throws an exception when triggered by + * a normal completion, it completes exceptionally + */ + public void testWhenComplete3() { + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenComplete((Integer x, Throwable t) -> + { throw new CFException(); } ); + f.complete(three); + checkCompletedNormally(f, three); + assertTrue(g.isCompletedExceptionally()); + checkCompletedWithWrappedCFException(g); + } + + /** + * whenCompleteAsync action executes on normal completion, propagating + * source result. + */ + public void testWhenCompleteAsync1() { + final AtomicInteger a = new AtomicInteger(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement()); + f.complete(three); + checkCompletedNormally(f, three); + checkCompletedNormally(g, three); + assertEquals(a.get(), 1); + } + + /** + * whenCompleteAsync action executes on exceptional completion, propagating + * source result. + */ + public void testWhenCompleteAsync2() { + final AtomicInteger a = new AtomicInteger(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement()); + f.completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(f); + checkCompletedWithWrappedCFException(g); + } + + /** + * If a whenCompleteAsync action throws an exception when + * triggered by a normal completion, it completes exceptionally + */ + public void testWhenCompleteAsync3() { + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenCompleteAsync((Integer x, Throwable t) -> + { throw new CFException(); } ); + f.complete(three); + checkCompletedNormally(f, three); + checkCompletedWithWrappedCFException(g); + } + + /** + * whenCompleteAsync action executes on normal completion, propagating + * source result. + */ + public void testWhenCompleteAsync1e() { + final AtomicInteger a = new AtomicInteger(); + ThreadExecutor exec = new ThreadExecutor(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement(), + exec); + f.complete(three); + checkCompletedNormally(f, three); + checkCompletedNormally(g, three); + assertEquals(a.get(), 1); + } + + /** + * whenCompleteAsync action executes on exceptional completion, propagating + * source result. + */ + public void testWhenCompleteAsync2e() { + final AtomicInteger a = new AtomicInteger(); + ThreadExecutor exec = new ThreadExecutor(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement(), + exec); + f.completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(f); + checkCompletedWithWrappedCFException(g); } + /** + * If a whenCompleteAsync action throws an exception when triggered + * by a normal completion, it completes exceptionally + */ + public void testWhenCompleteAsync3e() { + ThreadExecutor exec = new ThreadExecutor(); + CompletableFuture f = new CompletableFuture<>(); + CompletableFuture g = + f.whenCompleteAsync((Integer x, Throwable t) -> + { throw new CFException(); }, + exec); + f.complete(three); + checkCompletedNormally(f, three); + checkCompletedWithWrappedCFException(g); + } + + /** + * handleAsync action completes normally with function value on + * either normal or exceptional completion of source + */ + public void testHandleAsync() { + CompletableFuture f, g; + IntegerHandler r; + + f = new CompletableFuture<>(); + g = f.handleAsync(r = new IntegerHandler()); + assertFalse(r.ran); + f.completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(f); + checkCompletedNormally(g, three); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + g = f.handleAsync(r = new IntegerHandler()); + assertFalse(r.ran); + f.completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(f); + checkCompletedNormally(g, three); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + g = f.handleAsync(r = new IntegerHandler()); + assertFalse(r.ran); + f.complete(one); + checkCompletedNormally(f, one); + checkCompletedNormally(g, two); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + g = f.handleAsync(r = new IntegerHandler()); + assertFalse(r.ran); + f.complete(one); + checkCompletedNormally(f, one); + checkCompletedNormally(g, two); + assertTrue(r.ran); + } + + /** + * handleAsync action with Executor completes normally with + * function value on either normal or exceptional completion of + * source + */ + public void testHandleAsync2() { + CompletableFuture f, g; + ThreadExecutor exec = new ThreadExecutor(); + IntegerHandler r; + + f = new CompletableFuture<>(); + g = f.handleAsync(r = new IntegerHandler(), exec); + assertFalse(r.ran); + f.completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(f); + checkCompletedNormally(g, three); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + g = f.handleAsync(r = new IntegerHandler(), exec); + assertFalse(r.ran); + f.completeExceptionally(new CFException()); + checkCompletedWithWrappedCFException(f); + checkCompletedNormally(g, three); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + g = f.handleAsync(r = new IntegerHandler(), exec); + assertFalse(r.ran); + f.complete(one); + checkCompletedNormally(f, one); + checkCompletedNormally(g, two); + assertTrue(r.ran); + + f = new CompletableFuture<>(); + g = f.handleAsync(r = new IntegerHandler(), exec); + assertFalse(r.ran); + f.complete(one); + checkCompletedNormally(f, one); + checkCompletedNormally(g, two); + assertTrue(r.ran); + } }