--- jsr166/src/test/tck/CompletableFutureTest.java 2018/09/22 22:25:12 1.203 +++ jsr166/src/test/tck/CompletableFutureTest.java 2019/02/22 19:27:47 1.221 @@ -926,20 +926,19 @@ 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.exceptionally (f, (Throwable t) -> { - a.getAndIncrement(); - threadFail("should not be called"); - return null; // unreached + ran.getAndIncrement(); + throw new AssertionError("should not be called"); }); if (createIncomplete) assertTrue(f.complete(v1)); checkCompletedNormally(g, v1); checkCompletedNormally(f, v1); - assertEquals(0, a.get()); + assertEquals(0, ran.get()); }} /** @@ -951,21 +950,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()); }} /** @@ -976,7 +975,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<>(); @@ -984,15 +983,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()); }} /** @@ -1004,22 +1003,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()); }} /** @@ -1030,7 +1029,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); @@ -1038,15 +1037,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()); }} /** @@ -1058,22 +1057,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()); }} /** @@ -1085,7 +1084,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)); @@ -1093,16 +1092,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()); }} /** @@ -1114,7 +1113,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<>(); @@ -1124,9 +1123,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); @@ -1137,7 +1136,7 @@ public class CompletableFutureTest exten assertEquals(1, ex1.getSuppressed().length); assertSame(ex2, ex1.getSuppressed()[0]); } - assertEquals(1, a.get()); + assertEquals(1, ran.get()); }} /** @@ -1150,22 +1149,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()); }} /** @@ -1178,23 +1177,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()); }} /** @@ -1208,22 +1207,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()); }} /** @@ -1236,23 +1235,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()); }} /** @@ -1264,7 +1263,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<>(); @@ -1274,16 +1273,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()); }} /** @@ -3119,30 +3118,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; @@ -3202,7 +3201,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<>(); @@ -3217,6 +3215,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 @@ -3388,7 +3438,9 @@ public class CompletableFutureTest exten CompletableFuture nullFuture = (CompletableFuture)null; ThreadExecutor exec = new ThreadExecutor(); - Runnable[] throwingActions = { + assertThrows( + NullPointerException.class, + () -> CompletableFuture.supplyAsync(null), () -> CompletableFuture.supplyAsync(null, exec), () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.SYNC, 42), null), @@ -3491,10 +3543,8 @@ public class CompletableFutureTest exten () -> f.completeOnTimeout(42, 1L, null), () -> CompletableFuture.failedFuture(null), - () -> CompletableFuture.failedStage(null), - }; + () -> CompletableFuture.failedStage(null)); - assertThrows(NullPointerException.class, throwingActions); assertEquals(0, exec.count.get()); } @@ -3597,12 +3647,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)); @@ -4780,14 +4824,39 @@ 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 AtomicInteger ran = new AtomicInteger(0); + final CompletableFuture f = new CompletableFuture<>(); + final DelegatedCompletionStage d = + new DelegatedCompletionStage(f); + if (!createIncomplete) assertTrue(f.complete(v1)); + final CompletionStage g = d.exceptionallyAsync + ((Throwable t) -> { + ran.getAndIncrement(); + throw new AssertionError("should not be called"); + }); + if (createIncomplete) assertTrue(f.complete(v1)); + + checkCompletedNormally(g.toCompletableFuture(), v1); + checkCompletedNormally(f, v1); + assertEquals(0, ran.get()); + }} + + /** * 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 = @@ -4795,14 +4864,15 @@ 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()); + checkCompletedExceptionally(f, ex); + assertEquals(1, ran.get()); }} /** @@ -4810,10 +4880,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<>(); @@ -4822,8 +4892,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); @@ -4831,12 +4901,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 }) @@ -4884,7 +4954,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<>(); @@ -4902,8 +4971,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 }) @@ -4951,7 +5020,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<>(); @@ -4968,10 +5036,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 }) @@ -4983,7 +5050,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); @@ -5005,7 +5072,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); @@ -5019,7 +5086,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<>(); @@ -5028,7 +5094,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);