--- jsr166/src/test/tck/CompletableFutureTest.java 2016/06/26 23:45:46 1.156 +++ jsr166/src/test/tck/CompletableFutureTest.java 2016/07/03 18:33:17 1.163 @@ -2700,6 +2700,7 @@ public class CompletableFutureTest exten for (ExecutionMode m : ExecutionMode.values()) for (Integer v1 : new Integer[] { 1, null }) for (Integer v2 : new Integer[] { 2, null }) + for (boolean pushNop : new boolean[] { true, false }) { final CompletableFuture f = new CompletableFuture<>(); final CompletableFuture g = new CompletableFuture<>(); @@ -2712,6 +2713,10 @@ public class CompletableFutureTest exten checkIncomplete(h1); rs[0].assertNotInvoked(); rs[1].assertNotInvoked(); + if (pushNop) { // ad hoc test of intra-completion interference + m.thenRun(f, () -> {}); + m.thenRun(g, () -> {}); + } f.complete(v1); checkCompletedNormally(h0, null); checkCompletedNormally(h1, null); @@ -3354,8 +3359,8 @@ public class CompletableFutureTest exten * Test submissions to an executor that rejects all tasks. */ public void testRejectingExecutor() { - for (Integer v : new Integer[] { 1, null }) { - + for (Integer v : new Integer[] { 1, null }) + { final CountingRejectingExecutor e = new CountingRejectingExecutor(); final CompletableFuture complete = CompletableFuture.completedFuture(v); @@ -3434,9 +3439,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedException(future, e.ex); assertEquals(futures.size(), e.count.get()); - - } - } + }} /** * Test submissions to an executor that rejects all tasks, but @@ -3444,10 +3447,10 @@ public class CompletableFutureTest exten * explicitly completed. */ public void testRejectingExecutorNeverInvoked() { + for (Integer v : new Integer[] { 1, null }) + { final CountingRejectingExecutor e = new CountingRejectingExecutor(); - for (Integer v : new Integer[] { 1, null }) { - final CompletableFuture complete = CompletableFuture.completedFuture(v); final CompletableFuture incomplete = new CompletableFuture<>(); @@ -3495,9 +3498,7 @@ public class CompletableFutureTest exten checkCompletedNormally(future, null); assertEquals(0, e.count.get()); - - } - } + }} /** * toCompletableFuture returns this CompletableFuture. @@ -4138,12 +4139,33 @@ public class CompletableFutureTest exten Monad.plus(godot, Monad.unit(5L))); } + /** Test long recursive chains of CompletableFutures with cascading completions */ + public void testRecursiveChains() throws Throwable { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean addDeadEnds : new boolean[] { true, false }) + { + final int val = 42; + final int n = expensiveTests ? 1_000 : 2; + CompletableFuture head = new CompletableFuture<>(); + CompletableFuture tail = head; + for (int i = 0; i < n; i++) { + if (addDeadEnds) m.thenApply(tail, v -> v + 1); + tail = m.thenApply(tail, v -> v + 1); + if (addDeadEnds) m.applyToEither(tail, tail, v -> v + 1); + tail = m.applyToEither(tail, tail, v -> v + 1); + if (addDeadEnds) m.thenCombine(tail, tail, (v, w) -> v + 1); + tail = m.thenCombine(tail, tail, (v, w) -> v + 1); + } + head.complete(val); + assertEquals(val + 3 * n, (int) tail.join()); + }} + /** * A single CompletableFuture with many dependents. * A demo of scalability - runtime is O(n). */ public void testManyDependents() throws Throwable { - final int n = 1_000; + final int n = expensiveTests ? 1_000_000 : 10; final CompletableFuture head = new CompletableFuture<>(); final CompletableFuture complete = CompletableFuture.completedFuture((Void)null); final AtomicInteger count = new AtomicInteger(0); @@ -4170,10 +4192,9 @@ public class CompletableFutureTest exten assertEquals(5 * 3 * n, count.get()); } - /** a66 -Dvmoptions=-Xmx8m -Djsr166.tckTestClass=CompletableFutureTest tck */ - public void testCoCompletionGarbage() throws Throwable { - // final int n = 3_000_000; - final int n = 100; + /** ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest tck */ + public void testCoCompletionGarbageRetention() throws Throwable { + final int n = expensiveTests ? 1_000_000 : 10; final CompletableFuture incomplete = new CompletableFuture<>(); CompletableFuture f; for (int i = 0; i < n; i++) { @@ -4213,6 +4234,36 @@ public class CompletableFutureTest exten } } + /* + * Tests below currently fail in stress mode due to memory retention. + * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest tck + */ + + /** Checks for garbage retention with anyOf. */ + public void testAnyOfGarbageRetention() throws Throwable { + for (Integer v : new Integer[] { 1, null }) + { + final int n = expensiveTests ? 100_000 : 10; + CompletableFuture[] fs + = (CompletableFuture[]) new CompletableFuture[100]; + for (int i = 0; i < fs.length; i++) + fs[i] = new CompletableFuture<>(); + fs[fs.length - 1].complete(v); + for (int i = 0; i < n; i++) + checkCompletedNormally(CompletableFuture.anyOf(fs), v); + }} + + /** Checks for garbage retention with allOf. */ + public void testCancelledAllOfGarbageRetention() throws Throwable { + final int n = expensiveTests ? 100_000 : 10; + CompletableFuture[] fs + = (CompletableFuture[]) new CompletableFuture[100]; + for (int i = 0; i < fs.length; i++) + fs[i] = new CompletableFuture<>(); + for (int i = 0; i < n; i++) + assertTrue(CompletableFuture.allOf(fs).cancel(false)); + } + // static U join(CompletionStage stage) { // CompletableFuture f = new CompletableFuture<>(); // stage.whenComplete((v, ex) -> {