--- jsr166/src/test/tck/CompletableFutureTest.java 2014/06/02 22:48:50 1.57 +++ jsr166/src/test/tck/CompletableFutureTest.java 2014/06/03 06:16:41 1.60 @@ -320,13 +320,19 @@ public class CompletableFutureTest exten checkCompletedNormally(f, "test"); } - // Choose non-commutative actions for better coverage - - // A non-commutative function that handles and produces null values as well. - static Integer subtract(Integer x, Integer y) { - return (x == null && y == null) ? null : - ((x == null) ? 42 : x.intValue()) - - ((y == null) ? 99 : y.intValue()); + static final class IntegerSupplier implements Supplier { + final ExecutionMode m; + int invocationCount = 0; + final Integer value; + IntegerSupplier(ExecutionMode m, Integer value) { + this.m = m; + this.value = value; + } + public Integer get() { + m.checkExecutionMode(); + invocationCount++; + return value; + } } // A function that handles and produces null values as well. @@ -334,12 +340,6 @@ public class CompletableFutureTest exten return (x == null) ? null : x + 1; } - static final Supplier supplyOne = - () -> Integer.valueOf(1); - static final Function inc = - (Integer x) -> Integer.valueOf(x.intValue() + 1); - static final BiFunction subtract = - (Integer x, Integer y) -> subtract(x, y); static final class IncAction implements Consumer { int invocationCount = 0; Integer value; @@ -359,6 +359,15 @@ public class CompletableFutureTest exten return value = inc(x); } } + + // Choose non-commutative actions for better coverage + // A non-commutative function that handles and produces null values as well. + static Integer subtract(Integer x, Integer y) { + return (x == null && y == null) ? null : + ((x == null) ? 42 : x.intValue()) + - ((y == null) ? 99 : y.intValue()); + } + static final class SubtractAction implements BiConsumer { final ExecutionMode m; int invocationCount = 0; @@ -383,6 +392,7 @@ public class CompletableFutureTest exten return value = subtract(x, y); } } + static final class Noop implements Runnable { final ExecutionMode m; int invocationCount = 0; @@ -496,16 +506,20 @@ public class CompletableFutureTest exten /** * Permits the testing of parallel code for the 3 different - * execution modes without repeating all the testing code. + * execution modes without copy/pasting all the test methods. */ enum ExecutionMode { DEFAULT { public void checkExecutionMode() { + assertFalse(ThreadExecutor.startedCurrentThread()); assertNull(ForkJoinTask.getPool()); } public CompletableFuture runAsync(Runnable a) { throw new UnsupportedOperationException(); } + public CompletableFuture supplyAsync(Supplier a) { + throw new UnsupportedOperationException(); + } public CompletableFuture thenRun (CompletableFuture f, Runnable a) { return f.thenRun(a); @@ -577,6 +591,9 @@ public class CompletableFutureTest exten public CompletableFuture runAsync(Runnable a) { return CompletableFuture.runAsync(a); } + public CompletableFuture supplyAsync(Supplier a) { + return CompletableFuture.supplyAsync(a); + } public CompletableFuture thenRun (CompletableFuture f, Runnable a) { return f.thenRunAsync(a); @@ -647,6 +664,9 @@ public class CompletableFutureTest exten public CompletableFuture runAsync(Runnable a) { return CompletableFuture.runAsync(a, new ThreadExecutor()); } + public CompletableFuture supplyAsync(Supplier a) { + return CompletableFuture.supplyAsync(a, new ThreadExecutor()); + } public CompletableFuture thenRun (CompletableFuture f, Runnable a) { return f.thenRunAsync(a, new ThreadExecutor()); @@ -712,6 +732,7 @@ public class CompletableFutureTest exten public abstract void checkExecutionMode(); public abstract CompletableFuture runAsync(Runnable a); + public abstract CompletableFuture supplyAsync(Supplier a); public abstract CompletableFuture thenRun (CompletableFuture f, Runnable a); public abstract CompletableFuture thenAccept @@ -998,32 +1019,36 @@ public class CompletableFutureTest exten /** * supplyAsync completes with result of supplier */ - public void testSupplyAsync() { - 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; - f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor()); - assertEquals(f.join(), one); - checkCompletedNormally(f, one); - } + public void testSupplyAsync_normalCompletion() { + ExecutionMode[] executionModes = { + ExecutionMode.ASYNC, + ExecutionMode.EXECUTOR, + }; + for (ExecutionMode m : executionModes) + for (Integer v1 : new Integer[] { 1, null }) + { + final IntegerSupplier r = new IntegerSupplier(m, v1); + final CompletableFuture f = m.supplyAsync(r); + assertSame(v1, f.join()); + checkCompletedNormally(f, v1); + assertEquals(1, r.invocationCount); + }} /** * Failing supplyAsync completes exceptionally */ - public void testSupplyAsync3() { - FailingSupplier r = new FailingSupplier(ExecutionMode.ASYNC); - CompletableFuture f = CompletableFuture.supplyAsync(r); + public void testSupplyAsync_exceptionalCompletion() { + ExecutionMode[] executionModes = { + ExecutionMode.ASYNC, + ExecutionMode.EXECUTOR, + }; + for (ExecutionMode m : executionModes) + { + FailingSupplier r = new FailingSupplier(m); + CompletableFuture f = m.supplyAsync(r); checkCompletedWithWrappedCFException(f); assertEquals(1, r.invocationCount); - } + }} // seq completion methods @@ -2591,7 +2616,8 @@ public class CompletableFutureTest exten */ public void testAllOf_normal() throws Exception { for (int k = 1; k < 20; ++k) { - CompletableFuture[] fs = (CompletableFuture[]) new CompletableFuture[k]; + CompletableFuture[] fs + = (CompletableFuture[]) new CompletableFuture[k]; for (int i = 0; i < k; ++i) fs[i] = new CompletableFuture<>(); CompletableFuture f = CompletableFuture.allOf(fs); @@ -2605,6 +2631,23 @@ public class CompletableFutureTest exten } } + public void testAllOf_backwards() throws Exception { + for (int k = 1; k < 20; ++k) { + CompletableFuture[] fs + = (CompletableFuture[]) new CompletableFuture[k]; + for (int i = 0; i < k; ++i) + fs[i] = new CompletableFuture<>(); + CompletableFuture f = CompletableFuture.allOf(fs); + for (int i = k - 1; i >= 0; i--) { + checkIncomplete(f); + checkIncomplete(CompletableFuture.allOf(fs)); + fs[i].complete(one); + } + checkCompletedNormally(f, null); + checkCompletedNormally(CompletableFuture.allOf(fs), null); + } + } + /** * anyOf(no component futures) returns an incomplete future */ @@ -2663,7 +2706,7 @@ public class CompletableFutureTest exten Runnable[] throwingActions = { () -> CompletableFuture.supplyAsync(null), () -> CompletableFuture.supplyAsync(null, exec), - () -> CompletableFuture.supplyAsync(supplyOne, null), + () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.DEFAULT, 42), null), () -> CompletableFuture.runAsync(null), () -> CompletableFuture.runAsync(null, exec),