--- jsr166/src/test/tck/CompletableFutureTest.java 2016/06/26 19:17:08 1.153 +++ jsr166/src/test/tck/CompletableFutureTest.java 2016/06/26 23:45:46 1.156 @@ -550,6 +550,15 @@ public class CompletableFutureTest exten } } + static class CountingRejectingExecutor implements Executor { + final RejectedExecutionException ex = new RejectedExecutionException(); + final AtomicInteger count = new AtomicInteger(0); + public void execute(Runnable r) { + count.getAndIncrement(); + throw ex; + } + } + // Used for explicit executor tests static final class ThreadExecutor implements Executor { final AtomicInteger count = new AtomicInteger(0); @@ -1234,6 +1243,18 @@ public class CompletableFutureTest exten r.assertInvoked(); }} + public void testRunAsync_rejectingExecutor() { + CountingRejectingExecutor e = new CountingRejectingExecutor(); + try { + CompletableFuture.runAsync(() -> {}, e); + shouldThrow(); + } catch (Throwable t) { + assertSame(e.ex, t); + } + + assertEquals(1, e.count.get()); + } + /** * supplyAsync completes with result of supplier */ @@ -1268,6 +1289,18 @@ public class CompletableFutureTest exten r.assertInvoked(); }} + public void testSupplyAsync_rejectingExecutor() { + CountingRejectingExecutor e = new CountingRejectingExecutor(); + try { + CompletableFuture.supplyAsync(() -> null, e); + shouldThrow(); + } catch (Throwable t) { + assertSame(e.ex, t); + } + + assertEquals(1, e.count.get()); + } + // seq completion methods /** @@ -3321,11 +3354,10 @@ public class CompletableFutureTest exten * Test submissions to an executor that rejects all tasks. */ public void testRejectingExecutor() { - final RejectedExecutionException ex = new RejectedExecutionException(); - final Executor e = (Runnable r) -> { throw ex; }; - for (Integer v : new Integer[] { 1, null }) { + final CountingRejectingExecutor e = new CountingRejectingExecutor(); + final CompletableFuture complete = CompletableFuture.completedFuture(v); final CompletableFuture incomplete = new CompletableFuture<>(); @@ -3355,7 +3387,7 @@ public class CompletableFutureTest exten for (CompletableFuture future : fs) { if (src.isDone()) - checkCompletedWithWrappedException(future, ex); + checkCompletedWithWrappedException(future, e.ex); else checkIncomplete(future); } @@ -3392,14 +3424,17 @@ public class CompletableFutureTest exten fs.add(incomplete.runAfterEitherAsync(complete, () -> {}, e)); for (CompletableFuture future : fs) - checkCompletedWithWrappedException(future, ex); + checkCompletedWithWrappedException(future, e.ex); futures.addAll(fs); } incomplete.complete(v); for (CompletableFuture future : futures) - checkCompletedWithWrappedException(future, ex); + checkCompletedWithWrappedException(future, e.ex); + + assertEquals(futures.size(), e.count.get()); + } } @@ -3409,14 +3444,6 @@ public class CompletableFutureTest exten * explicitly completed. */ public void testRejectingExecutorNeverInvoked() { - final RejectedExecutionException ex = new RejectedExecutionException(); - class CountingRejectingExecutor implements Executor { - final AtomicInteger count = new AtomicInteger(0); - public void execute(Runnable r) { - count.getAndIncrement(); - throw ex; - } - } final CountingRejectingExecutor e = new CountingRejectingExecutor(); for (Integer v : new Integer[] { 1, null }) { @@ -4143,6 +4170,49 @@ 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; + final CompletableFuture incomplete = new CompletableFuture<>(); + CompletableFuture f; + for (int i = 0; i < n; i++) { + f = new CompletableFuture<>(); + f.runAfterEither(incomplete, () -> {}); + f.complete(null); + + f = new CompletableFuture<>(); + f.acceptEither(incomplete, (x) -> {}); + f.complete(null); + + f = new CompletableFuture<>(); + f.applyToEither(incomplete, (x) -> x); + f.complete(null); + + f = new CompletableFuture<>(); + CompletableFuture.anyOf(new CompletableFuture[] { f, incomplete }); + f.complete(null); + } + + for (int i = 0; i < n; i++) { + f = new CompletableFuture<>(); + incomplete.runAfterEither(f, () -> {}); + f.complete(null); + + f = new CompletableFuture<>(); + incomplete.acceptEither(f, (x) -> {}); + f.complete(null); + + f = new CompletableFuture<>(); + incomplete.applyToEither(f, (x) -> x); + f.complete(null); + + f = new CompletableFuture<>(); + CompletableFuture.anyOf(new CompletableFuture[] { incomplete, f }); + f.complete(null); + } + } + // static U join(CompletionStage stage) { // CompletableFuture f = new CompletableFuture<>(); // stage.whenComplete((v, ex) -> {