--- jsr166/src/test/tck/CompletableFutureTest.java 2018/09/22 21:04:48 1.201 +++ jsr166/src/test/tck/CompletableFutureTest.java 2018/11/24 18:24:14 1.218 @@ -551,9 +551,7 @@ public class CompletableFutureTest exten public CompletableFuture apply(Integer x) { invoked(); value = x; - CompletableFuture f = new CompletableFuture<>(); - assertTrue(f.complete(inc(x))); - return f; + return CompletableFuture.completedFuture(inc(x)); } } @@ -574,9 +572,7 @@ public class CompletableFutureTest exten ExceptionalCompletableFutureFunction(ExecutionMode m) { super(m); } public CompletionStage apply(Throwable x) { invoked(); - CompletableFuture d = new CompletableFuture(); - d.complete(value); - return d; + return CompletableFuture.completedFuture(value); } } @@ -930,12 +926,10 @@ public class CompletableFutureTest exten 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) assertTrue(f.complete(v1)); final CompletableFuture g = m.exceptionally (f, (Throwable t) -> { - a.getAndIncrement(); threadFail("should not be called"); return null; // unreached }); @@ -943,7 +937,6 @@ public class CompletableFutureTest exten checkCompletedNormally(g, v1); checkCompletedNormally(f, v1); - assertEquals(0, a.get()); }} /** @@ -955,21 +948,21 @@ public class CompletableFutureTest exten for (boolean createIncomplete : new boolean[] { true, false }) for (Integer v1 : new Integer[] { 1, null }) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); if (!createIncomplete) f.completeExceptionally(ex); final CompletableFuture g = m.exceptionally (f, (Throwable t) -> { m.checkExecutionMode(); - threadAssertSame(t, ex); - a.getAndIncrement(); + assertSame(t, ex); + ran.getAndIncrement(); return v1; }); if (createIncomplete) f.completeExceptionally(ex); checkCompletedNormally(g, v1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -980,7 +973,7 @@ public class CompletableFutureTest exten for (ExecutionMode m : ExecutionMode.values()) for (boolean createIncomplete : new boolean[] { true, false }) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex1 = new CFException(); final CFException ex2 = new CFException(); final CompletableFuture f = new CompletableFuture<>(); @@ -988,15 +981,15 @@ public class CompletableFutureTest exten final CompletableFuture g = m.exceptionally (f, (Throwable t) -> { m.checkExecutionMode(); - threadAssertSame(t, ex1); - a.getAndIncrement(); + assertSame(t, ex1); + ran.getAndIncrement(); throw ex2; }); if (createIncomplete) f.completeExceptionally(ex1); checkCompletedWithWrappedException(g, ex2); checkCompletedExceptionally(f, ex1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1008,22 +1001,22 @@ public class CompletableFutureTest exten for (boolean createIncomplete : new boolean[] { true, false }) for (Integer v1 : new Integer[] { 1, null }) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CompletableFuture f = new CompletableFuture<>(); if (!createIncomplete) assertTrue(f.complete(v1)); final CompletableFuture g = m.whenComplete (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertSame(result, v1); - threadAssertNull(t); - a.getAndIncrement(); + assertSame(result, v1); + assertNull(t); + ran.getAndIncrement(); }); if (createIncomplete) assertTrue(f.complete(v1)); checkCompletedNormally(g, v1); checkCompletedNormally(f, v1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1034,7 +1027,7 @@ public class CompletableFutureTest exten for (ExecutionMode m : ExecutionMode.values()) for (boolean createIncomplete : new boolean[] { true, false }) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); if (!createIncomplete) f.completeExceptionally(ex); @@ -1042,15 +1035,15 @@ public class CompletableFutureTest exten (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertNull(result); - threadAssertSame(t, ex); - a.getAndIncrement(); + assertNull(result); + assertSame(t, ex); + ran.getAndIncrement(); }); if (createIncomplete) f.completeExceptionally(ex); checkCompletedWithWrappedException(g, ex); checkCompletedExceptionally(f, ex); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1062,22 +1055,22 @@ public class CompletableFutureTest exten for (boolean mayInterruptIfRunning : new boolean[] { true, false }) for (boolean createIncomplete : new boolean[] { true, false }) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CompletableFuture f = new CompletableFuture<>(); if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); final CompletableFuture g = m.whenComplete (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertNull(result); - threadAssertTrue(t instanceof CancellationException); - a.getAndIncrement(); + assertNull(result); + assertTrue(t instanceof CancellationException); + ran.getAndIncrement(); }); if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); checkCompletedWithWrappedCancellationException(g); checkCancelled(f); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1089,7 +1082,7 @@ public class CompletableFutureTest exten for (ExecutionMode m : ExecutionMode.values()) for (Integer v1 : new Integer[] { 1, null }) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); if (!createIncomplete) assertTrue(f.complete(v1)); @@ -1097,16 +1090,16 @@ public class CompletableFutureTest exten (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertSame(result, v1); - threadAssertNull(t); - a.getAndIncrement(); + assertSame(result, v1); + assertNull(t); + ran.getAndIncrement(); throw ex; }); if (createIncomplete) assertTrue(f.complete(v1)); checkCompletedWithWrappedException(g, ex); checkCompletedNormally(f, v1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1118,7 +1111,7 @@ public class CompletableFutureTest exten for (boolean createIncomplete : new boolean[] { true, false }) for (ExecutionMode m : ExecutionMode.values()) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex1 = new CFException(); final CFException ex2 = new CFException(); final CompletableFuture f = new CompletableFuture<>(); @@ -1128,9 +1121,9 @@ public class CompletableFutureTest exten (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertSame(t, ex1); - threadAssertNull(result); - a.getAndIncrement(); + assertSame(t, ex1); + assertNull(result); + ran.getAndIncrement(); throw ex2; }); if (createIncomplete) f.completeExceptionally(ex1); @@ -1141,7 +1134,7 @@ public class CompletableFutureTest exten assertEquals(1, ex1.getSuppressed().length); assertSame(ex2, ex1.getSuppressed()[0]); } - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1154,22 +1147,22 @@ public class CompletableFutureTest exten for (Integer v1 : new Integer[] { 1, null }) { final CompletableFuture f = new CompletableFuture<>(); - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); if (!createIncomplete) assertTrue(f.complete(v1)); final CompletableFuture g = m.handle (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertSame(result, v1); - threadAssertNull(t); - a.getAndIncrement(); + assertSame(result, v1); + assertNull(t); + ran.getAndIncrement(); return inc(v1); }); if (createIncomplete) assertTrue(f.complete(v1)); checkCompletedNormally(g, inc(v1)); checkCompletedNormally(f, v1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1182,23 +1175,23 @@ public class CompletableFutureTest exten for (Integer v1 : new Integer[] { 1, null }) { final CompletableFuture f = new CompletableFuture<>(); - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex = new CFException(); if (!createIncomplete) f.completeExceptionally(ex); final CompletableFuture g = m.handle (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertNull(result); - threadAssertSame(t, ex); - a.getAndIncrement(); + assertNull(result); + assertSame(t, ex); + ran.getAndIncrement(); return v1; }); if (createIncomplete) f.completeExceptionally(ex); checkCompletedNormally(g, v1); checkCompletedExceptionally(f, ex); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1212,22 +1205,22 @@ public class CompletableFutureTest exten for (Integer v1 : new Integer[] { 1, null }) { final CompletableFuture f = new CompletableFuture<>(); - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); final CompletableFuture g = m.handle (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertNull(result); - threadAssertTrue(t instanceof CancellationException); - a.getAndIncrement(); + assertNull(result); + assertTrue(t instanceof CancellationException); + ran.getAndIncrement(); return v1; }); if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); checkCompletedNormally(g, v1); checkCancelled(f); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1240,23 +1233,23 @@ public class CompletableFutureTest exten for (Integer v1 : new Integer[] { 1, null }) { final CompletableFuture f = new CompletableFuture<>(); - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex = new CFException(); if (!createIncomplete) assertTrue(f.complete(v1)); final CompletableFuture g = m.handle (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertSame(result, v1); - threadAssertNull(t); - a.getAndIncrement(); + assertSame(result, v1); + assertNull(t); + ran.getAndIncrement(); throw ex; }); if (createIncomplete) assertTrue(f.complete(v1)); checkCompletedWithWrappedException(g, ex); checkCompletedNormally(f, v1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1268,7 +1261,7 @@ public class CompletableFutureTest exten for (boolean createIncomplete : new boolean[] { true, false }) for (ExecutionMode m : ExecutionMode.values()) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex1 = new CFException(); final CFException ex2 = new CFException(); final CompletableFuture f = new CompletableFuture<>(); @@ -1278,16 +1271,16 @@ public class CompletableFutureTest exten (f, (Integer result, Throwable t) -> { m.checkExecutionMode(); - threadAssertNull(result); - threadAssertSame(ex1, t); - a.getAndIncrement(); + assertNull(result); + assertSame(ex1, t); + ran.getAndIncrement(); throw ex2; }); if (createIncomplete) f.completeExceptionally(ex1); checkCompletedWithWrappedException(g, ex2); checkCompletedExceptionally(f, ex1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -3123,30 +3116,30 @@ public class CompletableFutureTest exten case 0: assertTrue(f.complete(v1)); assertTrue(g.completeExceptionally(ex)); - h = m.thenCompose(f, (x -> g)); + h = m.thenCompose(f, x -> g); break; case 1: assertTrue(f.complete(v1)); - h = m.thenCompose(f, (x -> g)); + h = m.thenCompose(f, x -> g); assertTrue(g.completeExceptionally(ex)); break; case 2: assertTrue(g.completeExceptionally(ex)); assertTrue(f.complete(v1)); - h = m.thenCompose(f, (x -> g)); + h = m.thenCompose(f, x -> g); break; case 3: assertTrue(g.completeExceptionally(ex)); - h = m.thenCompose(f, (x -> g)); + h = m.thenCompose(f, x -> g); assertTrue(f.complete(v1)); break; case 4: - h = m.thenCompose(f, (x -> g)); + h = m.thenCompose(f, x -> g); assertTrue(f.complete(v1)); assertTrue(g.completeExceptionally(ex)); break; case 5: - h = m.thenCompose(f, (x -> g)); + h = m.thenCompose(f, x -> g); assertTrue(f.complete(v1)); assertTrue(g.completeExceptionally(ex)); break; @@ -3206,7 +3199,6 @@ public class CompletableFutureTest exten public void testExceptionallyCompose_actionFailed() { for (ExecutionMode m : ExecutionMode.values()) for (boolean createIncomplete : new boolean[] { true, false }) - for (Integer v1 : new Integer[] { 1, null }) { final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); @@ -3221,6 +3213,58 @@ public class CompletableFutureTest exten r.assertInvoked(); }} + /** + * exceptionallyCompose result completes exceptionally if the + * result of the action does + */ + public void testExceptionallyCompose_actionReturnsFailingFuture() { + for (ExecutionMode m : ExecutionMode.values()) + for (int order = 0; order < 6; order++) + { + final CFException ex0 = new CFException(); + final CFException ex = new CFException(); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final CompletableFuture h; + // Test all permutations of orders + switch (order) { + case 0: + assertTrue(f.completeExceptionally(ex0)); + assertTrue(g.completeExceptionally(ex)); + h = m.exceptionallyCompose(f, x -> g); + break; + case 1: + assertTrue(f.completeExceptionally(ex0)); + h = m.exceptionallyCompose(f, x -> g); + assertTrue(g.completeExceptionally(ex)); + break; + case 2: + assertTrue(g.completeExceptionally(ex)); + assertTrue(f.completeExceptionally(ex0)); + h = m.exceptionallyCompose(f, x -> g); + break; + case 3: + assertTrue(g.completeExceptionally(ex)); + h = m.exceptionallyCompose(f, x -> g); + assertTrue(f.completeExceptionally(ex0)); + break; + case 4: + h = m.exceptionallyCompose(f, x -> g); + assertTrue(f.completeExceptionally(ex0)); + assertTrue(g.completeExceptionally(ex)); + break; + case 5: + h = m.exceptionallyCompose(f, x -> g); + assertTrue(f.completeExceptionally(ex0)); + assertTrue(g.completeExceptionally(ex)); + break; + default: throw new AssertionError(); + } + + checkCompletedExceptionally(g, ex); + checkCompletedWithWrappedException(h, ex); + checkCompletedExceptionally(f, ex0); + }} // other static methods @@ -3601,12 +3645,6 @@ public class CompletableFutureTest exten final CompletableFuture complete = CompletableFuture.completedFuture(v); final CompletableFuture incomplete = new CompletableFuture<>(); - List> futures = new ArrayList<>(); - - List> srcs = new ArrayList<>(); - srcs.add(complete); - srcs.add(incomplete); - List> fs = new ArrayList<>(); fs.add(incomplete.thenRunAsync(() -> {}, e)); fs.add(incomplete.thenAcceptAsync(z -> {}, e)); @@ -4784,14 +4822,36 @@ public class CompletableFutureTest exten } /** + * default-implemented exceptionallyAsync action is not invoked when + * source completes normally, and source result is propagated + */ + public void testDefaultExceptionallyAsync_normalCompletion() { + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + final CompletableFuture f = new CompletableFuture<>(); + final DelegatedCompletionStage d = + new DelegatedCompletionStage(f); + if (!createIncomplete) assertTrue(f.complete(v1)); + final CompletionStage g = d.exceptionallyAsync + ((Throwable t) -> { + threadFail("should not be called"); + return null; // unreached + }); + if (createIncomplete) assertTrue(f.complete(v1)); + + checkCompletedNormally(g.toCompletableFuture(), v1); + }} + + /** * default-implemented exceptionallyAsync action completes with * function value on source exception */ - public void testDefaulExceptionallyAsync_exceptionalCompletion() { + public void testDefaultExceptionallyAsync_exceptionalCompletion() { for (boolean createIncomplete : new boolean[] { true, false }) for (Integer v1 : new Integer[] { 1, null }) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); final DelegatedCompletionStage d = @@ -4799,14 +4859,14 @@ public class CompletableFutureTest exten if (!createIncomplete) f.completeExceptionally(ex); final CompletionStage g = d.exceptionallyAsync ((Throwable t) -> { - threadAssertSame(t, ex); - a.getAndIncrement(); + assertSame(t, ex); + ran.getAndIncrement(); return v1; }); if (createIncomplete) f.completeExceptionally(ex); checkCompletedNormally(g.toCompletableFuture(), v1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -4814,10 +4874,10 @@ public class CompletableFutureTest exten * throws an exception, it completes exceptionally with that * exception */ - public void testDefaulExceptionallyAsync_exceptionalCompletionActionFailed() { + public void testDefaultExceptionallyAsync_exceptionalCompletionActionFailed() { for (boolean createIncomplete : new boolean[] { true, false }) { - final AtomicInteger a = new AtomicInteger(0); + final AtomicInteger ran = new AtomicInteger(0); final CFException ex1 = new CFException(); final CFException ex2 = new CFException(); final CompletableFuture f = new CompletableFuture<>(); @@ -4826,8 +4886,8 @@ public class CompletableFutureTest exten if (!createIncomplete) f.completeExceptionally(ex1); final CompletionStage g = d.exceptionallyAsync ((Throwable t) -> { - threadAssertSame(t, ex1); - a.getAndIncrement(); + assertSame(t, ex1); + ran.getAndIncrement(); throw ex2; }); if (createIncomplete) f.completeExceptionally(ex1); @@ -4835,12 +4895,12 @@ public class CompletableFutureTest exten checkCompletedWithWrappedException(g.toCompletableFuture(), ex2); checkCompletedExceptionally(f, ex1); checkCompletedExceptionally(d.toCompletableFuture(), ex1); - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** - * default exceptionallyCompose result completes normally after normal - * completion of source + * default-implemented exceptionallyCompose result completes + * normally after normal completion of source */ public void testDefaultExceptionallyCompose_normalCompletion() { for (boolean createIncomplete : new boolean[] { true, false }) @@ -4888,7 +4948,6 @@ public class CompletableFutureTest exten */ public void testDefaultExceptionallyCompose_actionFailed() { for (boolean createIncomplete : new boolean[] { true, false }) - for (Integer v1 : new Integer[] { 1, null }) { final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); @@ -4906,8 +4965,8 @@ public class CompletableFutureTest exten }} /** - * default exceptionallyComposeAsync result completes normally after normal - * completion of source + * default-implemented exceptionallyComposeAsync result completes + * normally after normal completion of source */ public void testDefaultExceptionallyComposeAsync_normalCompletion() { for (boolean createIncomplete : new boolean[] { true, false }) @@ -4955,7 +5014,6 @@ public class CompletableFutureTest exten */ public void testDefaultExceptionallyComposeAsync_actionFailed() { for (boolean createIncomplete : new boolean[] { true, false }) - for (Integer v1 : new Integer[] { 1, null }) { final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); @@ -4972,10 +5030,9 @@ public class CompletableFutureTest exten r.assertInvoked(); }} - /** - * default exceptionallyComposeAsync result completes normally after normal - * completion of source + * default-implemented exceptionallyComposeAsync result completes + * normally after normal completion of source */ public void testDefaultExceptionallyComposeAsyncExecutor_normalCompletion() { for (boolean createIncomplete : new boolean[] { true, false }) @@ -4987,7 +5044,7 @@ public class CompletableFutureTest exten final DelegatedCompletionStage d = new DelegatedCompletionStage(f); if (!createIncomplete) assertTrue(f.complete(v1)); - final CompletionStage g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); + final CompletionStage g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); if (createIncomplete) assertTrue(f.complete(v1)); checkCompletedNormally(f, v1); @@ -5009,7 +5066,7 @@ public class CompletableFutureTest exten final DelegatedCompletionStage d = new DelegatedCompletionStage(f); if (!createIncomplete) f.completeExceptionally(ex); - final CompletionStage g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); + final CompletionStage g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); if (createIncomplete) f.completeExceptionally(ex); checkCompletedExceptionally(f, ex); @@ -5023,7 +5080,6 @@ public class CompletableFutureTest exten */ public void testDefaultExceptionallyComposeAsyncExecutor_actionFailed() { for (boolean createIncomplete : new boolean[] { true, false }) - for (Integer v1 : new Integer[] { 1, null }) { final CFException ex = new CFException(); final CompletableFuture f = new CompletableFuture<>(); @@ -5032,7 +5088,7 @@ public class CompletableFutureTest exten final DelegatedCompletionStage d = new DelegatedCompletionStage(f); if (!createIncomplete) f.completeExceptionally(ex); - final CompletionStage g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); + final CompletionStage g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); if (createIncomplete) f.completeExceptionally(ex); checkCompletedExceptionally(f, ex);