--- jsr166/src/test/tck/CompletableFutureTest.java 2014/06/02 04:13:54 1.43 +++ jsr166/src/test/tck/CompletableFutureTest.java 2014/06/02 17:41:22 1.46 @@ -247,6 +247,8 @@ public class CompletableFutureTest exten f = new CompletableFuture<>(); f.obtrudeValue(three); checkCompletedNormally(f, three); + f.obtrudeValue(null); + checkCompletedNormally(f, null); f = new CompletableFuture<>(); f.completeExceptionally(new CFException()); f.obtrudeValue(four); @@ -279,16 +281,16 @@ public class CompletableFutureTest exten */ public void testGetNumberOfDependents() { CompletableFuture f = new CompletableFuture<>(); - assertEquals(f.getNumberOfDependents(), 0); + assertEquals(0, f.getNumberOfDependents()); CompletableFuture g = f.thenRun(new Noop()); - assertEquals(f.getNumberOfDependents(), 1); - assertEquals(g.getNumberOfDependents(), 0); + assertEquals(1, f.getNumberOfDependents()); + assertEquals(0, g.getNumberOfDependents()); CompletableFuture h = f.thenRun(new Noop()); - assertEquals(f.getNumberOfDependents(), 2); + assertEquals(2, f.getNumberOfDependents()); f.complete(1); checkCompletedNormally(g, null); - assertEquals(f.getNumberOfDependents(), 0); - assertEquals(g.getNumberOfDependents(), 0); + assertEquals(0, f.getNumberOfDependents()); + assertEquals(0, g.getNumberOfDependents()); } /** @@ -339,7 +341,6 @@ public class CompletableFutureTest exten static final class IncAction implements Consumer { int invocationCount = 0; Integer value; - public boolean ran() { return invocationCount == 1; } public void accept(Integer x) { invocationCount++; value = inc(x); @@ -348,7 +349,6 @@ public class CompletableFutureTest exten static final class IncFunction implements Function { int invocationCount = 0; Integer value; - public boolean ran() { return invocationCount == 1; } public Integer apply(Integer x) { invocationCount++; return value = inc(x); @@ -358,7 +358,6 @@ public class CompletableFutureTest exten int invocationCount = 0; Integer value; // Check this action was invoked exactly once when result is computed. - public boolean ran() { return invocationCount == 1; } public void accept(Integer x, Integer y) { invocationCount++; value = subtract(x, y); @@ -368,7 +367,6 @@ public class CompletableFutureTest exten int invocationCount = 0; Integer value; // Check this action was invoked exactly once when result is computed. - public boolean ran() { return invocationCount == 1; } public Integer apply(Integer x, Integer y) { invocationCount++; return value = subtract(x, y); @@ -376,54 +374,71 @@ public class CompletableFutureTest exten } static final class Noop implements Runnable { int invocationCount = 0; - boolean ran; public void run() { invocationCount++; - ran = true; } } static final class FailingSupplier implements Supplier { - boolean ran; - public Integer get() { ran = true; throw new CFException(); } + int invocationCount = 0; + public Integer get() { + invocationCount++; + throw new CFException(); + } } static final class FailingConsumer implements Consumer { - boolean ran; - public void accept(Integer x) { ran = true; throw new CFException(); } + int invocationCount = 0; + public void accept(Integer x) { + invocationCount++; + throw new CFException(); + } } static final class FailingBiConsumer implements BiConsumer { - boolean ran; - public void accept(Integer x, Integer y) { ran = true; throw new CFException(); } + int invocationCount = 0; + public void accept(Integer x, Integer y) { + invocationCount++; + throw new CFException(); + } } static final class FailingFunction implements Function { - boolean ran; - public Integer apply(Integer x) { ran = true; throw new CFException(); } + int invocationCount = 0; + public Integer apply(Integer x) { + invocationCount++; + throw new CFException(); + } } static final class FailingBiFunction implements BiFunction { - boolean ran; - public Integer apply(Integer x, Integer y) { ran = true; throw new CFException(); } + int invocationCount = 0; + public Integer apply(Integer x, Integer y) { + invocationCount++; + throw new CFException(); + } } static final class FailingNoop implements Runnable { - boolean ran; - public void run() { ran = true; throw new CFException(); } + int invocationCount = 0; + public void run() { + invocationCount++; + throw new CFException(); + } } static final class CompletableFutureInc implements Function> { - boolean ran; + int invocationCount = 0; public CompletableFuture apply(Integer x) { - ran = true; + invocationCount++; CompletableFuture f = new CompletableFuture<>(); - f.complete(Integer.valueOf(x.intValue() + 1)); + f.complete(inc(x)); return f; } } static final class FailingCompletableFutureFunction implements Function> { - boolean ran; + int invocationCount = 0; public CompletableFuture apply(Integer x) { - ran = true; throw new CFException(); + invocationCount++; + throw new CFException(); } } @@ -437,24 +452,39 @@ public class CompletableFutureTest exten } } - static final class ExceptionToInteger implements Function { - public Integer apply(Throwable x) { return Integer.valueOf(3); } - } - - static final class IntegerHandler implements BiFunction { - boolean ran; - public Integer apply(Integer x, Throwable t) { - ran = true; - return (t == null) ? two : three; - } - } - /** * Permits the testing of parallel code for the 3 different * execution modes without repeating all the testing code. */ enum ExecutionMode { DEFAULT { + public CompletableFuture thenRun + (CompletableFuture f, Runnable a) { + return f.thenRun(a); + } + public CompletableFuture thenAccept + (CompletableFuture f, Consumer a) { + return f.thenAccept(a); + } + public CompletableFuture thenApply + (CompletableFuture f, Function a) { + return f.thenApply(a); + } + public CompletableFuture thenCompose + (CompletableFuture f, + Function> a) { + return f.thenCompose(a); + } + public CompletableFuture handle + (CompletableFuture f, + BiFunction a) { + return f.handle(a); + } + public CompletableFuture whenComplete + (CompletableFuture f, + BiConsumer a) { + return f.whenComplete(a); + } public CompletableFuture runAfterBoth (CompletableFuture f, CompletableFuture g, Runnable a) { return f.runAfterBoth(g, a); @@ -471,11 +501,11 @@ public class CompletableFutureTest exten BiFunction a) { return f.thenCombine(g, a); } - public CompletableFuture applyToEither + public CompletableFuture runAfterEither (CompletableFuture f, - CompletionStage g, - Function a) { - return f.applyToEither(g, a); + CompletionStage g, + java.lang.Runnable a) { + return f.runAfterEither(g, a); } public CompletableFuture acceptEither (CompletableFuture f, @@ -483,39 +513,42 @@ public class CompletableFutureTest exten Consumer a) { return f.acceptEither(g, a); } - public CompletableFuture runAfterEither + public CompletableFuture applyToEither (CompletableFuture f, - CompletionStage g, - java.lang.Runnable a) { - return f.runAfterEither(g, a); + CompletionStage g, + Function a) { + return f.applyToEither(g, a); + } + }, + + DEFAULT_ASYNC { + public CompletableFuture thenRun + (CompletableFuture f, Runnable a) { + return f.thenRunAsync(a); + } + public CompletableFuture thenAccept + (CompletableFuture f, Consumer a) { + return f.thenAcceptAsync(a); + } + public CompletableFuture thenApply + (CompletableFuture f, Function a) { + return f.thenApplyAsync(a); } public CompletableFuture thenCompose (CompletableFuture f, Function> a) { - return f.thenCompose(a); + return f.thenComposeAsync(a); + } + public CompletableFuture handle + (CompletableFuture f, + BiFunction a) { + return f.handleAsync(a); } public CompletableFuture whenComplete (CompletableFuture f, BiConsumer a) { - return f.whenComplete(a); + return f.whenCompleteAsync(a); } - }, - -// /** Experimental way to do more testing */ -// REVERSE_DEFAULT { -// public CompletableFuture runAfterBoth -// (CompletableFuture f, CompletableFuture g, Runnable a) { -// return g.runAfterBoth(f, a); -// } -// public CompletableFuture thenAcceptBoth -// (CompletableFuture f, -// CompletionStage g, -// BiConsumer a) { -// return DEFAULT.thenAcceptBoth(f, g, a); -// } -// }, - - DEFAULT_ASYNC { public CompletableFuture runAfterBoth (CompletableFuture f, CompletableFuture g, Runnable a) { return f.runAfterBothAsync(g, a); @@ -532,11 +565,11 @@ public class CompletableFutureTest exten BiFunction a) { return f.thenCombineAsync(g, a); } - public CompletableFuture applyToEither + public CompletableFuture runAfterEither (CompletableFuture f, - CompletionStage g, - Function a) { - return f.applyToEitherAsync(g, a); + CompletionStage g, + java.lang.Runnable a) { + return f.runAfterEitherAsync(g, a); } public CompletableFuture acceptEither (CompletableFuture f, @@ -544,38 +577,42 @@ public class CompletableFutureTest exten Consumer a) { return f.acceptEitherAsync(g, a); } - public CompletableFuture runAfterEither + public CompletableFuture applyToEither (CompletableFuture f, - CompletionStage g, - java.lang.Runnable a) { - return f.runAfterEitherAsync(g, a); + CompletionStage g, + Function a) { + return f.applyToEitherAsync(g, a); + } + }, + + EXECUTOR { + public CompletableFuture thenRun + (CompletableFuture f, Runnable a) { + return f.thenRunAsync(a, new ThreadExecutor()); + } + public CompletableFuture thenAccept + (CompletableFuture f, Consumer a) { + return f.thenAcceptAsync(a, new ThreadExecutor()); + } + public CompletableFuture thenApply + (CompletableFuture f, Function a) { + return f.thenApplyAsync(a, new ThreadExecutor()); } public CompletableFuture thenCompose (CompletableFuture f, Function> a) { - return f.thenComposeAsync(a); + return f.thenComposeAsync(a, new ThreadExecutor()); + } + public CompletableFuture handle + (CompletableFuture f, + BiFunction a) { + return f.handleAsync(a, new ThreadExecutor()); } public CompletableFuture whenComplete (CompletableFuture f, BiConsumer a) { - return f.whenCompleteAsync(a); + return f.whenCompleteAsync(a, new ThreadExecutor()); } - }, - -// REVERSE_DEFAULT_ASYNC { -// public CompletableFuture runAfterBoth -// (CompletableFuture f, CompletableFuture g, Runnable a) { -// return f.runAfterBothAsync(g, a); -// } -// public CompletableFuture thenAcceptBoth -// (CompletableFuture f, -// CompletionStage g, -// BiConsumer a) { -// return DEFAULT_ASYNC.thenAcceptBoth(f, g, a); -// } -// }, - - EXECUTOR { public CompletableFuture runAfterBoth (CompletableFuture f, CompletableFuture g, Runnable a) { return f.runAfterBothAsync(g, a, new ThreadExecutor()); @@ -592,36 +629,41 @@ public class CompletableFutureTest exten BiFunction a) { return f.thenCombineAsync(g, a, new ThreadExecutor()); } - public CompletableFuture applyToEither - (CompletableFuture f, - CompletionStage g, - Function a) { - return f.applyToEitherAsync(g, a, new ThreadExecutor()); - } - public CompletableFuture acceptEither - (CompletableFuture f, - CompletionStage g, - Consumer a) { - return f.acceptEitherAsync(g, a, new ThreadExecutor()); - } public CompletableFuture runAfterEither (CompletableFuture f, CompletionStage g, java.lang.Runnable a) { return f.runAfterEitherAsync(g, a, new ThreadExecutor()); } - public CompletableFuture thenCompose + public CompletableFuture acceptEither (CompletableFuture f, - Function> a) { - return f.thenComposeAsync(a, new ThreadExecutor()); + CompletionStage g, + Consumer a) { + return f.acceptEitherAsync(g, a, new ThreadExecutor()); } - public CompletableFuture whenComplete + public CompletableFuture applyToEither (CompletableFuture f, - BiConsumer a) { - return f.whenCompleteAsync(a, new ThreadExecutor()); + CompletionStage g, + Function a) { + return f.applyToEitherAsync(g, a, new ThreadExecutor()); } }; + public abstract CompletableFuture thenRun + (CompletableFuture f, Runnable a); + public abstract CompletableFuture thenAccept + (CompletableFuture f, Consumer a); + public abstract CompletableFuture thenApply + (CompletableFuture f, Function a); + public abstract CompletableFuture thenCompose + (CompletableFuture f, + Function> a); + public abstract CompletableFuture handle + (CompletableFuture f, + BiFunction a); + public abstract CompletableFuture whenComplete + (CompletableFuture f, + BiConsumer a); public abstract CompletableFuture runAfterBoth (CompletableFuture f, CompletableFuture g, Runnable a); public abstract CompletableFuture thenAcceptBoth @@ -632,80 +674,223 @@ public class CompletableFutureTest exten (CompletableFuture f, CompletionStage g, BiFunction a); - public abstract CompletableFuture applyToEither - (CompletableFuture f, - CompletionStage g, - Function a); - public abstract CompletableFuture acceptEither - (CompletableFuture f, - CompletionStage g, - Consumer a); public abstract CompletableFuture runAfterEither (CompletableFuture f, CompletionStage g, java.lang.Runnable a); - public abstract CompletableFuture thenCompose + public abstract CompletableFuture acceptEither (CompletableFuture f, - Function> a); - public abstract CompletableFuture whenComplete + CompletionStage g, + Consumer a); + public abstract CompletableFuture applyToEither (CompletableFuture f, - BiConsumer a); + CompletionStage g, + Function a); + } + + /** + * exceptionally action is not invoked when source completes + * normally, and source result is propagated + */ + public void testExceptionally_normalCompletion() { + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final AtomicInteger a = new AtomicInteger(0); + final CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) f.complete(v1); + final CompletableFuture g = f.exceptionally + ((Throwable t) -> { + // Should not be called + a.getAndIncrement(); + throw new AssertionError(); + }); + if (createIncomplete) f.complete(v1); + checkCompletedNormally(g, v1); + checkCompletedNormally(f, v1); + assertEquals(0, a.get()); + }} - } /** * exceptionally action completes with function value on source - * exception; otherwise with source value + * exception */ - public void testExceptionally() { - CompletableFuture f = new CompletableFuture<>(); - ExceptionToInteger r = new ExceptionToInteger(); - CompletableFuture g = f.exceptionally(r); - f.completeExceptionally(new CFException()); - checkCompletedNormally(g, three); + public void testExceptionally_exceptionalCompletion() { + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final AtomicInteger a = new AtomicInteger(0); + final CFException ex = new CFException(); + final CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) f.completeExceptionally(ex); + final CompletableFuture g = f.exceptionally + ((Throwable t) -> { + threadAssertSame(t, ex); + a.getAndIncrement(); + return v1; + }); + if (createIncomplete) f.completeExceptionally(ex); - f = new CompletableFuture<>(); - r = new ExceptionToInteger(); - g = f.exceptionally(r); - f.complete(one); - checkCompletedNormally(g, one); - } + checkCompletedNormally(g, v1); + assertEquals(1, a.get()); + }} + + public void testExceptionally_exceptionalCompletionActionFailed() { + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final AtomicInteger a = new AtomicInteger(0); + final CFException ex1 = new CFException(); + final CFException ex2 = new CFException(); + final CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) f.completeExceptionally(ex1); + final CompletableFuture g = f.exceptionally + ((Throwable t) -> { + threadAssertSame(t, ex1); + a.getAndIncrement(); + throw ex2; + }); + if (createIncomplete) f.completeExceptionally(ex1); + + checkCompletedWithWrappedCFException(g, ex2); + assertEquals(1, a.get()); + }} + + /** + * handle action completes normally with function value on normal + * completion of source + */ + public void testHandle_normalCompletion() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final CompletableFuture f = new CompletableFuture<>(); + final AtomicInteger a = new AtomicInteger(0); + if (!createIncomplete) f.complete(v1); + final CompletableFuture g = m.handle + (f, + (Integer x, Throwable t) -> { + threadAssertSame(x, v1); + threadAssertNull(t); + a.getAndIncrement(); + return inc(v1); + }); + if (createIncomplete) f.complete(v1); + + checkCompletedNormally(g, inc(v1)); + checkCompletedNormally(f, v1); + assertEquals(1, a.get()); + }} /** - * handle action completes normally with function value on either - * normal or exceptional completion of source + * handle action completes normally with function value on + * exceptional completion of source */ - public void testHandle() { - CompletableFuture f, g; - IntegerHandler r; + public void testHandle_exceptionalCompletion() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final CompletableFuture f = new CompletableFuture<>(); + final AtomicInteger a = new AtomicInteger(0); + final CFException ex = new CFException(); + if (!createIncomplete) f.completeExceptionally(ex); + final CompletableFuture g = m.handle + (f, + (Integer x, Throwable t) -> { + threadAssertNull(x); + threadAssertSame(t, ex); + a.getAndIncrement(); + return v1; + }); + if (createIncomplete) f.completeExceptionally(ex); - f = new CompletableFuture<>(); - f.completeExceptionally(new CFException()); - g = f.handle(r = new IntegerHandler()); - assertTrue(r.ran); - checkCompletedNormally(g, three); + checkCompletedNormally(g, v1); + checkCompletedWithWrappedCFException(f, ex); + assertEquals(1, a.get()); + }} - f = new CompletableFuture<>(); - g = f.handle(r = new IntegerHandler()); - assertFalse(r.ran); - f.completeExceptionally(new CFException()); - checkCompletedNormally(g, three); - assertTrue(r.ran); + /** + * handle action completes normally with function value on + * cancelled source + */ + public void testHandle_sourceCancelled() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final CompletableFuture f = new CompletableFuture<>(); + final AtomicInteger a = new AtomicInteger(0); + if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); + final CompletableFuture g = m.handle + (f, + (Integer x, Throwable t) -> { + threadAssertNull(x); + threadAssertTrue(t instanceof CancellationException); + a.getAndIncrement(); + return v1; + }); + if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); - f = new CompletableFuture<>(); - f.complete(one); - g = f.handle(r = new IntegerHandler()); - assertTrue(r.ran); - checkCompletedNormally(g, two); + checkCompletedNormally(g, v1); + checkCancelled(f); + assertEquals(1, a.get()); + }} - f = new CompletableFuture<>(); - g = f.handle(r = new IntegerHandler()); - assertFalse(r.ran); - f.complete(one); - assertTrue(r.ran); - checkCompletedNormally(g, two); - } + /** + * handle result completes exceptionally if action does + */ + public void testHandle_sourceFailedActionFailed() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean createIncomplete : new boolean[] { true, false }) + { + final CompletableFuture f = new CompletableFuture<>(); + final AtomicInteger a = new AtomicInteger(0); + final CFException ex1 = new CFException(); + final CFException ex2 = new CFException(); + if (!createIncomplete) f.completeExceptionally(ex1); + final CompletableFuture g = m.handle + (f, + (Integer x, Throwable t) -> { + threadAssertNull(x); + threadAssertSame(ex1, t); + a.getAndIncrement(); + throw ex2; + }); + if (createIncomplete) f.completeExceptionally(ex1); + + checkCompletedWithWrappedCFException(g, ex2); + checkCompletedWithWrappedCFException(f, ex1); + assertEquals(1, a.get()); + }} + + public void testHandle_sourceCompletedNormallyActionFailed() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final CompletableFuture f = new CompletableFuture<>(); + final AtomicInteger a = new AtomicInteger(0); + final CFException ex = new CFException(); + if (!createIncomplete) f.complete(v1); + final CompletableFuture g = m.handle + (f, + (Integer x, Throwable t) -> { + threadAssertSame(x, v1); + threadAssertNull(t); + a.getAndIncrement(); + throw ex; + }); + if (createIncomplete) f.complete(v1); + + checkCompletedWithWrappedCFException(g, ex); + checkCompletedNormally(f, v1); + assertEquals(1, a.get()); + }} /** * runAsync completes after running Runnable @@ -714,7 +899,7 @@ public class CompletableFutureTest exten Noop r = new Noop(); CompletableFuture f = CompletableFuture.runAsync(r); assertNull(f.join()); - assertTrue(r.ran); + assertEquals(1, r.invocationCount); checkCompletedNormally(f, null); } @@ -726,7 +911,7 @@ public class CompletableFutureTest exten ThreadExecutor exec = new ThreadExecutor(); CompletableFuture f = CompletableFuture.runAsync(r, exec); assertNull(f.join()); - assertTrue(r.ran); + assertEquals(1, r.invocationCount); checkCompletedNormally(f, null); assertEquals(1, exec.count.get()); } @@ -738,7 +923,7 @@ public class CompletableFutureTest exten FailingNoop r = new FailingNoop(); CompletableFuture f = CompletableFuture.runAsync(r); checkCompletedWithWrappedCFException(f); - assertTrue(r.ran); + assertEquals(1, r.invocationCount); } /** @@ -768,7 +953,7 @@ public class CompletableFutureTest exten FailingSupplier r = new FailingSupplier(); CompletableFuture f = CompletableFuture.supplyAsync(r); checkCompletedWithWrappedCFException(f); - assertTrue(r.ran); + assertEquals(1, r.invocationCount); } // seq completion methods @@ -785,13 +970,13 @@ public class CompletableFutureTest exten g = f.thenRun(r = new Noop()); f.complete(null); checkCompletedNormally(g, null); - assertTrue(r.ran); + assertEquals(1, r.invocationCount); f = new CompletableFuture<>(); f.complete(null); g = f.thenRun(r = new Noop()); checkCompletedNormally(g, null); - assertTrue(r.ran); + assertEquals(1, r.invocationCount); } /** @@ -807,13 +992,13 @@ public class CompletableFutureTest exten g = f.thenRun(r = new Noop()); f.completeExceptionally(new CFException()); checkCompletedWithWrappedCFException(g); - assertFalse(r.ran); + assertEquals(0, r.invocationCount); f = new CompletableFuture<>(); f.completeExceptionally(new CFException()); g = f.thenRun(r = new Noop()); checkCompletedWithWrappedCFException(g); - assertFalse(r.ran); + assertEquals(0, r.invocationCount); } /** @@ -928,7 +1113,7 @@ public class CompletableFutureTest exten CompletableFuture g = f.thenAccept(r); f.complete(one); checkCompletedWithWrappedCFException(g); - assertTrue(r.ran); + assertEquals(1, r.invocationCount); } /** @@ -947,7 +1132,7 @@ public class CompletableFutureTest exten * of sources */ public void testThenCombine_normalCompletion1() { - for (boolean createdIncomplete : new boolean[] { true, false }) + for (boolean createIncomplete : new boolean[] { true, false }) for (boolean fFirst : new boolean[] { true, false }) for (ExecutionMode m : ExecutionMode.values()) for (Integer v1 : new Integer[] { 1, null }) @@ -957,24 +1142,24 @@ public class CompletableFutureTest exten final CompletableFuture g = new CompletableFuture<>(); final SubtractFunction r = new SubtractFunction(); CompletableFuture h = null; - if (createdIncomplete) h = m.thenCombine(f, g, r); + if (createIncomplete) h = m.thenCombine(f, g, r); if (fFirst) f.complete(v1); else g.complete(v2); - if (createdIncomplete) checkIncomplete(h); - assertEquals(r.invocationCount, 0); + if (createIncomplete) checkIncomplete(h); + assertEquals(0, r.invocationCount); if (!fFirst) f.complete(v1); else g.complete(v2); - if (!createdIncomplete) h = m.thenCombine(f, g, r); + if (!createIncomplete) h = m.thenCombine(f, g, r); checkCompletedNormally(h, subtract(v1, v2)); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); } } @@ -998,7 +1183,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1019,7 +1204,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1039,7 +1224,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1059,7 +1244,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1126,7 +1311,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1147,7 +1332,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1167,7 +1352,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1187,7 +1372,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1208,11 +1393,11 @@ public class CompletableFutureTest exten f.complete(v1); checkIncomplete(h); - assertFalse(r.ran()); + assertEquals(0, r.invocationCount); g.complete(v2); checkCompletedNormally(h, null); - assertEquals(r.value, subtract(v1, v2)); + assertEquals(subtract(v1, v2), r.value); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1230,11 +1415,11 @@ public class CompletableFutureTest exten g.complete(v2); checkIncomplete(h); - assertFalse(r.ran()); + assertEquals(0, r.invocationCount); f.complete(v1); checkCompletedNormally(h, null); - assertEquals(r.value, subtract(v1, v2)); + assertEquals(subtract(v1, v2), r.value); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1254,7 +1439,7 @@ public class CompletableFutureTest exten final CompletableFuture h = m.thenAcceptBoth(f, g, r); checkCompletedNormally(h, null); - assertEquals(r.value, subtract(v1, v2)); + assertEquals(subtract(v1, v2), r.value); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1274,7 +1459,7 @@ public class CompletableFutureTest exten final CompletableFuture h = m.thenAcceptBoth(f, g, r); checkCompletedNormally(h, null); - assertEquals(r.value, subtract(v1, v2)); + assertEquals(subtract(v1, v2), r.value); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1300,7 +1485,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1321,7 +1506,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1341,7 +1526,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1361,7 +1546,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertFalse(r.ran()); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1428,7 +1613,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1449,7 +1634,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1469,7 +1654,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1489,7 +1674,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1510,11 +1695,11 @@ public class CompletableFutureTest exten f.complete(v1); checkIncomplete(h); - assertFalse(r.ran); + assertEquals(0, r.invocationCount); g.complete(v2); checkCompletedNormally(h, null); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1532,11 +1717,11 @@ public class CompletableFutureTest exten g.complete(v2); checkIncomplete(h); - assertFalse(r.ran); + assertEquals(0, r.invocationCount); f.complete(v1); checkCompletedNormally(h, null); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1556,7 +1741,7 @@ public class CompletableFutureTest exten final CompletableFuture h = m.runAfterBoth(f, g, r); checkCompletedNormally(h, null); - assertTrue(r.ran); + assertEquals(1, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1576,7 +1761,7 @@ public class CompletableFutureTest exten final CompletableFuture h = m.runAfterBoth(f, g, r); checkCompletedNormally(h, null); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1602,7 +1787,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1623,7 +1808,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1643,7 +1828,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1663,7 +1848,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1730,7 +1915,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1751,7 +1936,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1771,7 +1956,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); } } @@ -1791,7 +1976,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); } } @@ -1858,7 +2043,7 @@ public class CompletableFutureTest exten // unspecified behavior assertTrue(Objects.equals(h.join(), inc(v1)) || Objects.equals(h.join(), inc(v2))); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); } } @@ -1880,7 +2065,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); g.complete(v1); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); checkCompletedWithWrappedCFException(f, ex); checkCompletedWithWrappedCFException(h, ex); @@ -1901,7 +2086,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); f.complete(v1); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedWithWrappedCFException(g, ex); checkCompletedWithWrappedCFException(h, ex); @@ -1924,11 +2109,11 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), inc(v1)); - assertEquals(r.invocationCount, 1); + assertEquals(inc(v1), h.join()); + assertEquals(1, r.invocationCount); } catch (CompletionException ok) { checkCompletedWithWrappedCFException(h, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCompletedWithWrappedCFException(g, ex); @@ -1952,11 +2137,11 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), inc(v1)); - assertEquals(r.invocationCount, 1); + assertEquals(inc(v1), h.join()); + assertEquals(1, r.invocationCount); } catch (CompletionException ok) { checkCompletedWithWrappedCFException(h, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCompletedWithWrappedCFException(f, ex); @@ -2021,7 +2206,7 @@ public class CompletableFutureTest exten g.complete(v1); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); checkCompletedWithWrappedCancellationException(h); } @@ -2042,7 +2227,7 @@ public class CompletableFutureTest exten f.complete(v1); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedWithWrappedCancellationException(h); } @@ -2064,11 +2249,11 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), inc(v1)); - assertEquals(r.invocationCount, 1); + assertEquals(inc(v1), h.join()); + assertEquals(1, r.invocationCount); } catch (CompletionException ok) { checkCompletedWithWrappedCancellationException(h); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCancelled(g); @@ -2092,11 +2277,11 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), inc(v1)); - assertEquals(r.invocationCount, 1); + assertEquals(inc(v1), h.join()); + assertEquals(1, r.invocationCount); } catch (CompletionException ok) { checkCompletedWithWrappedCancellationException(h); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCancelled(f); @@ -2120,7 +2305,7 @@ public class CompletableFutureTest exten f.complete(v1); checkCompletedNormally(h, null); - assertEquals(r.value, inc(v1)); + assertEquals(inc(v1), r.value); g.complete(v2); checkCompletedNormally(f, v1); @@ -2141,7 +2326,7 @@ public class CompletableFutureTest exten g.complete(v2); checkCompletedNormally(h, null); - assertEquals(r.value, inc(v2)); + assertEquals(inc(v2), r.value); f.complete(v1); checkCompletedNormally(f, v1); @@ -2190,7 +2375,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); g.complete(v1); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); checkCompletedWithWrappedCFException(f, ex); checkCompletedWithWrappedCFException(h, ex); @@ -2211,7 +2396,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); f.complete(v1); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedWithWrappedCFException(g, ex); checkCompletedWithWrappedCFException(h, ex); @@ -2234,12 +2419,12 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), null); - assertEquals(r.invocationCount, 1); + assertNull(h.join()); + assertEquals(1, r.invocationCount); assertEquals(inc(v1), r.value); } catch (CompletionException ok) { checkCompletedWithWrappedCFException(h, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCompletedWithWrappedCFException(g, ex); @@ -2263,12 +2448,12 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), null); - assertEquals(r.invocationCount, 1); + assertNull(h.join()); + assertEquals(1, r.invocationCount); assertEquals(inc(v1), r.value); } catch (CompletionException ok) { checkCompletedWithWrappedCFException(h, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCompletedWithWrappedCFException(f, ex); @@ -2333,7 +2518,7 @@ public class CompletableFutureTest exten g.complete(v1); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); checkCompletedWithWrappedCancellationException(h); } @@ -2354,7 +2539,7 @@ public class CompletableFutureTest exten f.complete(v1); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedWithWrappedCancellationException(h); } @@ -2376,12 +2561,12 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), null); - assertEquals(r.invocationCount, 1); + assertNull(h.join()); + assertEquals(1, r.invocationCount); assertEquals(inc(v1), r.value); } catch (CompletionException ok) { checkCompletedWithWrappedCancellationException(h); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCancelled(g); @@ -2405,12 +2590,12 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), null); - assertEquals(r.invocationCount, 1); + assertNull(h.join()); + assertEquals(1, r.invocationCount); assertEquals(inc(v1), r.value); } catch (CompletionException ok) { checkCompletedWithWrappedCancellationException(h); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCancelled(f); @@ -2434,13 +2619,13 @@ public class CompletableFutureTest exten f.complete(v1); checkCompletedNormally(h, null); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); g.complete(v2); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); checkCompletedNormally(h, null); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); } } @@ -2456,13 +2641,13 @@ public class CompletableFutureTest exten g.complete(v2); checkCompletedNormally(h, null); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); f.complete(v1); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); checkCompletedNormally(h, null); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); } } public void testRunAfterEither_normalCompletion3() { @@ -2481,7 +2666,7 @@ public class CompletableFutureTest exten checkCompletedNormally(h, null); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); - assertEquals(r.invocationCount, 1); + assertEquals(1, r.invocationCount); } } @@ -2503,7 +2688,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); g.complete(v1); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); checkCompletedWithWrappedCFException(f, ex); checkCompletedWithWrappedCFException(h, ex); @@ -2524,7 +2709,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); f.complete(v1); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedWithWrappedCFException(g, ex); checkCompletedWithWrappedCFException(h, ex); @@ -2547,11 +2732,11 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), null); - assertEquals(r.invocationCount, 1); + assertNull(h.join()); + assertEquals(1, r.invocationCount); } catch (CompletionException ok) { checkCompletedWithWrappedCFException(h, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCompletedWithWrappedCFException(g, ex); @@ -2575,11 +2760,11 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), null); - assertEquals(r.invocationCount, 1); + assertNull(h.join()); + assertEquals(1, r.invocationCount); } catch (CompletionException ok) { checkCompletedWithWrappedCFException(h, ex); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCompletedWithWrappedCFException(f, ex); @@ -2644,7 +2829,7 @@ public class CompletableFutureTest exten g.complete(v1); checkCancelled(f); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(g, v1); checkCompletedWithWrappedCancellationException(h); } @@ -2665,7 +2850,7 @@ public class CompletableFutureTest exten f.complete(v1); checkCancelled(g); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); checkCompletedNormally(f, v1); checkCompletedWithWrappedCancellationException(h); } @@ -2687,11 +2872,11 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), null); - assertEquals(r.invocationCount, 1); + assertNull(h.join()); + assertEquals(1, r.invocationCount); } catch (CompletionException ok) { checkCompletedWithWrappedCancellationException(h); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCancelled(g); @@ -2715,11 +2900,11 @@ public class CompletableFutureTest exten // unspecified behavior Integer v; try { - assertEquals(h.join(), null); - assertEquals(r.invocationCount, 1); + assertNull(h.join()); + assertEquals(1, r.invocationCount); } catch (CompletionException ok) { checkCompletedWithWrappedCancellationException(h); - assertEquals(r.invocationCount, 0); + assertEquals(0, r.invocationCount); } checkCancelled(f); @@ -2730,76 +2915,122 @@ public class CompletableFutureTest exten /** * thenCompose result completes normally after normal completion of source */ - public void testThenCompose() { - CompletableFuture f, g; - CompletableFutureInc r; + public void testThenCompose_normalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { - f = new CompletableFuture<>(); - g = f.thenCompose(r = new CompletableFutureInc()); - f.complete(one); - checkCompletedNormally(g, two); - assertTrue(r.ran); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFutureInc r = new CompletableFutureInc(); + final CompletableFuture g = f.thenCompose(r); + f.complete(v1); + checkCompletedNormally(g, inc(v1)); + checkCompletedNormally(f, v1); + assertEquals(1, r.invocationCount); + } + } - f = new CompletableFuture<>(); - f.complete(one); - g = f.thenCompose(r = new CompletableFutureInc()); - checkCompletedNormally(g, two); - assertTrue(r.ran); + public void testThenCompose_normalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFutureInc r = new CompletableFutureInc(); + f.complete(v1); + final CompletableFuture g = f.thenCompose(r); + checkCompletedNormally(g, inc(v1)); + checkCompletedNormally(f, v1); + assertEquals(1, r.invocationCount); + } } /** * thenCompose result completes exceptionally after exceptional * completion of source */ - public void testThenCompose2() { - CompletableFuture f, g; - CompletableFutureInc r; + public void testThenCompose_exceptionalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) { - f = new CompletableFuture<>(); - g = f.thenCompose(r = new CompletableFutureInc()); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); + final CFException ex = new CFException(); + final CompletableFutureInc r = new CompletableFutureInc(); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = f.thenCompose(r); + f.completeExceptionally(ex); + checkCompletedWithWrappedCFException(g, ex); + checkCompletedWithWrappedCFException(f, ex); + } + } - f = new CompletableFuture<>(); - f.completeExceptionally(new CFException()); - g = f.thenCompose(r = new CompletableFutureInc()); - checkCompletedWithWrappedCFException(g); + public void testThenCompose_exceptionalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) { + + final CFException ex = new CFException(); + final CompletableFuture f = new CompletableFuture<>(); + f.completeExceptionally(ex); + final CompletableFutureInc r = new CompletableFutureInc(); + final CompletableFuture g = f.thenCompose(r); + checkCompletedWithWrappedCFException(g, ex); + checkCompletedWithWrappedCFException(f, ex); + } } /** * thenCompose result completes exceptionally if action does */ - public void testThenCompose3() { - CompletableFuture f, g; - FailingCompletableFutureFunction r; + public void testThenCompose_actionFailed1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { - f = new CompletableFuture<>(); - g = f.thenCompose(r = new FailingCompletableFutureFunction()); - f.complete(one); + final CompletableFuture f = new CompletableFuture<>(); + final FailingCompletableFutureFunction r + = new FailingCompletableFutureFunction(); + final CompletableFuture g = f.thenCompose(r); + f.complete(v1); checkCompletedWithWrappedCFException(g); + checkCompletedNormally(f, v1); + } + } - f = new CompletableFuture<>(); - f.complete(one); - g = f.thenCompose(r = new FailingCompletableFutureFunction()); + public void testThenCompose_actionFailed2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + f.complete(v1); + final FailingCompletableFutureFunction r + = new FailingCompletableFutureFunction(); + final CompletableFuture g = f.thenCompose(r); checkCompletedWithWrappedCFException(g); + checkCompletedNormally(f, v1); + } } /** * thenCompose result completes exceptionally if source cancelled */ - public void testThenCompose4() { - CompletableFuture f, g; - CompletableFutureInc r; + public void testThenCompose_sourceCancelled1() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) { - f = new CompletableFuture<>(); - g = f.thenCompose(r = new CompletableFutureInc()); - assertTrue(f.cancel(true)); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFutureInc r = new CompletableFutureInc(); + final CompletableFuture g = f.thenCompose(r); + assertTrue(f.cancel(mayInterruptIfRunning)); checkCompletedWithWrappedCancellationException(g); + checkCancelled(f); + } + } - f = new CompletableFuture<>(); - assertTrue(f.cancel(true)); - g = f.thenCompose(r = new CompletableFutureInc()); + public void testThenCompose_sourceCancelled2() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) { + + final CompletableFuture f = new CompletableFuture<>(); + assertTrue(f.cancel(mayInterruptIfRunning)); + final CompletableFutureInc r = new CompletableFutureInc(); + final CompletableFuture g = f.thenCompose(r); checkCompletedWithWrappedCancellationException(g); + checkCancelled(f); + } } // asyncs @@ -2949,82 +3180,6 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(g); } - /** - * thenComposeAsync result completes normally after normal - * completion of source - */ - public void testThenComposeAsync() { - 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); - } - - /** - * thenComposeAsync result completes exceptionally after - * exceptional completion of source - */ - public void testThenComposeAsync2() { - 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, 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, 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 /** @@ -3172,52 +3327,6 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(g); } - /** - * thenComposeAsync result completes normally after normal - * completion of source - */ - public void testThenComposeAsyncE() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenComposeAsync(r, new ThreadExecutor()); - f.complete(one); - checkCompletedNormally(g, two); - } - - /** - * thenComposeAsync result completes exceptionally after - * exceptional completion of source - */ - public void testThenComposeAsync2E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenComposeAsync(r, new ThreadExecutor()); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - } - - /** - * thenComposeAsync result completes exceptionally if action does - */ - public void testThenComposeAsync3E() { - CompletableFuture f = new CompletableFuture<>(); - FailingCompletableFutureFunction r = new FailingCompletableFutureFunction(); - CompletableFuture g = f.thenComposeAsync(r, new ThreadExecutor()); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * thenComposeAsync result completes exceptionally if source cancelled - */ - public void testThenComposeAsync4E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFutureInc r = new CompletableFutureInc(); - CompletableFuture g = f.thenComposeAsync(r, new ThreadExecutor()); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - } - // other static methods /** @@ -3418,23 +3527,25 @@ public class CompletableFutureTest exten */ public void testWhenComplete_normalCompletion1() { for (ExecutionMode m : ExecutionMode.values()) - for (Integer v1 : new Integer[] { 1, null }) { - - final AtomicInteger a = new AtomicInteger(); + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final AtomicInteger a = new AtomicInteger(0); final CompletableFuture f = new CompletableFuture<>(); - final CompletableFuture g = - m.whenComplete(f, - (Integer x, Throwable t) -> { - threadAssertSame(x, v1); - threadAssertNull(t); - a.getAndIncrement(); - }); - f.complete(v1); - checkCompletedNormally(f, v1); + if (!createIncomplete) f.complete(v1); + final CompletableFuture g = m.whenComplete + (f, + (Integer x, Throwable t) -> { + threadAssertSame(x, v1); + threadAssertNull(t); + a.getAndIncrement(); + }); + if (createIncomplete) f.complete(v1); + checkCompletedNormally(g, v1); - assertEquals(a.get(), 1); - } - } + checkCompletedNormally(f, v1); + assertEquals(1, a.get()); + }} /** * whenComplete action executes on exceptional completion, propagating @@ -3442,11 +3553,13 @@ public class CompletableFutureTest exten */ public void testWhenComplete_exceptionalCompletion() { for (ExecutionMode m : ExecutionMode.values()) - for (Integer v1 : new Integer[] { 1, null }) { - - final AtomicInteger a = new AtomicInteger(); + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final AtomicInteger a = new AtomicInteger(0); final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) f.completeExceptionally(ex); final CompletableFuture g = m.whenComplete (f, (Integer x, Throwable t) -> { @@ -3454,33 +3567,64 @@ public class CompletableFutureTest exten threadAssertSame(t, ex); a.getAndIncrement(); }); - f.completeExceptionally(ex); + if (createIncomplete) f.completeExceptionally(ex); checkCompletedWithWrappedCFException(f, ex); checkCompletedWithWrappedCFException(g, ex); - assertEquals(a.get(), 1); - } - } + assertEquals(1, a.get()); + }} + + /** + * whenComplete action executes on cancelled source, propagating + * CancellationException. + */ + public void testWhenComplete_sourceCancelled() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (boolean createIncomplete : new boolean[] { true, false }) + { + final AtomicInteger a = new AtomicInteger(0); + final CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); + final CompletableFuture g = m.whenComplete + (f, + (Integer x, Throwable t) -> { + threadAssertNull(x); + threadAssertTrue(t instanceof CancellationException); + a.getAndIncrement(); + }); + if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); + + //try { g.join(); } catch (Throwable t) { throw new Error(t); } + checkCompletedWithWrappedCancellationException(g); + checkCancelled(f); + assertEquals(1, a.get()); + }} /** * If a whenComplete action throws an exception when triggered by * a normal completion, it completes exceptionally */ public void testWhenComplete_actionFailed() { + for (boolean createIncomplete : new boolean[] { true, false }) for (ExecutionMode m : ExecutionMode.values()) for (Integer v1 : new Integer[] { 1, null }) { + final AtomicInteger a = new AtomicInteger(0); final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) f.complete(v1); final CompletableFuture g = m.whenComplete (f, (Integer x, Throwable t) -> { threadAssertSame(x, v1); threadAssertNull(t); + a.getAndIncrement(); throw ex; }); - f.complete(v1); + if (createIncomplete) f.complete(v1); checkCompletedNormally(f, v1); checkCompletedWithWrappedCFException(g, ex); + assertEquals(1, a.get()); } } @@ -3490,107 +3634,30 @@ public class CompletableFutureTest exten * exception takes precedence. */ public void testWhenComplete_actionFailedSourceFailed() { + for (boolean createIncomplete : new boolean[] { true, false }) for (ExecutionMode m : ExecutionMode.values()) for (Integer v1 : new Integer[] { 1, null }) { + final AtomicInteger a = new AtomicInteger(0); final CFException ex1 = new CFException(); final CFException ex2 = new CFException(); final CompletableFuture f = new CompletableFuture<>(); + + if (!createIncomplete) f.completeExceptionally(ex1); final CompletableFuture g = m.whenComplete (f, (Integer x, Throwable t) -> { threadAssertSame(t, ex1); threadAssertNull(x); + a.getAndIncrement(); throw ex2; }); - f.completeExceptionally(ex1); + if (createIncomplete) f.completeExceptionally(ex1); + checkCompletedWithWrappedCFException(f, ex1); checkCompletedWithWrappedCFException(g, ex1); + assertEquals(1, a.get()); } } - /** - * 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); - } - }