--- jsr166/src/test/tck/CompletableFutureTest.java 2013/03/31 18:16:35 1.12 +++ jsr166/src/test/tck/CompletableFutureTest.java 2013/04/04 04:16:02 1.17 @@ -98,6 +98,7 @@ public class CompletableFutureTest exten } catch (Throwable fail) { threadUnexpectedException(fail); } assertTrue(f.isDone()); assertFalse(f.isCancelled()); + assertTrue(f.toString().contains("[Completed exceptionally]")); } void checkCancelled(CompletableFuture f) { @@ -121,6 +122,7 @@ public class CompletableFutureTest exten } catch (Throwable fail) { threadUnexpectedException(fail); } assertTrue(f.isDone()); assertTrue(f.isCancelled()); + assertTrue(f.toString().contains("[Completed exceptionally]")); } void checkCompletedWithWrappedCancellationException(CompletableFuture f) { @@ -150,6 +152,7 @@ public class CompletableFutureTest exten } catch (Throwable fail) { threadUnexpectedException(fail); } assertTrue(f.isDone()); assertFalse(f.isCancelled()); + assertTrue(f.toString().contains("[Completed exceptionally]")); } /** @@ -342,7 +345,10 @@ public class CompletableFutureTest exten // Used for explicit executor tests static final class ThreadExecutor implements Executor { + AtomicInteger count = new AtomicInteger(0); + public void execute(Runnable r) { + count.getAndIncrement(); new Thread(r).start(); } } @@ -352,7 +358,9 @@ public class CompletableFutureTest exten } static final class IntegerHandler implements BiFunction { + boolean ran; public Integer apply(Integer x, Throwable t) { + ran = true; return (t == null) ? two : three; } } @@ -381,16 +389,33 @@ public class CompletableFutureTest exten * normal or exceptional completion of source */ public void testHandle() { - CompletableFuture f = new CompletableFuture(); - IntegerHandler r = new IntegerHandler(); - CompletableFuture g = f.handle(r); + CompletableFuture f, g; + IntegerHandler r; + + f = new CompletableFuture(); + f.completeExceptionally(new CFException()); + g = f.handle(r = new IntegerHandler()); + assertTrue(r.ran); + checkCompletedNormally(g, three); + + f = new CompletableFuture(); + g = f.handle(r = new IntegerHandler()); + assertFalse(r.ran); f.completeExceptionally(new CFException()); checkCompletedNormally(g, three); + assertTrue(r.ran); f = new CompletableFuture(); - r = new IntegerHandler(); - g = f.handle(r); f.complete(one); + g = f.handle(r = new IntegerHandler()); + assertTrue(r.ran); + checkCompletedNormally(g, two); + + f = new CompletableFuture(); + g = f.handle(r = new IntegerHandler()); + assertFalse(r.ran); + f.complete(one); + assertTrue(r.ran); checkCompletedNormally(g, two); } @@ -402,6 +427,7 @@ public class CompletableFutureTest exten CompletableFuture f = CompletableFuture.runAsync(r); assertNull(f.join()); assertTrue(r.ran); + checkCompletedNormally(f, null); } /** @@ -409,9 +435,12 @@ public class CompletableFutureTest exten */ public void testRunAsync2() { Noop r = new Noop(); - CompletableFuture f = CompletableFuture.runAsync(r, new ThreadExecutor()); + ThreadExecutor exec = new ThreadExecutor(); + CompletableFuture f = CompletableFuture.runAsync(r, exec); assertNull(f.join()); assertTrue(r.ran); + checkCompletedNormally(f, null); + assertEquals(1, exec.count.get()); } /** @@ -428,16 +457,20 @@ public class CompletableFutureTest exten * supplyAsync completes with result of supplier */ public void testSupplyAsync() { - CompletableFuture f = CompletableFuture.supplyAsync(supplyOne); + CompletableFuture f; + f = CompletableFuture.supplyAsync(supplyOne); assertEquals(f.join(), one); + checkCompletedNormally(f, one); } /** * supplyAsync with executor completes with result of supplier */ public void testSupplyAsync2() { - CompletableFuture f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor()); + CompletableFuture f; + f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor()); assertEquals(f.join(), one); + checkCompletedNormally(f, one); } /** @@ -2370,7 +2403,7 @@ public class CompletableFutureTest exten } /** - * allOf returns a future completed when any components complete + * anyOf returns a future completed when any components complete */ public void testAnyOf() throws Exception { for (int k = 1; k < 20; ++k) { @@ -2392,42 +2425,106 @@ public class CompletableFutureTest exten public void testNPE() { CompletableFuture f = new CompletableFuture(); CompletableFuture g = new CompletableFuture(); - CompletableFuture h; - Runnable[] actions = { - () => f.thenApply(null), - } - try { h = f.thenApply(null); } catch (NullPointerException ok) {} - try { h = f.thenAccept(null); } catch (NullPointerException ok) {} - try { h = f.thenRun(null); } catch (NullPointerException ok) {} - try { h = f.thenCombine(g, null); } catch (NullPointerException ok) {} - try { h = f.thenCombine(null, null); } catch (NullPointerException ok) {} - try { h = f.applyToEither(g, null); } catch (NullPointerException ok) {} - try { h = f.applyToEither(null, null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptBoth(g, null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptBoth(null, null); } catch (NullPointerException ok) {} - try { h = f.runAfterEither(g, null); } catch (NullPointerException ok) {} - try { h = f.runAfterEither(null, null); } catch (NullPointerException ok) {} - try { h = f.runAfterBoth(g, null); } catch (NullPointerException ok) {} - try { h = f.runAfterBoth(null, null); } catch (NullPointerException ok) {} - try { h = f.exceptionally(null); } catch (NullPointerException ok) {} - try { h = f.handle(null); } catch (NullPointerException ok) {} - try { h = f.thenCompose(null); } catch (NullPointerException ok) {} - - try { h = f.thenApplyAsync(null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptAsync(null); } catch (NullPointerException ok) {} - try { h = f.thenRunAsync(null); } catch (NullPointerException ok) {} - try { h = f.thenCombineAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.thenCombineAsync(null, null); } catch (NullPointerException ok) {} - try { h = f.applyToEitherAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.applyToEitherAsync(null, null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptBothAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.thenAcceptBothAsync(null, null); } catch (NullPointerException ok) {} - try { h = f.runAfterEitherAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.runAfterEitherAsync(null, null); } catch (NullPointerException ok) {} - try { h = f.runAfterBothAsync(g, null); } catch (NullPointerException ok) {} - try { h = f.runAfterBothAsync(null, null); } catch (NullPointerException ok) {} + CompletableFuture nullFuture = (CompletableFuture)null; + CompletableFuture h; + ThreadExecutor exec = new ThreadExecutor(); + + Runnable[] throwingActions = { + () -> { CompletableFuture.supplyAsync(null); }, + () -> { CompletableFuture.supplyAsync(null, exec); }, + () -> { CompletableFuture.supplyAsync(supplyOne, null); }, + + () -> { CompletableFuture.runAsync(null); }, + () -> { CompletableFuture.runAsync(null, exec); }, + () -> { CompletableFuture.runAsync(() -> {}, null); }, + + () -> { f.completeExceptionally(null); }, + + () -> { f.thenApply(null); }, + () -> { f.thenApplyAsync(null); }, + () -> { f.thenApplyAsync((x) -> x, null); }, + () -> { f.thenApplyAsync(null, exec); }, + + () -> { f.thenAccept(null); }, + () -> { f.thenAcceptAsync(null); }, + () -> { f.thenAcceptAsync((x) -> { ; }, null); }, + () -> { f.thenAcceptAsync(null, exec); }, + + () -> { f.thenRun(null); }, + () -> { f.thenRunAsync(null); }, + () -> { f.thenRunAsync(() -> { ; }, null); }, + () -> { f.thenRunAsync(null, exec); }, + + () -> { f.thenCombine(g, null); }, + () -> { f.thenCombineAsync(g, null); }, + () -> { f.thenCombineAsync(g, null, exec); }, + () -> { f.thenCombine(nullFuture, (x, y) -> x); }, + () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); }, + () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); }, + () -> { f.thenCombineAsync(g, (x, y) -> x, null); }, + + () -> { f.thenAcceptBoth(g, null); }, + () -> { f.thenAcceptBothAsync(g, null); }, + () -> { f.thenAcceptBothAsync(g, null, exec); }, + () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); }, + () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); }, + () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); }, + () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); }, + + () -> { f.runAfterBoth(g, null); }, + () -> { f.runAfterBothAsync(g, null); }, + () -> { f.runAfterBothAsync(g, null, exec); }, + () -> { f.runAfterBoth(nullFuture, () -> {}); }, + () -> { f.runAfterBothAsync(nullFuture, () -> {}); }, + () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); }, + () -> { f.runAfterBothAsync(g, () -> {}, null); }, + + () -> { f.applyToEither(g, null); }, + () -> { f.applyToEitherAsync(g, null); }, + () -> { f.applyToEitherAsync(g, null, exec); }, + () -> { f.applyToEither(nullFuture, (x) -> x); }, + () -> { f.applyToEitherAsync(nullFuture, (x) -> x); }, + () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); }, + () -> { f.applyToEitherAsync(g, (x) -> x, null); }, + + () -> { f.acceptEither(g, null); }, + () -> { f.acceptEitherAsync(g, null); }, + () -> { f.acceptEitherAsync(g, null, exec); }, + () -> { f.acceptEither(nullFuture, (x) -> {}); }, + () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); }, + () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); }, + () -> { f.acceptEitherAsync(g, (x) -> {}, null); }, + + () -> { f.runAfterEither(g, null); }, + () -> { f.runAfterEitherAsync(g, null); }, + () -> { f.runAfterEitherAsync(g, null, exec); }, + () -> { f.runAfterEither(nullFuture, () -> {}); }, + () -> { f.runAfterEitherAsync(nullFuture, () -> {}); }, + () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); }, + () -> { f.runAfterEitherAsync(g, () -> {}, null); }, + + () -> { f.thenCompose(null); }, + () -> { f.thenComposeAsync(null); }, + () -> { f.thenComposeAsync(new CompletableFutureInc(), null); }, + () -> { f.thenComposeAsync(null, exec); }, + + () -> { f.exceptionally(null); }, + + () -> { f.handle(null); }, + + () -> { CompletableFuture.allOf((CompletableFuture)null); }, + () -> { CompletableFuture.allOf((CompletableFuture[])null); }, + () -> { CompletableFuture.allOf(f, null); }, + () -> { CompletableFuture.allOf(null, f); }, + + () -> { CompletableFuture.anyOf((CompletableFuture)null); }, + () -> { CompletableFuture.anyOf((CompletableFuture[])null); }, + () -> { CompletableFuture.anyOf(f, null); }, + () -> { CompletableFuture.anyOf(null, f); }, + }; + assertThrows(NullPointerException.class, throwingActions); + assertEquals(0, exec.count.get()); } - }