1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea and Martin Buchholz with assistance from 30 * members of JCP JSR-166 Expert Group and released to the public 31 * domain, as explained at 32 * http://creativecommons.org/publicdomain/zero/1.0/ 33 */ 34 35 package test.java.util.concurrent.tck; 36 import static org.junit.Assert.assertEquals; 37 import static org.junit.Assert.assertFalse; 38 import static org.junit.Assert.assertNull; 39 import static org.junit.Assert.assertNotNull; 40 import static org.junit.Assert.assertSame; 41 import static org.junit.Assert.assertNotSame; 42 import static org.junit.Assert.assertTrue; 43 import static org.junit.Assert.fail; 44 45 46 import static java.util.concurrent.TimeUnit.MILLISECONDS; 47 import static java.util.concurrent.TimeUnit.SECONDS; 48 import static java.util.concurrent.CompletableFuture.completedFuture; 49 import static java.util.concurrent.CompletableFuture.failedFuture; 50 51 import java.lang.reflect.Method; 52 import java.lang.reflect.Modifier; 53 54 import java.util.stream.Collectors; 55 import java.util.stream.Stream; 56 57 import java.util.ArrayList; 58 import java.util.Arrays; 59 import java.util.List; 60 import java.util.Objects; 61 import java.util.Set; 62 import java.util.concurrent.Callable; 63 import java.util.concurrent.CancellationException; 64 import java.util.concurrent.CompletableFuture; 65 import java.util.concurrent.CompletionException; 66 import java.util.concurrent.CompletionStage; 67 import java.util.concurrent.ExecutionException; 68 import java.util.concurrent.Executor; 69 import java.util.concurrent.ForkJoinPool; 70 import java.util.concurrent.ForkJoinTask; 71 import java.util.concurrent.RejectedExecutionException; 72 import java.util.concurrent.TimeoutException; 73 import java.util.concurrent.atomic.AtomicInteger; 74 import java.util.concurrent.atomic.AtomicReference; 75 import java.util.function.BiConsumer; 76 import java.util.function.BiFunction; 77 import java.util.function.Consumer; 78 import java.util.function.Function; 79 import java.util.function.Predicate; 80 import java.util.function.Supplier; 81 82 import org.junit.Test; 83 import org.junit.runner.RunWith; 84 import org.junit.runners.JUnit4; 85 86 // Android-changed: Use JUnit4. 87 @RunWith(JUnit4.class) 88 public class CompletableFutureTest extends JSR166TestCase { 89 // Android-changed: Use JUnitCore.main. main(String[] args)90 public static void main(String[] args) { 91 // main(suite(), args); 92 org.junit.runner.JUnitCore.main("test.java.util.concurrent.tck.CompletableFutureTest"); 93 } 94 // public static Test suite() { 95 // return new TestSuite(CompletableFutureTest.class); 96 // } 97 98 static class CFException extends RuntimeException {} 99 checkIncomplete(CompletableFuture<?> f)100 void checkIncomplete(CompletableFuture<?> f) { 101 assertFalse(f.isDone()); 102 assertFalse(f.isCancelled()); 103 assertTrue(f.toString().matches(".*\\[.*Not completed.*\\]")); 104 105 Object result = null; 106 try { 107 result = f.getNow(null); 108 } catch (Throwable fail) { threadUnexpectedException(fail); } 109 assertNull(result); 110 111 try { 112 f.get(randomExpiredTimeout(), randomTimeUnit()); 113 shouldThrow(); 114 } 115 catch (TimeoutException success) {} 116 catch (Throwable fail) { threadUnexpectedException(fail); } 117 } 118 checkCompletedNormally(CompletableFuture<T> f, T expectedValue)119 <T> void checkCompletedNormally(CompletableFuture<T> f, T expectedValue) { 120 checkTimedGet(f, expectedValue); 121 122 mustEqual(expectedValue, f.join()); 123 mustEqual(expectedValue, f.getNow(null)); 124 125 T result = null; 126 try { 127 result = f.get(); 128 } catch (Throwable fail) { threadUnexpectedException(fail); } 129 mustEqual(expectedValue, result); 130 131 assertTrue(f.isDone()); 132 assertFalse(f.isCancelled()); 133 assertFalse(f.isCompletedExceptionally()); 134 assertTrue(f.toString().matches(".*\\[.*Completed normally.*\\]")); 135 } 136 137 /** 138 * Returns the "raw" internal exceptional completion of f, 139 * without any additional wrapping with CompletionException. 140 */ exceptionalCompletion(CompletableFuture<?> f)141 Throwable exceptionalCompletion(CompletableFuture<?> f) { 142 // handle (and whenComplete and exceptionally) can distinguish 143 // between "direct" and "wrapped" exceptional completion 144 return f.handle((u, t) -> t).join(); 145 } 146 checkCompletedExceptionally(CompletableFuture<?> f, boolean wrapped, Consumer<Throwable> checker)147 void checkCompletedExceptionally(CompletableFuture<?> f, 148 boolean wrapped, 149 Consumer<Throwable> checker) { 150 Throwable cause = exceptionalCompletion(f); 151 if (wrapped) { 152 assertTrue(cause instanceof CompletionException); 153 cause = cause.getCause(); 154 } 155 checker.accept(cause); 156 157 long startTime = System.nanoTime(); 158 try { 159 f.get(LONG_DELAY_MS, MILLISECONDS); 160 shouldThrow(); 161 } catch (ExecutionException success) { 162 assertSame(cause, success.getCause()); 163 } catch (Throwable fail) { threadUnexpectedException(fail); } 164 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); 165 166 try { 167 f.join(); 168 shouldThrow(); 169 } catch (CompletionException success) { 170 assertSame(cause, success.getCause()); 171 } catch (Throwable fail) { threadUnexpectedException(fail); } 172 173 try { 174 f.getNow(null); 175 shouldThrow(); 176 } catch (CompletionException success) { 177 assertSame(cause, success.getCause()); 178 } catch (Throwable fail) { threadUnexpectedException(fail); } 179 180 try { 181 f.get(); 182 shouldThrow(); 183 } catch (ExecutionException success) { 184 assertSame(cause, success.getCause()); 185 } catch (Throwable fail) { threadUnexpectedException(fail); } 186 187 assertFalse(f.isCancelled()); 188 assertTrue(f.isDone()); 189 assertTrue(f.isCompletedExceptionally()); 190 assertTrue(f.toString().matches(".*\\[.*Completed exceptionally.*\\]")); 191 } 192 193 void checkCompletedWithWrappedCFException(CompletableFuture<?> f) { 194 checkCompletedExceptionally(f, true, 195 t -> assertTrue(t instanceof CFException)); 196 } 197 checkCompletedWithWrappedCancellationException(CompletableFuture<?> f)198 void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) { 199 checkCompletedExceptionally(f, true, 200 t -> assertTrue(t instanceof CancellationException)); 201 } 202 checkCompletedWithTimeoutException(CompletableFuture<?> f)203 void checkCompletedWithTimeoutException(CompletableFuture<?> f) { 204 checkCompletedExceptionally(f, false, 205 t -> assertTrue(t instanceof TimeoutException)); 206 } 207 checkCompletedWithWrappedException(CompletableFuture<?> f, Throwable ex)208 void checkCompletedWithWrappedException(CompletableFuture<?> f, 209 Throwable ex) { 210 checkCompletedExceptionally(f, true, t -> assertSame(t, ex)); 211 } 212 checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex)213 void checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex) { 214 checkCompletedExceptionally(f, false, t -> assertSame(t, ex)); 215 } 216 checkCancelled(CompletableFuture<?> f)217 void checkCancelled(CompletableFuture<?> f) { 218 long startTime = System.nanoTime(); 219 try { 220 f.get(LONG_DELAY_MS, MILLISECONDS); 221 shouldThrow(); 222 } catch (CancellationException success) { 223 } catch (Throwable fail) { threadUnexpectedException(fail); } 224 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); 225 226 try { 227 f.join(); 228 shouldThrow(); 229 } catch (CancellationException success) {} 230 try { 231 f.getNow(null); 232 shouldThrow(); 233 } catch (CancellationException success) {} 234 try { 235 f.get(); 236 shouldThrow(); 237 } catch (CancellationException success) { 238 } catch (Throwable fail) { threadUnexpectedException(fail); } 239 240 assertTrue(exceptionalCompletion(f) instanceof CancellationException); 241 242 assertTrue(f.isDone()); 243 assertTrue(f.isCompletedExceptionally()); 244 assertTrue(f.isCancelled()); 245 assertTrue(f.toString().matches(".*\\[.*Completed exceptionally.*\\]")); 246 } 247 248 /** 249 * A newly constructed CompletableFuture is incomplete, as indicated 250 * by methods isDone, isCancelled, and getNow 251 */ 252 @Test 253 public void testConstructor() { 254 CompletableFuture<Item> f = new CompletableFuture<>(); 255 checkIncomplete(f); 256 } 257 258 /** 259 * complete completes normally, as indicated by methods isDone, 260 * isCancelled, join, get, and getNow 261 */ 262 @Test 263 public void testComplete() { 264 for (Item v1 : new Item[] { itemOne, null }) 265 { 266 CompletableFuture<Item> f = new CompletableFuture<>(); 267 checkIncomplete(f); 268 assertTrue(f.complete(v1)); 269 assertFalse(f.complete(v1)); 270 checkCompletedNormally(f, v1); 271 }} 272 273 /** 274 * completeExceptionally completes exceptionally, as indicated by 275 * methods isDone, isCancelled, join, get, and getNow 276 */ 277 @Test 278 public void testCompleteExceptionally() { 279 CompletableFuture<Item> f = new CompletableFuture<>(); 280 CFException ex = new CFException(); 281 checkIncomplete(f); 282 f.completeExceptionally(ex); 283 checkCompletedExceptionally(f, ex); 284 } 285 286 /** 287 * cancel completes exceptionally and reports cancelled, as indicated by 288 * methods isDone, isCancelled, join, get, and getNow 289 */ 290 @Test 291 public void testCancel() { 292 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 293 { 294 CompletableFuture<Item> f = new CompletableFuture<>(); 295 checkIncomplete(f); 296 assertTrue(f.cancel(mayInterruptIfRunning)); 297 assertTrue(f.cancel(mayInterruptIfRunning)); 298 assertTrue(f.cancel(!mayInterruptIfRunning)); 299 checkCancelled(f); 300 }} 301 302 /** 303 * obtrudeValue forces completion with given value 304 */ 305 @Test 306 public void testObtrudeValue() { 307 CompletableFuture<Item> f = new CompletableFuture<>(); 308 checkIncomplete(f); 309 assertTrue(f.complete(itemOne)); 310 checkCompletedNormally(f, itemOne); 311 f.obtrudeValue(itemThree); 312 checkCompletedNormally(f, itemThree); 313 f.obtrudeValue(itemTwo); 314 checkCompletedNormally(f, itemTwo); 315 f = new CompletableFuture<>(); 316 f.obtrudeValue(itemThree); 317 checkCompletedNormally(f, itemThree); 318 f.obtrudeValue(null); 319 checkCompletedNormally(f, null); 320 f = new CompletableFuture<>(); 321 f.completeExceptionally(new CFException()); 322 f.obtrudeValue(itemFour); 323 checkCompletedNormally(f, itemFour); 324 } 325 326 /** 327 * obtrudeException forces completion with given exception 328 */ 329 @Test 330 public void testObtrudeException() { 331 for (Item v1 : new Item[] { itemOne, null }) 332 { 333 CFException ex; 334 CompletableFuture<Item> f; 335 336 f = new CompletableFuture<>(); 337 assertTrue(f.complete(v1)); 338 for (int i = 0; i < 2; i++) { 339 f.obtrudeException(ex = new CFException()); 340 checkCompletedExceptionally(f, ex); 341 } 342 343 f = new CompletableFuture<>(); 344 for (int i = 0; i < 2; i++) { 345 f.obtrudeException(ex = new CFException()); 346 checkCompletedExceptionally(f, ex); 347 } 348 349 f = new CompletableFuture<>(); 350 f.completeExceptionally(new CFException()); 351 f.obtrudeValue(v1); 352 checkCompletedNormally(f, v1); 353 f.obtrudeException(ex = new CFException()); 354 checkCompletedExceptionally(f, ex); 355 f.completeExceptionally(new CFException()); 356 checkCompletedExceptionally(f, ex); 357 assertFalse(f.complete(v1)); 358 checkCompletedExceptionally(f, ex); 359 }} 360 361 /** 362 * getNumberOfDependents returns number of dependent tasks 363 */ 364 @Test 365 public void testGetNumberOfDependents() { 366 for (ExecutionMode m : ExecutionMode.values()) 367 for (Item v1 : new Item[] { itemOne, null }) 368 { 369 CompletableFuture<Item> f = new CompletableFuture<>(); 370 mustEqual(0, f.getNumberOfDependents()); 371 final CompletableFuture<Void> g = m.thenRun(f, new Noop(m)); 372 mustEqual(1, f.getNumberOfDependents()); 373 mustEqual(0, g.getNumberOfDependents()); 374 final CompletableFuture<Void> h = m.thenRun(f, new Noop(m)); 375 mustEqual(2, f.getNumberOfDependents()); 376 mustEqual(0, h.getNumberOfDependents()); 377 assertTrue(f.complete(v1)); 378 checkCompletedNormally(g, null); 379 checkCompletedNormally(h, null); 380 mustEqual(0, f.getNumberOfDependents()); 381 mustEqual(0, g.getNumberOfDependents()); 382 mustEqual(0, h.getNumberOfDependents()); 383 }} 384 385 /** 386 * toString indicates current completion state 387 */ 388 @Test 389 public void testToString_incomplete() { 390 CompletableFuture<String> f = new CompletableFuture<>(); 391 assertTrue(f.toString().matches(".*\\[.*Not completed.*\\]")); 392 } 393 394 @Test 395 public void testToString_normal() { 396 CompletableFuture<String> f = new CompletableFuture<>(); 397 assertTrue(f.complete("foo")); 398 assertTrue(f.toString().matches(".*\\[.*Completed normally.*\\]")); 399 } 400 401 @Test 402 public void testToString_exception() { 403 CompletableFuture<String> f = new CompletableFuture<>(); 404 assertTrue(f.completeExceptionally(new IndexOutOfBoundsException())); 405 assertTrue(f.toString().matches(".*\\[.*Completed exceptionally.*\\]")); 406 } 407 408 @Test 409 public void testToString_cancelled() { 410 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) { 411 CompletableFuture<String> f = new CompletableFuture<>(); 412 assertTrue(f.cancel(mayInterruptIfRunning)); 413 assertTrue(f.toString().matches(".*\\[.*Completed exceptionally.*\\]")); 414 } 415 } 416 417 /** 418 * completedFuture returns a completed CompletableFuture with given value 419 */ 420 @Test 421 public void testCompletedFuture() { 422 CompletableFuture<String> f = CompletableFuture.completedFuture("test"); 423 checkCompletedNormally(f, "test"); 424 } 425 426 abstract static class CheckedAction { 427 int invocationCount = 0; 428 final ExecutionMode m; 429 CheckedAction(ExecutionMode m) { this.m = m; } 430 void invoked() { 431 m.checkExecutionMode(); 432 mustEqual(0, invocationCount++); 433 } 434 void assertNotInvoked() { mustEqual(0, invocationCount); } 435 void assertInvoked() { mustEqual(1, invocationCount); } 436 } 437 438 abstract static class CheckedItemAction extends CheckedAction { 439 Item value; 440 CheckedItemAction(ExecutionMode m) { super(m); } 441 void assertValue(Item expected) { 442 assertInvoked(); 443 mustEqual(expected, value); 444 } 445 } 446 447 static class ItemSupplier extends CheckedAction 448 implements Supplier<Item> 449 { 450 final Item value; 451 ItemSupplier(ExecutionMode m, Item value) { 452 super(m); 453 this.value = value; 454 } 455 public Item get() { 456 invoked(); 457 return value; 458 } 459 } 460 461 // A function that handles and produces null values as well. 462 static Item inc(Item x) { 463 return (x == null) ? null : new Item(x.value + 1); 464 } 465 466 static class NoopConsumer extends CheckedItemAction 467 implements Consumer<Item> 468 { 469 NoopConsumer(ExecutionMode m) { super(m); } 470 public void accept(Item x) { 471 invoked(); 472 value = x; 473 } 474 } 475 476 static class IncFunction extends CheckedItemAction 477 implements Function<Item,Item> 478 { 479 IncFunction(ExecutionMode m) { super(m); } 480 public Item apply(Item x) { 481 invoked(); 482 return value = inc(x); 483 } 484 } 485 486 // Choose non-commutative actions for better coverage 487 // A non-commutative function that handles and produces null values as well. 488 static Item subtract(Item x, Item y) { 489 return (x == null && y == null) ? null : 490 new Item(((x == null) ? 42 : x.value) 491 - ((y == null) ? 99 : y.value)); 492 } 493 494 static class SubtractAction extends CheckedItemAction 495 implements BiConsumer<Item, Item> 496 { 497 SubtractAction(ExecutionMode m) { super(m); } 498 public void accept(Item x, Item y) { 499 invoked(); 500 value = subtract(x, y); 501 } 502 } 503 504 static class SubtractFunction extends CheckedItemAction 505 implements BiFunction<Item, Item, Item> 506 { 507 SubtractFunction(ExecutionMode m) { super(m); } 508 public Item apply(Item x, Item y) { 509 invoked(); 510 return value = subtract(x, y); 511 } 512 } 513 514 static class Noop extends CheckedAction implements Runnable { 515 Noop(ExecutionMode m) { super(m); } 516 public void run() { 517 invoked(); 518 } 519 } 520 521 static class FailingSupplier extends CheckedAction 522 implements Supplier<Item> 523 { 524 final CFException ex; 525 FailingSupplier(ExecutionMode m) { super(m); ex = new CFException(); } 526 public Item get() { 527 invoked(); 528 throw ex; 529 } 530 } 531 532 static class FailingConsumer extends CheckedItemAction 533 implements Consumer<Item> 534 { 535 final CFException ex; 536 FailingConsumer(ExecutionMode m) { super(m); ex = new CFException(); } 537 public void accept(Item x) { 538 invoked(); 539 value = x; 540 throw ex; 541 } 542 } 543 544 static class FailingBiConsumer extends CheckedItemAction 545 implements BiConsumer<Item, Item> 546 { 547 final CFException ex; 548 FailingBiConsumer(ExecutionMode m) { super(m); ex = new CFException(); } 549 public void accept(Item x, Item y) { 550 invoked(); 551 value = subtract(x, y); 552 throw ex; 553 } 554 } 555 556 static class FailingFunction extends CheckedItemAction 557 implements Function<Item, Item> 558 { 559 final CFException ex; 560 FailingFunction(ExecutionMode m) { super(m); ex = new CFException(); } 561 public Item apply(Item x) { 562 invoked(); 563 value = x; 564 throw ex; 565 } 566 } 567 568 static class FailingBiFunction extends CheckedItemAction 569 implements BiFunction<Item, Item, Item> 570 { 571 final CFException ex; 572 FailingBiFunction(ExecutionMode m) { super(m); ex = new CFException(); } 573 public Item apply(Item x, Item y) { 574 invoked(); 575 value = subtract(x, y); 576 throw ex; 577 } 578 } 579 580 static class FailingRunnable extends CheckedAction implements Runnable { 581 final CFException ex; 582 FailingRunnable(ExecutionMode m) { super(m); ex = new CFException(); } 583 public void run() { 584 invoked(); 585 throw ex; 586 } 587 } 588 589 static class CompletableFutureInc extends CheckedItemAction 590 implements Function<Item, CompletableFuture<Item>> 591 { 592 CompletableFutureInc(ExecutionMode m) { super(m); } 593 public CompletableFuture<Item> apply(Item x) { 594 invoked(); 595 value = x; 596 return CompletableFuture.completedFuture(inc(x)); 597 } 598 } 599 600 static class FailingExceptionalCompletableFutureFunction extends CheckedAction 601 implements Function<Throwable, CompletableFuture<Item>> 602 { 603 final CFException ex; 604 FailingExceptionalCompletableFutureFunction(ExecutionMode m) { super(m); ex = new CFException(); } 605 public CompletableFuture<Item> apply(Throwable x) { 606 invoked(); 607 throw ex; 608 } 609 } 610 611 static class ExceptionalCompletableFutureFunction extends CheckedAction 612 implements Function<Throwable, CompletionStage<Item>> { 613 final Item value = itemThree; 614 ExceptionalCompletableFutureFunction(ExecutionMode m) { super(m); } 615 public CompletionStage<Item> apply(Throwable x) { 616 invoked(); 617 return CompletableFuture.completedFuture(value); 618 } 619 } 620 621 static class FailingCompletableFutureFunction extends CheckedItemAction 622 implements Function<Item, CompletableFuture<Item>> 623 { 624 final CFException ex; 625 FailingCompletableFutureFunction(ExecutionMode m) { super(m); ex = new CFException(); } 626 public CompletableFuture<Item> apply(Item x) { 627 invoked(); 628 value = x; 629 throw ex; 630 } 631 } 632 633 static class CountingRejectingExecutor implements Executor { 634 final RejectedExecutionException ex = new RejectedExecutionException(); 635 final AtomicInteger count = new AtomicInteger(0); 636 public void execute(Runnable r) { 637 count.getAndIncrement(); 638 throw ex; 639 } 640 } 641 642 // Used for explicit executor tests 643 static final class ThreadExecutor implements Executor { 644 final AtomicInteger count = new AtomicInteger(0); 645 static final ThreadGroup tg = new ThreadGroup("ThreadExecutor"); 646 static boolean startedCurrentThread() { 647 return Thread.currentThread().getThreadGroup() == tg; 648 } 649 650 public void execute(Runnable r) { 651 count.getAndIncrement(); 652 new Thread(tg, r).start(); 653 } 654 } 655 656 static final boolean defaultExecutorIsCommonPool 657 = ForkJoinPool.getCommonPoolParallelism() > 1; 658 659 /** 660 * Permits the testing of parallel code for the 3 different 661 * execution modes without copy/pasting all the test methods. 662 */ 663 enum ExecutionMode { 664 SYNC { 665 public void checkExecutionMode() { 666 assertFalse(ThreadExecutor.startedCurrentThread()); 667 assertNull(ForkJoinTask.getPool()); 668 } 669 public CompletableFuture<Void> runAsync(Runnable a) { 670 throw new UnsupportedOperationException(); 671 } 672 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) { 673 throw new UnsupportedOperationException(); 674 } 675 public <T> CompletableFuture<Void> thenRun 676 (CompletableFuture<T> f, Runnable a) { 677 return f.thenRun(a); 678 } 679 public <T> CompletableFuture<Void> thenAccept 680 (CompletableFuture<T> f, Consumer<? super T> a) { 681 return f.thenAccept(a); 682 } 683 public <T,U> CompletableFuture<U> thenApply 684 (CompletableFuture<T> f, Function<? super T,U> a) { 685 return f.thenApply(a); 686 } 687 public <T,U> CompletableFuture<U> thenCompose 688 (CompletableFuture<T> f, 689 Function<? super T,? extends CompletionStage<U>> a) { 690 return f.thenCompose(a); 691 } 692 public <T,U> CompletableFuture<U> handle 693 (CompletableFuture<T> f, 694 BiFunction<? super T,Throwable,? extends U> a) { 695 return f.handle(a); 696 } 697 public <T> CompletableFuture<T> whenComplete 698 (CompletableFuture<T> f, 699 BiConsumer<? super T,? super Throwable> a) { 700 return f.whenComplete(a); 701 } 702 public <T,U> CompletableFuture<Void> runAfterBoth 703 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) { 704 return f.runAfterBoth(g, a); 705 } 706 public <T,U> CompletableFuture<Void> thenAcceptBoth 707 (CompletableFuture<T> f, 708 CompletionStage<? extends U> g, 709 BiConsumer<? super T,? super U> a) { 710 return f.thenAcceptBoth(g, a); 711 } 712 public <T,U,V> CompletableFuture<V> thenCombine 713 (CompletableFuture<T> f, 714 CompletionStage<? extends U> g, 715 BiFunction<? super T,? super U,? extends V> a) { 716 return f.thenCombine(g, a); 717 } 718 public <T> CompletableFuture<Void> runAfterEither 719 (CompletableFuture<T> f, 720 CompletionStage<?> g, 721 java.lang.Runnable a) { 722 return f.runAfterEither(g, a); 723 } 724 public <T> CompletableFuture<Void> acceptEither 725 (CompletableFuture<T> f, 726 CompletionStage<? extends T> g, 727 Consumer<? super T> a) { 728 return f.acceptEither(g, a); 729 } 730 public <T,U> CompletableFuture<U> applyToEither 731 (CompletableFuture<T> f, 732 CompletionStage<? extends T> g, 733 Function<? super T,U> a) { 734 return f.applyToEither(g, a); 735 } 736 public <T> CompletableFuture<T> exceptionally 737 (CompletableFuture<T> f, 738 Function<Throwable, ? extends T> fn) { 739 return f.exceptionally(fn); 740 } 741 public <T> CompletableFuture<T> exceptionallyCompose 742 (CompletableFuture<T> f, Function<Throwable, ? extends CompletionStage<T>> fn) { 743 return f.exceptionallyCompose(fn); 744 } 745 }, 746 ASYNC { 747 public void checkExecutionMode() { 748 mustEqual(defaultExecutorIsCommonPool, 749 (ForkJoinPool.commonPool() == ForkJoinTask.getPool())); 750 } 751 public CompletableFuture<Void> runAsync(Runnable a) { 752 return CompletableFuture.runAsync(a); 753 } 754 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) { 755 return CompletableFuture.supplyAsync(a); 756 } 757 public <T> CompletableFuture<Void> thenRun 758 (CompletableFuture<T> f, Runnable a) { 759 return f.thenRunAsync(a); 760 } 761 public <T> CompletableFuture<Void> thenAccept 762 (CompletableFuture<T> f, Consumer<? super T> a) { 763 return f.thenAcceptAsync(a); 764 } 765 public <T,U> CompletableFuture<U> thenApply 766 (CompletableFuture<T> f, Function<? super T,U> a) { 767 return f.thenApplyAsync(a); 768 } 769 public <T,U> CompletableFuture<U> thenCompose 770 (CompletableFuture<T> f, 771 Function<? super T,? extends CompletionStage<U>> a) { 772 return f.thenComposeAsync(a); 773 } 774 public <T,U> CompletableFuture<U> handle 775 (CompletableFuture<T> f, 776 BiFunction<? super T,Throwable,? extends U> a) { 777 return f.handleAsync(a); 778 } 779 public <T> CompletableFuture<T> whenComplete 780 (CompletableFuture<T> f, 781 BiConsumer<? super T,? super Throwable> a) { 782 return f.whenCompleteAsync(a); 783 } 784 public <T,U> CompletableFuture<Void> runAfterBoth 785 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) { 786 return f.runAfterBothAsync(g, a); 787 } 788 public <T,U> CompletableFuture<Void> thenAcceptBoth 789 (CompletableFuture<T> f, 790 CompletionStage<? extends U> g, 791 BiConsumer<? super T,? super U> a) { 792 return f.thenAcceptBothAsync(g, a); 793 } 794 public <T,U,V> CompletableFuture<V> thenCombine 795 (CompletableFuture<T> f, 796 CompletionStage<? extends U> g, 797 BiFunction<? super T,? super U,? extends V> a) { 798 return f.thenCombineAsync(g, a); 799 } 800 public <T> CompletableFuture<Void> runAfterEither 801 (CompletableFuture<T> f, 802 CompletionStage<?> g, 803 java.lang.Runnable a) { 804 return f.runAfterEitherAsync(g, a); 805 } 806 public <T> CompletableFuture<Void> acceptEither 807 (CompletableFuture<T> f, 808 CompletionStage<? extends T> g, 809 Consumer<? super T> a) { 810 return f.acceptEitherAsync(g, a); 811 } 812 public <T,U> CompletableFuture<U> applyToEither 813 (CompletableFuture<T> f, 814 CompletionStage<? extends T> g, 815 Function<? super T,U> a) { 816 return f.applyToEitherAsync(g, a); 817 } 818 public <T> CompletableFuture<T> exceptionally 819 (CompletableFuture<T> f, 820 Function<Throwable, ? extends T> fn) { 821 return f.exceptionallyAsync(fn); 822 } 823 824 public <T> CompletableFuture<T> exceptionallyCompose 825 (CompletableFuture<T> f, Function<Throwable, ? extends CompletionStage<T>> fn) { 826 return f.exceptionallyComposeAsync(fn); 827 } 828 829 }, 830 831 EXECUTOR { 832 public void checkExecutionMode() { 833 assertTrue(ThreadExecutor.startedCurrentThread()); 834 } 835 public CompletableFuture<Void> runAsync(Runnable a) { 836 return CompletableFuture.runAsync(a, new ThreadExecutor()); 837 } 838 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) { 839 return CompletableFuture.supplyAsync(a, new ThreadExecutor()); 840 } 841 public <T> CompletableFuture<Void> thenRun 842 (CompletableFuture<T> f, Runnable a) { 843 return f.thenRunAsync(a, new ThreadExecutor()); 844 } 845 public <T> CompletableFuture<Void> thenAccept 846 (CompletableFuture<T> f, Consumer<? super T> a) { 847 return f.thenAcceptAsync(a, new ThreadExecutor()); 848 } 849 public <T,U> CompletableFuture<U> thenApply 850 (CompletableFuture<T> f, Function<? super T,U> a) { 851 return f.thenApplyAsync(a, new ThreadExecutor()); 852 } 853 public <T,U> CompletableFuture<U> thenCompose 854 (CompletableFuture<T> f, 855 Function<? super T,? extends CompletionStage<U>> a) { 856 return f.thenComposeAsync(a, new ThreadExecutor()); 857 } 858 public <T,U> CompletableFuture<U> handle 859 (CompletableFuture<T> f, 860 BiFunction<? super T,Throwable,? extends U> a) { 861 return f.handleAsync(a, new ThreadExecutor()); 862 } 863 public <T> CompletableFuture<T> whenComplete 864 (CompletableFuture<T> f, 865 BiConsumer<? super T,? super Throwable> a) { 866 return f.whenCompleteAsync(a, new ThreadExecutor()); 867 } 868 public <T,U> CompletableFuture<Void> runAfterBoth 869 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) { 870 return f.runAfterBothAsync(g, a, new ThreadExecutor()); 871 } 872 public <T,U> CompletableFuture<Void> thenAcceptBoth 873 (CompletableFuture<T> f, 874 CompletionStage<? extends U> g, 875 BiConsumer<? super T,? super U> a) { 876 return f.thenAcceptBothAsync(g, a, new ThreadExecutor()); 877 } 878 public <T,U,V> CompletableFuture<V> thenCombine 879 (CompletableFuture<T> f, 880 CompletionStage<? extends U> g, 881 BiFunction<? super T,? super U,? extends V> a) { 882 return f.thenCombineAsync(g, a, new ThreadExecutor()); 883 } 884 public <T> CompletableFuture<Void> runAfterEither 885 (CompletableFuture<T> f, 886 CompletionStage<?> g, 887 java.lang.Runnable a) { 888 return f.runAfterEitherAsync(g, a, new ThreadExecutor()); 889 } 890 public <T> CompletableFuture<Void> acceptEither 891 (CompletableFuture<T> f, 892 CompletionStage<? extends T> g, 893 Consumer<? super T> a) { 894 return f.acceptEitherAsync(g, a, new ThreadExecutor()); 895 } 896 public <T,U> CompletableFuture<U> applyToEither 897 (CompletableFuture<T> f, 898 CompletionStage<? extends T> g, 899 Function<? super T,U> a) { 900 return f.applyToEitherAsync(g, a, new ThreadExecutor()); 901 } 902 public <T> CompletableFuture<T> exceptionally 903 (CompletableFuture<T> f, 904 Function<Throwable, ? extends T> fn) { 905 return f.exceptionallyAsync(fn, new ThreadExecutor()); 906 } 907 public <T> CompletableFuture<T> exceptionallyCompose 908 (CompletableFuture<T> f, Function<Throwable, ? extends CompletionStage<T>> fn) { 909 return f.exceptionallyComposeAsync(fn, new ThreadExecutor()); 910 } 911 912 }; 913 914 public abstract void checkExecutionMode(); 915 public abstract CompletableFuture<Void> runAsync(Runnable a); 916 public abstract <U> CompletableFuture<U> supplyAsync(Supplier<U> a); 917 public abstract <T> CompletableFuture<Void> thenRun 918 (CompletableFuture<T> f, Runnable a); 919 public abstract <T> CompletableFuture<Void> thenAccept 920 (CompletableFuture<T> f, Consumer<? super T> a); 921 public abstract <T,U> CompletableFuture<U> thenApply 922 (CompletableFuture<T> f, Function<? super T,U> a); 923 public abstract <T,U> CompletableFuture<U> thenCompose 924 (CompletableFuture<T> f, 925 Function<? super T,? extends CompletionStage<U>> a); 926 public abstract <T,U> CompletableFuture<U> handle 927 (CompletableFuture<T> f, 928 BiFunction<? super T,Throwable,? extends U> a); 929 public abstract <T> CompletableFuture<T> whenComplete 930 (CompletableFuture<T> f, 931 BiConsumer<? super T,? super Throwable> a); 932 public abstract <T,U> CompletableFuture<Void> runAfterBoth 933 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a); 934 public abstract <T,U> CompletableFuture<Void> thenAcceptBoth 935 (CompletableFuture<T> f, 936 CompletionStage<? extends U> g, 937 BiConsumer<? super T,? super U> a); 938 public abstract <T,U,V> CompletableFuture<V> thenCombine 939 (CompletableFuture<T> f, 940 CompletionStage<? extends U> g, 941 BiFunction<? super T,? super U,? extends V> a); 942 public abstract <T> CompletableFuture<Void> runAfterEither 943 (CompletableFuture<T> f, 944 CompletionStage<?> g, 945 java.lang.Runnable a); 946 public abstract <T> CompletableFuture<Void> acceptEither 947 (CompletableFuture<T> f, 948 CompletionStage<? extends T> g, 949 Consumer<? super T> a); 950 public abstract <T,U> CompletableFuture<U> applyToEither 951 (CompletableFuture<T> f, 952 CompletionStage<? extends T> g, 953 Function<? super T,U> a); 954 public abstract <T> CompletableFuture<T> exceptionally 955 (CompletableFuture<T> f, 956 Function<Throwable, ? extends T> fn); 957 public abstract <T> CompletableFuture<T> exceptionallyCompose 958 (CompletableFuture<T> f, 959 Function<Throwable, ? extends CompletionStage<T>> fn); 960 } 961 962 /** 963 * exceptionally action is not invoked when source completes 964 * normally, and source result is propagated 965 */ 966 @Test 967 public void testExceptionally_normalCompletion() { 968 for (ExecutionMode m : ExecutionMode.values()) 969 for (boolean createIncomplete : new boolean[] { true, false }) 970 for (Item v1 : new Item[] { itemOne, null }) 971 { 972 final AtomicInteger ran = new AtomicInteger(0); 973 final CompletableFuture<Item> f = new CompletableFuture<>(); 974 if (!createIncomplete) assertTrue(f.complete(v1)); 975 final CompletableFuture<Item> g = m.exceptionally 976 (f, (Throwable t) -> { 977 ran.getAndIncrement(); 978 throw new AssertionError("should not be called"); 979 }); 980 if (createIncomplete) assertTrue(f.complete(v1)); 981 982 checkCompletedNormally(g, v1); 983 checkCompletedNormally(f, v1); 984 mustEqual(0, ran.get()); 985 }} 986 987 /** 988 * exceptionally action completes with function value on source 989 * exception 990 */ 991 @Test 992 public void testExceptionally_exceptionalCompletion() { 993 for (ExecutionMode m : ExecutionMode.values()) 994 for (boolean createIncomplete : new boolean[] { true, false }) 995 for (Item v1 : new Item[] { itemOne, null }) 996 { 997 final AtomicInteger ran = new AtomicInteger(0); 998 final CFException ex = new CFException(); 999 final CompletableFuture<Item> f = new CompletableFuture<>(); 1000 if (!createIncomplete) f.completeExceptionally(ex); 1001 final CompletableFuture<Item> g = m.exceptionally 1002 (f, (Throwable t) -> { 1003 m.checkExecutionMode(); 1004 assertSame(t, ex); 1005 ran.getAndIncrement(); 1006 return v1; 1007 }); 1008 if (createIncomplete) f.completeExceptionally(ex); 1009 1010 checkCompletedNormally(g, v1); 1011 mustEqual(1, ran.get()); 1012 }} 1013 1014 /** 1015 * If an "exceptionally action" throws an exception, it completes 1016 * exceptionally with that exception 1017 */ 1018 @Test testExceptionally_exceptionalCompletionActionFailed()1019 public void testExceptionally_exceptionalCompletionActionFailed() { 1020 for (ExecutionMode m : ExecutionMode.values()) 1021 for (boolean createIncomplete : new boolean[] { true, false }) 1022 { 1023 final AtomicInteger ran = new AtomicInteger(0); 1024 final CFException ex1 = new CFException(); 1025 final CFException ex2 = new CFException(); 1026 final CompletableFuture<Item> f = new CompletableFuture<>(); 1027 if (!createIncomplete) f.completeExceptionally(ex1); 1028 final CompletableFuture<Item> g = m.exceptionally 1029 (f, (Throwable t) -> { 1030 m.checkExecutionMode(); 1031 assertSame(t, ex1); 1032 ran.getAndIncrement(); 1033 throw ex2; 1034 }); 1035 if (createIncomplete) f.completeExceptionally(ex1); 1036 1037 checkCompletedWithWrappedException(g, ex2); 1038 checkCompletedExceptionally(f, ex1); 1039 mustEqual(1, ran.get()); 1040 }} 1041 1042 /** 1043 * whenComplete action executes on normal completion, propagating 1044 * source result. 1045 */ 1046 @Test testWhenComplete_normalCompletion()1047 public void testWhenComplete_normalCompletion() { 1048 for (ExecutionMode m : ExecutionMode.values()) 1049 for (boolean createIncomplete : new boolean[] { true, false }) 1050 for (Item v1 : new Item[] { itemOne, null }) 1051 { 1052 final AtomicInteger ran = new AtomicInteger(0); 1053 final CompletableFuture<Item> f = new CompletableFuture<>(); 1054 if (!createIncomplete) assertTrue(f.complete(v1)); 1055 final CompletableFuture<Item> g = m.whenComplete 1056 (f, 1057 (Item result, Throwable t) -> { 1058 m.checkExecutionMode(); 1059 assertSame(result, v1); 1060 assertNull(t); 1061 ran.getAndIncrement(); 1062 }); 1063 if (createIncomplete) assertTrue(f.complete(v1)); 1064 1065 checkCompletedNormally(g, v1); 1066 checkCompletedNormally(f, v1); 1067 mustEqual(1, ran.get()); 1068 }} 1069 1070 /** 1071 * whenComplete action executes on exceptional completion, propagating 1072 * source result. 1073 */ 1074 @Test testWhenComplete_exceptionalCompletion()1075 public void testWhenComplete_exceptionalCompletion() { 1076 for (ExecutionMode m : ExecutionMode.values()) 1077 for (boolean createIncomplete : new boolean[] { true, false }) 1078 { 1079 final AtomicInteger ran = new AtomicInteger(0); 1080 final CFException ex = new CFException(); 1081 final CompletableFuture<Item> f = new CompletableFuture<>(); 1082 if (!createIncomplete) f.completeExceptionally(ex); 1083 final CompletableFuture<Item> g = m.whenComplete 1084 (f, 1085 (Item result, Throwable t) -> { 1086 m.checkExecutionMode(); 1087 assertNull(result); 1088 assertSame(t, ex); 1089 ran.getAndIncrement(); 1090 }); 1091 if (createIncomplete) f.completeExceptionally(ex); 1092 1093 checkCompletedWithWrappedException(g, ex); 1094 checkCompletedExceptionally(f, ex); 1095 mustEqual(1, ran.get()); 1096 }} 1097 1098 /** 1099 * whenComplete action executes on cancelled source, propagating 1100 * CancellationException. 1101 */ 1102 @Test testWhenComplete_sourceCancelled()1103 public void testWhenComplete_sourceCancelled() { 1104 for (ExecutionMode m : ExecutionMode.values()) 1105 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1106 for (boolean createIncomplete : new boolean[] { true, false }) 1107 { 1108 final AtomicInteger ran = new AtomicInteger(0); 1109 final CompletableFuture<Item> f = new CompletableFuture<>(); 1110 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 1111 final CompletableFuture<Item> g = m.whenComplete 1112 (f, 1113 (Item result, Throwable t) -> { 1114 m.checkExecutionMode(); 1115 assertNull(result); 1116 assertTrue(t instanceof CancellationException); 1117 ran.getAndIncrement(); 1118 }); 1119 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 1120 1121 checkCompletedWithWrappedCancellationException(g); 1122 checkCancelled(f); 1123 mustEqual(1, ran.get()); 1124 }} 1125 1126 /** 1127 * If a whenComplete action throws an exception when triggered by 1128 * a normal completion, it completes exceptionally 1129 */ 1130 @Test testWhenComplete_sourceCompletedNormallyActionFailed()1131 public void testWhenComplete_sourceCompletedNormallyActionFailed() { 1132 for (boolean createIncomplete : new boolean[] { true, false }) 1133 for (ExecutionMode m : ExecutionMode.values()) 1134 for (Item v1 : new Item[] { itemOne, null }) 1135 { 1136 final AtomicInteger ran = new AtomicInteger(0); 1137 final CFException ex = new CFException(); 1138 final CompletableFuture<Item> f = new CompletableFuture<>(); 1139 if (!createIncomplete) assertTrue(f.complete(v1)); 1140 final CompletableFuture<Item> g = m.whenComplete 1141 (f, 1142 (Item result, Throwable t) -> { 1143 m.checkExecutionMode(); 1144 assertSame(result, v1); 1145 assertNull(t); 1146 ran.getAndIncrement(); 1147 throw ex; 1148 }); 1149 if (createIncomplete) assertTrue(f.complete(v1)); 1150 1151 checkCompletedWithWrappedException(g, ex); 1152 checkCompletedNormally(f, v1); 1153 mustEqual(1, ran.get()); 1154 }} 1155 1156 /** 1157 * If a whenComplete action throws an exception when triggered by 1158 * a source completion that also throws an exception, the source 1159 * exception takes precedence (unlike handle) 1160 */ 1161 @Test testWhenComplete_sourceFailedActionFailed()1162 public void testWhenComplete_sourceFailedActionFailed() { 1163 for (boolean createIncomplete : new boolean[] { true, false }) 1164 for (ExecutionMode m : ExecutionMode.values()) 1165 { 1166 final AtomicInteger ran = new AtomicInteger(0); 1167 final CFException ex1 = new CFException(); 1168 final CFException ex2 = new CFException(); 1169 final CompletableFuture<Item> f = new CompletableFuture<>(); 1170 1171 if (!createIncomplete) f.completeExceptionally(ex1); 1172 final CompletableFuture<Item> g = m.whenComplete 1173 (f, 1174 (Item result, Throwable t) -> { 1175 m.checkExecutionMode(); 1176 assertSame(t, ex1); 1177 assertNull(result); 1178 ran.getAndIncrement(); 1179 throw ex2; 1180 }); 1181 if (createIncomplete) f.completeExceptionally(ex1); 1182 1183 checkCompletedWithWrappedException(g, ex1); 1184 checkCompletedExceptionally(f, ex1); 1185 if (testImplementationDetails) { 1186 mustEqual(1, ex1.getSuppressed().length); 1187 assertSame(ex2, ex1.getSuppressed()[0]); 1188 } 1189 mustEqual(1, ran.get()); 1190 }} 1191 1192 /** 1193 * handle action completes normally with function value on normal 1194 * completion of source 1195 */ 1196 @Test testHandle_normalCompletion()1197 public void testHandle_normalCompletion() { 1198 for (ExecutionMode m : ExecutionMode.values()) 1199 for (boolean createIncomplete : new boolean[] { true, false }) 1200 for (Item v1 : new Item[] { itemOne, null }) 1201 { 1202 final CompletableFuture<Item> f = new CompletableFuture<>(); 1203 final AtomicInteger ran = new AtomicInteger(0); 1204 if (!createIncomplete) assertTrue(f.complete(v1)); 1205 final CompletableFuture<Item> g = m.handle 1206 (f, 1207 (Item result, Throwable t) -> { 1208 m.checkExecutionMode(); 1209 assertSame(result, v1); 1210 assertNull(t); 1211 ran.getAndIncrement(); 1212 return inc(v1); 1213 }); 1214 if (createIncomplete) assertTrue(f.complete(v1)); 1215 1216 checkCompletedNormally(g, inc(v1)); 1217 checkCompletedNormally(f, v1); 1218 mustEqual(1, ran.get()); 1219 }} 1220 1221 /** 1222 * handle action completes normally with function value on 1223 * exceptional completion of source 1224 */ 1225 @Test testHandle_exceptionalCompletion()1226 public void testHandle_exceptionalCompletion() { 1227 for (ExecutionMode m : ExecutionMode.values()) 1228 for (boolean createIncomplete : new boolean[] { true, false }) 1229 for (Item v1 : new Item[] { itemOne, null }) 1230 { 1231 final CompletableFuture<Item> f = new CompletableFuture<>(); 1232 final AtomicInteger ran = new AtomicInteger(0); 1233 final CFException ex = new CFException(); 1234 if (!createIncomplete) f.completeExceptionally(ex); 1235 final CompletableFuture<Item> g = m.handle 1236 (f, 1237 (Item result, Throwable t) -> { 1238 m.checkExecutionMode(); 1239 assertNull(result); 1240 assertSame(t, ex); 1241 ran.getAndIncrement(); 1242 return v1; 1243 }); 1244 if (createIncomplete) f.completeExceptionally(ex); 1245 1246 checkCompletedNormally(g, v1); 1247 checkCompletedExceptionally(f, ex); 1248 mustEqual(1, ran.get()); 1249 }} 1250 1251 /** 1252 * handle action completes normally with function value on 1253 * cancelled source 1254 */ 1255 @Test testHandle_sourceCancelled()1256 public void testHandle_sourceCancelled() { 1257 for (ExecutionMode m : ExecutionMode.values()) 1258 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1259 for (boolean createIncomplete : new boolean[] { true, false }) 1260 for (Item v1 : new Item[] { itemOne, null }) 1261 { 1262 final CompletableFuture<Item> f = new CompletableFuture<>(); 1263 final AtomicInteger ran = new AtomicInteger(0); 1264 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 1265 final CompletableFuture<Item> g = m.handle 1266 (f, 1267 (Item result, Throwable t) -> { 1268 m.checkExecutionMode(); 1269 assertNull(result); 1270 assertTrue(t instanceof CancellationException); 1271 ran.getAndIncrement(); 1272 return v1; 1273 }); 1274 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 1275 1276 checkCompletedNormally(g, v1); 1277 checkCancelled(f); 1278 mustEqual(1, ran.get()); 1279 }} 1280 1281 /** 1282 * If a "handle action" throws an exception when triggered by 1283 * a normal completion, it completes exceptionally 1284 */ 1285 @Test testHandle_sourceCompletedNormallyActionFailed()1286 public void testHandle_sourceCompletedNormallyActionFailed() { 1287 for (ExecutionMode m : ExecutionMode.values()) 1288 for (boolean createIncomplete : new boolean[] { true, false }) 1289 for (Item v1 : new Item[] { itemOne, null }) 1290 { 1291 final CompletableFuture<Item> f = new CompletableFuture<>(); 1292 final AtomicInteger ran = new AtomicInteger(0); 1293 final CFException ex = new CFException(); 1294 if (!createIncomplete) assertTrue(f.complete(v1)); 1295 final CompletableFuture<Item> g = m.handle 1296 (f, 1297 (Item result, Throwable t) -> { 1298 m.checkExecutionMode(); 1299 assertSame(result, v1); 1300 assertNull(t); 1301 ran.getAndIncrement(); 1302 throw ex; 1303 }); 1304 if (createIncomplete) assertTrue(f.complete(v1)); 1305 1306 checkCompletedWithWrappedException(g, ex); 1307 checkCompletedNormally(f, v1); 1308 mustEqual(1, ran.get()); 1309 }} 1310 1311 /** 1312 * If a "handle action" throws an exception when triggered by 1313 * a source completion that also throws an exception, the action 1314 * exception takes precedence (unlike whenComplete) 1315 */ 1316 @Test testHandle_sourceFailedActionFailed()1317 public void testHandle_sourceFailedActionFailed() { 1318 for (boolean createIncomplete : new boolean[] { true, false }) 1319 for (ExecutionMode m : ExecutionMode.values()) 1320 { 1321 final AtomicInteger ran = new AtomicInteger(0); 1322 final CFException ex1 = new CFException(); 1323 final CFException ex2 = new CFException(); 1324 final CompletableFuture<Item> f = new CompletableFuture<>(); 1325 1326 if (!createIncomplete) f.completeExceptionally(ex1); 1327 final CompletableFuture<Item> g = m.handle 1328 (f, 1329 (Item result, Throwable t) -> { 1330 m.checkExecutionMode(); 1331 assertNull(result); 1332 assertSame(ex1, t); 1333 ran.getAndIncrement(); 1334 throw ex2; 1335 }); 1336 if (createIncomplete) f.completeExceptionally(ex1); 1337 1338 checkCompletedWithWrappedException(g, ex2); 1339 checkCompletedExceptionally(f, ex1); 1340 mustEqual(1, ran.get()); 1341 }} 1342 1343 /** 1344 * runAsync completes after running Runnable 1345 */ 1346 @Test testRunAsync_normalCompletion()1347 public void testRunAsync_normalCompletion() { 1348 ExecutionMode[] executionModes = { 1349 ExecutionMode.ASYNC, 1350 ExecutionMode.EXECUTOR, 1351 }; 1352 for (ExecutionMode m : executionModes) 1353 { 1354 final Noop r = new Noop(m); 1355 final CompletableFuture<Void> f = m.runAsync(r); 1356 assertNull(f.join()); 1357 checkCompletedNormally(f, null); 1358 r.assertInvoked(); 1359 }} 1360 1361 /** 1362 * failing runAsync completes exceptionally after running Runnable 1363 */ 1364 @Test testRunAsync_exceptionalCompletion()1365 public void testRunAsync_exceptionalCompletion() { 1366 ExecutionMode[] executionModes = { 1367 ExecutionMode.ASYNC, 1368 ExecutionMode.EXECUTOR, 1369 }; 1370 for (ExecutionMode m : executionModes) 1371 { 1372 final FailingRunnable r = new FailingRunnable(m); 1373 final CompletableFuture<Void> f = m.runAsync(r); 1374 checkCompletedWithWrappedException(f, r.ex); 1375 r.assertInvoked(); 1376 }} 1377 1378 @SuppressWarnings("FutureReturnValueIgnored") 1379 @Test testRunAsync_rejectingExecutor()1380 public void testRunAsync_rejectingExecutor() { 1381 CountingRejectingExecutor e = new CountingRejectingExecutor(); 1382 try { 1383 CompletableFuture.runAsync(() -> {}, e); 1384 shouldThrow(); 1385 } catch (Throwable t) { 1386 assertSame(e.ex, t); 1387 } 1388 1389 mustEqual(1, e.count.get()); 1390 } 1391 1392 /** 1393 * supplyAsync completes with result of supplier 1394 */ 1395 @Test testSupplyAsync_normalCompletion()1396 public void testSupplyAsync_normalCompletion() { 1397 ExecutionMode[] executionModes = { 1398 ExecutionMode.ASYNC, 1399 ExecutionMode.EXECUTOR, 1400 }; 1401 for (ExecutionMode m : executionModes) 1402 for (Item v1 : new Item[] { itemOne, null }) 1403 { 1404 final ItemSupplier r = new ItemSupplier(m, v1); 1405 final CompletableFuture<Item> f = m.supplyAsync(r); 1406 assertSame(v1, f.join()); 1407 checkCompletedNormally(f, v1); 1408 r.assertInvoked(); 1409 }} 1410 1411 /** 1412 * Failing supplyAsync completes exceptionally 1413 */ 1414 @Test testSupplyAsync_exceptionalCompletion()1415 public void testSupplyAsync_exceptionalCompletion() { 1416 ExecutionMode[] executionModes = { 1417 ExecutionMode.ASYNC, 1418 ExecutionMode.EXECUTOR, 1419 }; 1420 for (ExecutionMode m : executionModes) 1421 { 1422 FailingSupplier r = new FailingSupplier(m); 1423 CompletableFuture<Item> f = m.supplyAsync(r); 1424 checkCompletedWithWrappedException(f, r.ex); 1425 r.assertInvoked(); 1426 }} 1427 1428 @SuppressWarnings("FutureReturnValueIgnored") 1429 @Test testSupplyAsync_rejectingExecutor()1430 public void testSupplyAsync_rejectingExecutor() { 1431 CountingRejectingExecutor e = new CountingRejectingExecutor(); 1432 try { 1433 CompletableFuture.supplyAsync(() -> null, e); 1434 shouldThrow(); 1435 } catch (Throwable t) { 1436 assertSame(e.ex, t); 1437 } 1438 1439 mustEqual(1, e.count.get()); 1440 } 1441 1442 // seq completion methods 1443 1444 /** 1445 * thenRun result completes normally after normal completion of source 1446 */ 1447 @Test testThenRun_normalCompletion()1448 public void testThenRun_normalCompletion() { 1449 for (ExecutionMode m : ExecutionMode.values()) 1450 for (Item v1 : new Item[] { itemOne, null }) 1451 { 1452 final CompletableFuture<Item> f = new CompletableFuture<>(); 1453 final Noop[] rs = new Noop[6]; 1454 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 1455 1456 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]); 1457 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]); 1458 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]); 1459 checkIncomplete(h0); 1460 checkIncomplete(h1); 1461 checkIncomplete(h2); 1462 assertTrue(f.complete(v1)); 1463 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]); 1464 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]); 1465 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]); 1466 1467 checkCompletedNormally(h0, null); 1468 checkCompletedNormally(h1, null); 1469 checkCompletedNormally(h2, null); 1470 checkCompletedNormally(h3, null); 1471 checkCompletedNormally(h4, null); 1472 checkCompletedNormally(h5, null); 1473 checkCompletedNormally(f, v1); 1474 for (Noop r : rs) r.assertInvoked(); 1475 }} 1476 1477 /** 1478 * thenRun result completes exceptionally after exceptional 1479 * completion of source 1480 */ 1481 @Test testThenRun_exceptionalCompletion()1482 public void testThenRun_exceptionalCompletion() { 1483 for (ExecutionMode m : ExecutionMode.values()) 1484 { 1485 final CFException ex = new CFException(); 1486 final CompletableFuture<Item> f = new CompletableFuture<>(); 1487 final Noop[] rs = new Noop[6]; 1488 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 1489 1490 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]); 1491 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]); 1492 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]); 1493 checkIncomplete(h0); 1494 checkIncomplete(h1); 1495 checkIncomplete(h2); 1496 assertTrue(f.completeExceptionally(ex)); 1497 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]); 1498 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]); 1499 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]); 1500 1501 checkCompletedWithWrappedException(h0, ex); 1502 checkCompletedWithWrappedException(h1, ex); 1503 checkCompletedWithWrappedException(h2, ex); 1504 checkCompletedWithWrappedException(h3, ex); 1505 checkCompletedWithWrappedException(h4, ex); 1506 checkCompletedWithWrappedException(h5, ex); 1507 checkCompletedExceptionally(f, ex); 1508 for (Noop r : rs) r.assertNotInvoked(); 1509 }} 1510 1511 /** 1512 * thenRun result completes exceptionally if source cancelled 1513 */ 1514 @Test testThenRun_sourceCancelled()1515 public void testThenRun_sourceCancelled() { 1516 for (ExecutionMode m : ExecutionMode.values()) 1517 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1518 { 1519 final CompletableFuture<Item> f = new CompletableFuture<>(); 1520 final Noop[] rs = new Noop[6]; 1521 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 1522 1523 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]); 1524 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]); 1525 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]); 1526 checkIncomplete(h0); 1527 checkIncomplete(h1); 1528 checkIncomplete(h2); 1529 assertTrue(f.cancel(mayInterruptIfRunning)); 1530 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]); 1531 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]); 1532 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]); 1533 1534 checkCompletedWithWrappedCancellationException(h0); 1535 checkCompletedWithWrappedCancellationException(h1); 1536 checkCompletedWithWrappedCancellationException(h2); 1537 checkCompletedWithWrappedCancellationException(h3); 1538 checkCompletedWithWrappedCancellationException(h4); 1539 checkCompletedWithWrappedCancellationException(h5); 1540 checkCancelled(f); 1541 for (Noop r : rs) r.assertNotInvoked(); 1542 }} 1543 1544 /** 1545 * thenRun result completes exceptionally if action does 1546 */ 1547 @Test testThenRun_actionFailed()1548 public void testThenRun_actionFailed() { 1549 for (ExecutionMode m : ExecutionMode.values()) 1550 for (Item v1 : new Item[] { itemOne, null }) 1551 { 1552 final CompletableFuture<Item> f = new CompletableFuture<>(); 1553 final FailingRunnable[] rs = new FailingRunnable[6]; 1554 for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m); 1555 1556 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]); 1557 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]); 1558 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]); 1559 assertTrue(f.complete(v1)); 1560 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]); 1561 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]); 1562 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]); 1563 1564 checkCompletedWithWrappedException(h0, rs[0].ex); 1565 checkCompletedWithWrappedException(h1, rs[1].ex); 1566 checkCompletedWithWrappedException(h2, rs[2].ex); 1567 checkCompletedWithWrappedException(h3, rs[3].ex); 1568 checkCompletedWithWrappedException(h4, rs[4].ex); 1569 checkCompletedWithWrappedException(h5, rs[5].ex); 1570 checkCompletedNormally(f, v1); 1571 }} 1572 1573 /** 1574 * thenApply result completes normally after normal completion of source 1575 */ 1576 @Test testThenApply_normalCompletion()1577 public void testThenApply_normalCompletion() { 1578 for (ExecutionMode m : ExecutionMode.values()) 1579 for (Item v1 : new Item[] { itemOne, null }) 1580 { 1581 final CompletableFuture<Item> f = new CompletableFuture<>(); 1582 final IncFunction[] rs = new IncFunction[4]; 1583 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 1584 1585 final CompletableFuture<Item> h0 = m.thenApply(f, rs[0]); 1586 final CompletableFuture<Item> h1 = m.applyToEither(f, f, rs[1]); 1587 checkIncomplete(h0); 1588 checkIncomplete(h1); 1589 assertTrue(f.complete(v1)); 1590 final CompletableFuture<Item> h2 = m.thenApply(f, rs[2]); 1591 final CompletableFuture<Item> h3 = m.applyToEither(f, f, rs[3]); 1592 1593 checkCompletedNormally(h0, inc(v1)); 1594 checkCompletedNormally(h1, inc(v1)); 1595 checkCompletedNormally(h2, inc(v1)); 1596 checkCompletedNormally(h3, inc(v1)); 1597 checkCompletedNormally(f, v1); 1598 for (IncFunction r : rs) r.assertValue(inc(v1)); 1599 }} 1600 1601 /** 1602 * thenApply result completes exceptionally after exceptional 1603 * completion of source 1604 */ 1605 @Test testThenApply_exceptionalCompletion()1606 public void testThenApply_exceptionalCompletion() { 1607 for (ExecutionMode m : ExecutionMode.values()) 1608 { 1609 final CFException ex = new CFException(); 1610 final CompletableFuture<Item> f = new CompletableFuture<>(); 1611 final IncFunction[] rs = new IncFunction[4]; 1612 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 1613 1614 final CompletableFuture<Item> h0 = m.thenApply(f, rs[0]); 1615 final CompletableFuture<Item> h1 = m.applyToEither(f, f, rs[1]); 1616 assertTrue(f.completeExceptionally(ex)); 1617 final CompletableFuture<Item> h2 = m.thenApply(f, rs[2]); 1618 final CompletableFuture<Item> h3 = m.applyToEither(f, f, rs[3]); 1619 1620 checkCompletedWithWrappedException(h0, ex); 1621 checkCompletedWithWrappedException(h1, ex); 1622 checkCompletedWithWrappedException(h2, ex); 1623 checkCompletedWithWrappedException(h3, ex); 1624 checkCompletedExceptionally(f, ex); 1625 for (IncFunction r : rs) r.assertNotInvoked(); 1626 }} 1627 1628 /** 1629 * thenApply result completes exceptionally if source cancelled 1630 */ 1631 @Test testThenApply_sourceCancelled()1632 public void testThenApply_sourceCancelled() { 1633 for (ExecutionMode m : ExecutionMode.values()) 1634 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1635 { 1636 final CompletableFuture<Item> f = new CompletableFuture<>(); 1637 final IncFunction[] rs = new IncFunction[4]; 1638 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 1639 1640 final CompletableFuture<Item> h0 = m.thenApply(f, rs[0]); 1641 final CompletableFuture<Item> h1 = m.applyToEither(f, f, rs[1]); 1642 assertTrue(f.cancel(mayInterruptIfRunning)); 1643 final CompletableFuture<Item> h2 = m.thenApply(f, rs[2]); 1644 final CompletableFuture<Item> h3 = m.applyToEither(f, f, rs[3]); 1645 1646 checkCompletedWithWrappedCancellationException(h0); 1647 checkCompletedWithWrappedCancellationException(h1); 1648 checkCompletedWithWrappedCancellationException(h2); 1649 checkCompletedWithWrappedCancellationException(h3); 1650 checkCancelled(f); 1651 for (IncFunction r : rs) r.assertNotInvoked(); 1652 }} 1653 1654 /** 1655 * thenApply result completes exceptionally if action does 1656 */ 1657 @Test testThenApply_actionFailed()1658 public void testThenApply_actionFailed() { 1659 for (ExecutionMode m : ExecutionMode.values()) 1660 for (Item v1 : new Item[] { itemOne, null }) 1661 { 1662 final CompletableFuture<Item> f = new CompletableFuture<>(); 1663 final FailingFunction[] rs = new FailingFunction[4]; 1664 for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m); 1665 1666 final CompletableFuture<Item> h0 = m.thenApply(f, rs[0]); 1667 final CompletableFuture<Item> h1 = m.applyToEither(f, f, rs[1]); 1668 assertTrue(f.complete(v1)); 1669 final CompletableFuture<Item> h2 = m.thenApply(f, rs[2]); 1670 final CompletableFuture<Item> h3 = m.applyToEither(f, f, rs[3]); 1671 1672 checkCompletedWithWrappedException(h0, rs[0].ex); 1673 checkCompletedWithWrappedException(h1, rs[1].ex); 1674 checkCompletedWithWrappedException(h2, rs[2].ex); 1675 checkCompletedWithWrappedException(h3, rs[3].ex); 1676 checkCompletedNormally(f, v1); 1677 }} 1678 1679 /** 1680 * thenAccept result completes normally after normal completion of source 1681 */ 1682 @Test testThenAccept_normalCompletion()1683 public void testThenAccept_normalCompletion() { 1684 for (ExecutionMode m : ExecutionMode.values()) 1685 for (Item v1 : new Item[] { itemOne, null }) 1686 { 1687 final CompletableFuture<Item> f = new CompletableFuture<>(); 1688 final NoopConsumer[] rs = new NoopConsumer[4]; 1689 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 1690 1691 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]); 1692 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]); 1693 checkIncomplete(h0); 1694 checkIncomplete(h1); 1695 assertTrue(f.complete(v1)); 1696 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]); 1697 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]); 1698 1699 checkCompletedNormally(h0, null); 1700 checkCompletedNormally(h1, null); 1701 checkCompletedNormally(h2, null); 1702 checkCompletedNormally(h3, null); 1703 checkCompletedNormally(f, v1); 1704 for (NoopConsumer r : rs) r.assertValue(v1); 1705 }} 1706 1707 /** 1708 * thenAccept result completes exceptionally after exceptional 1709 * completion of source 1710 */ 1711 @Test testThenAccept_exceptionalCompletion()1712 public void testThenAccept_exceptionalCompletion() { 1713 for (ExecutionMode m : ExecutionMode.values()) 1714 { 1715 final CFException ex = new CFException(); 1716 final CompletableFuture<Item> f = new CompletableFuture<>(); 1717 final NoopConsumer[] rs = new NoopConsumer[4]; 1718 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 1719 1720 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]); 1721 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]); 1722 assertTrue(f.completeExceptionally(ex)); 1723 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]); 1724 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]); 1725 1726 checkCompletedWithWrappedException(h0, ex); 1727 checkCompletedWithWrappedException(h1, ex); 1728 checkCompletedWithWrappedException(h2, ex); 1729 checkCompletedWithWrappedException(h3, ex); 1730 checkCompletedExceptionally(f, ex); 1731 for (NoopConsumer r : rs) r.assertNotInvoked(); 1732 }} 1733 1734 /** 1735 * thenAccept result completes exceptionally if source cancelled 1736 */ 1737 @Test testThenAccept_sourceCancelled()1738 public void testThenAccept_sourceCancelled() { 1739 for (ExecutionMode m : ExecutionMode.values()) 1740 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1741 { 1742 final CompletableFuture<Item> f = new CompletableFuture<>(); 1743 final NoopConsumer[] rs = new NoopConsumer[4]; 1744 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 1745 1746 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]); 1747 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]); 1748 assertTrue(f.cancel(mayInterruptIfRunning)); 1749 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]); 1750 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]); 1751 1752 checkCompletedWithWrappedCancellationException(h0); 1753 checkCompletedWithWrappedCancellationException(h1); 1754 checkCompletedWithWrappedCancellationException(h2); 1755 checkCompletedWithWrappedCancellationException(h3); 1756 checkCancelled(f); 1757 for (NoopConsumer r : rs) r.assertNotInvoked(); 1758 }} 1759 1760 /** 1761 * thenAccept result completes exceptionally if action does 1762 */ 1763 @Test testThenAccept_actionFailed()1764 public void testThenAccept_actionFailed() { 1765 for (ExecutionMode m : ExecutionMode.values()) 1766 for (Item v1 : new Item[] { itemOne, null }) 1767 { 1768 final CompletableFuture<Item> f = new CompletableFuture<>(); 1769 final FailingConsumer[] rs = new FailingConsumer[4]; 1770 for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m); 1771 1772 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]); 1773 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]); 1774 assertTrue(f.complete(v1)); 1775 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]); 1776 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]); 1777 1778 checkCompletedWithWrappedException(h0, rs[0].ex); 1779 checkCompletedWithWrappedException(h1, rs[1].ex); 1780 checkCompletedWithWrappedException(h2, rs[2].ex); 1781 checkCompletedWithWrappedException(h3, rs[3].ex); 1782 checkCompletedNormally(f, v1); 1783 }} 1784 1785 /** 1786 * thenCombine result completes normally after normal completion 1787 * of sources 1788 */ 1789 @Test testThenCombine_normalCompletion()1790 public void testThenCombine_normalCompletion() { 1791 for (ExecutionMode m : ExecutionMode.values()) 1792 for (boolean fFirst : new boolean[] { true, false }) 1793 for (Item v1 : new Item[] { itemOne, null }) 1794 for (Item v2 : new Item[] { itemTwo, null }) 1795 { 1796 final CompletableFuture<Item> f = new CompletableFuture<>(); 1797 final CompletableFuture<Item> g = new CompletableFuture<>(); 1798 final SubtractFunction[] rs = new SubtractFunction[6]; 1799 for (int i = 0; i < rs.length; i++) rs[i] = new SubtractFunction(m); 1800 1801 final CompletableFuture<Item> fst = fFirst ? f : g; 1802 final CompletableFuture<Item> snd = !fFirst ? f : g; 1803 final Item w1 = fFirst ? v1 : v2; 1804 final Item w2 = !fFirst ? v1 : v2; 1805 1806 final CompletableFuture<Item> h0 = m.thenCombine(f, g, rs[0]); 1807 final CompletableFuture<Item> h1 = m.thenCombine(fst, fst, rs[1]); 1808 assertTrue(fst.complete(w1)); 1809 final CompletableFuture<Item> h2 = m.thenCombine(f, g, rs[2]); 1810 final CompletableFuture<Item> h3 = m.thenCombine(fst, fst, rs[3]); 1811 checkIncomplete(h0); rs[0].assertNotInvoked(); 1812 checkIncomplete(h2); rs[2].assertNotInvoked(); 1813 checkCompletedNormally(h1, subtract(w1, w1)); 1814 checkCompletedNormally(h3, subtract(w1, w1)); 1815 rs[1].assertValue(subtract(w1, w1)); 1816 rs[3].assertValue(subtract(w1, w1)); 1817 assertTrue(snd.complete(w2)); 1818 final CompletableFuture<Item> h4 = m.thenCombine(f, g, rs[4]); 1819 1820 checkCompletedNormally(h0, subtract(v1, v2)); 1821 checkCompletedNormally(h2, subtract(v1, v2)); 1822 checkCompletedNormally(h4, subtract(v1, v2)); 1823 rs[0].assertValue(subtract(v1, v2)); 1824 rs[2].assertValue(subtract(v1, v2)); 1825 rs[4].assertValue(subtract(v1, v2)); 1826 1827 checkCompletedNormally(f, v1); 1828 checkCompletedNormally(g, v2); 1829 }} 1830 1831 /** 1832 * thenCombine result completes exceptionally after exceptional 1833 * completion of either source 1834 */ 1835 @Test testThenCombine_exceptionalCompletion()1836 public void testThenCombine_exceptionalCompletion() throws Throwable { 1837 for (ExecutionMode m : ExecutionMode.values()) 1838 for (boolean fFirst : new boolean[] { true, false }) 1839 for (boolean failFirst : new boolean[] { true, false }) 1840 for (Item v1 : new Item[] { itemOne, null }) 1841 { 1842 final CompletableFuture<Item> f = new CompletableFuture<>(); 1843 final CompletableFuture<Item> g = new CompletableFuture<>(); 1844 final CFException ex = new CFException(); 1845 final SubtractFunction r1 = new SubtractFunction(m); 1846 final SubtractFunction r2 = new SubtractFunction(m); 1847 final SubtractFunction r3 = new SubtractFunction(m); 1848 1849 final CompletableFuture<Item> fst = fFirst ? f : g; 1850 final CompletableFuture<Item> snd = !fFirst ? f : g; 1851 final Callable<Boolean> complete1 = failFirst ? 1852 () -> fst.completeExceptionally(ex) : 1853 () -> fst.complete(v1); 1854 final Callable<Boolean> complete2 = failFirst ? 1855 () -> snd.complete(v1) : 1856 () -> snd.completeExceptionally(ex); 1857 1858 final CompletableFuture<Item> h1 = m.thenCombine(f, g, r1); 1859 assertTrue(complete1.call()); 1860 final CompletableFuture<Item> h2 = m.thenCombine(f, g, r2); 1861 checkIncomplete(h1); 1862 checkIncomplete(h2); 1863 assertTrue(complete2.call()); 1864 final CompletableFuture<Item> h3 = m.thenCombine(f, g, r3); 1865 1866 checkCompletedWithWrappedException(h1, ex); 1867 checkCompletedWithWrappedException(h2, ex); 1868 checkCompletedWithWrappedException(h3, ex); 1869 r1.assertNotInvoked(); 1870 r2.assertNotInvoked(); 1871 r3.assertNotInvoked(); 1872 checkCompletedNormally(failFirst ? snd : fst, v1); 1873 checkCompletedExceptionally(failFirst ? fst : snd, ex); 1874 }} 1875 1876 /** 1877 * thenCombine result completes exceptionally if either source cancelled 1878 */ 1879 @Test testThenCombine_sourceCancelled()1880 public void testThenCombine_sourceCancelled() throws Throwable { 1881 for (ExecutionMode m : ExecutionMode.values()) 1882 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1883 for (boolean fFirst : new boolean[] { true, false }) 1884 for (boolean failFirst : new boolean[] { true, false }) 1885 for (Item v1 : new Item[] { itemOne, null }) 1886 { 1887 final CompletableFuture<Item> f = new CompletableFuture<>(); 1888 final CompletableFuture<Item> g = new CompletableFuture<>(); 1889 final SubtractFunction r1 = new SubtractFunction(m); 1890 final SubtractFunction r2 = new SubtractFunction(m); 1891 final SubtractFunction r3 = new SubtractFunction(m); 1892 1893 final CompletableFuture<Item> fst = fFirst ? f : g; 1894 final CompletableFuture<Item> snd = !fFirst ? f : g; 1895 final Callable<Boolean> complete1 = failFirst ? 1896 () -> fst.cancel(mayInterruptIfRunning) : 1897 () -> fst.complete(v1); 1898 final Callable<Boolean> complete2 = failFirst ? 1899 () -> snd.complete(v1) : 1900 () -> snd.cancel(mayInterruptIfRunning); 1901 1902 final CompletableFuture<Item> h1 = m.thenCombine(f, g, r1); 1903 assertTrue(complete1.call()); 1904 final CompletableFuture<Item> h2 = m.thenCombine(f, g, r2); 1905 checkIncomplete(h1); 1906 checkIncomplete(h2); 1907 assertTrue(complete2.call()); 1908 final CompletableFuture<Item> h3 = m.thenCombine(f, g, r3); 1909 1910 checkCompletedWithWrappedCancellationException(h1); 1911 checkCompletedWithWrappedCancellationException(h2); 1912 checkCompletedWithWrappedCancellationException(h3); 1913 r1.assertNotInvoked(); 1914 r2.assertNotInvoked(); 1915 r3.assertNotInvoked(); 1916 checkCompletedNormally(failFirst ? snd : fst, v1); 1917 checkCancelled(failFirst ? fst : snd); 1918 }} 1919 1920 /** 1921 * thenCombine result completes exceptionally if action does 1922 */ 1923 @Test testThenCombine_actionFailed()1924 public void testThenCombine_actionFailed() { 1925 for (ExecutionMode m : ExecutionMode.values()) 1926 for (boolean fFirst : new boolean[] { true, false }) 1927 for (Item v1 : new Item[] { itemOne, null }) 1928 for (Item v2 : new Item[] { itemTwo, null }) 1929 { 1930 final CompletableFuture<Item> f = new CompletableFuture<>(); 1931 final CompletableFuture<Item> g = new CompletableFuture<>(); 1932 final FailingBiFunction r1 = new FailingBiFunction(m); 1933 final FailingBiFunction r2 = new FailingBiFunction(m); 1934 final FailingBiFunction r3 = new FailingBiFunction(m); 1935 1936 final CompletableFuture<Item> fst = fFirst ? f : g; 1937 final CompletableFuture<Item> snd = !fFirst ? f : g; 1938 final Item w1 = fFirst ? v1 : v2; 1939 final Item w2 = !fFirst ? v1 : v2; 1940 1941 final CompletableFuture<Item> h1 = m.thenCombine(f, g, r1); 1942 assertTrue(fst.complete(w1)); 1943 final CompletableFuture<Item> h2 = m.thenCombine(f, g, r2); 1944 assertTrue(snd.complete(w2)); 1945 final CompletableFuture<Item> h3 = m.thenCombine(f, g, r3); 1946 1947 checkCompletedWithWrappedException(h1, r1.ex); 1948 checkCompletedWithWrappedException(h2, r2.ex); 1949 checkCompletedWithWrappedException(h3, r3.ex); 1950 r1.assertInvoked(); 1951 r2.assertInvoked(); 1952 r3.assertInvoked(); 1953 checkCompletedNormally(f, v1); 1954 checkCompletedNormally(g, v2); 1955 }} 1956 1957 /** 1958 * thenAcceptBoth result completes normally after normal 1959 * completion of sources 1960 */ 1961 @Test testThenAcceptBoth_normalCompletion()1962 public void testThenAcceptBoth_normalCompletion() { 1963 for (ExecutionMode m : ExecutionMode.values()) 1964 for (boolean fFirst : new boolean[] { true, false }) 1965 for (Item v1 : new Item[] { itemOne, null }) 1966 for (Item v2 : new Item[] { itemTwo, null }) 1967 { 1968 final CompletableFuture<Item> f = new CompletableFuture<>(); 1969 final CompletableFuture<Item> g = new CompletableFuture<>(); 1970 final SubtractAction r1 = new SubtractAction(m); 1971 final SubtractAction r2 = new SubtractAction(m); 1972 final SubtractAction r3 = new SubtractAction(m); 1973 1974 final CompletableFuture<Item> fst = fFirst ? f : g; 1975 final CompletableFuture<Item> snd = !fFirst ? f : g; 1976 final Item w1 = fFirst ? v1 : v2; 1977 final Item w2 = !fFirst ? v1 : v2; 1978 1979 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1); 1980 assertTrue(fst.complete(w1)); 1981 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2); 1982 checkIncomplete(h1); 1983 checkIncomplete(h2); 1984 r1.assertNotInvoked(); 1985 r2.assertNotInvoked(); 1986 assertTrue(snd.complete(w2)); 1987 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3); 1988 1989 checkCompletedNormally(h1, null); 1990 checkCompletedNormally(h2, null); 1991 checkCompletedNormally(h3, null); 1992 r1.assertValue(subtract(v1, v2)); 1993 r2.assertValue(subtract(v1, v2)); 1994 r3.assertValue(subtract(v1, v2)); 1995 checkCompletedNormally(f, v1); 1996 checkCompletedNormally(g, v2); 1997 }} 1998 1999 /** 2000 * thenAcceptBoth result completes exceptionally after exceptional 2001 * completion of either source 2002 */ 2003 @Test testThenAcceptBoth_exceptionalCompletion()2004 public void testThenAcceptBoth_exceptionalCompletion() throws Throwable { 2005 for (ExecutionMode m : ExecutionMode.values()) 2006 for (boolean fFirst : new boolean[] { true, false }) 2007 for (boolean failFirst : new boolean[] { true, false }) 2008 for (Item v1 : new Item[] { itemOne, null }) 2009 { 2010 final CompletableFuture<Item> f = new CompletableFuture<>(); 2011 final CompletableFuture<Item> g = new CompletableFuture<>(); 2012 final CFException ex = new CFException(); 2013 final SubtractAction r1 = new SubtractAction(m); 2014 final SubtractAction r2 = new SubtractAction(m); 2015 final SubtractAction r3 = new SubtractAction(m); 2016 2017 final CompletableFuture<Item> fst = fFirst ? f : g; 2018 final CompletableFuture<Item> snd = !fFirst ? f : g; 2019 final Callable<Boolean> complete1 = failFirst ? 2020 () -> fst.completeExceptionally(ex) : 2021 () -> fst.complete(v1); 2022 final Callable<Boolean> complete2 = failFirst ? 2023 () -> snd.complete(v1) : 2024 () -> snd.completeExceptionally(ex); 2025 2026 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1); 2027 assertTrue(complete1.call()); 2028 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2); 2029 checkIncomplete(h1); 2030 checkIncomplete(h2); 2031 assertTrue(complete2.call()); 2032 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3); 2033 2034 checkCompletedWithWrappedException(h1, ex); 2035 checkCompletedWithWrappedException(h2, ex); 2036 checkCompletedWithWrappedException(h3, ex); 2037 r1.assertNotInvoked(); 2038 r2.assertNotInvoked(); 2039 r3.assertNotInvoked(); 2040 checkCompletedNormally(failFirst ? snd : fst, v1); 2041 checkCompletedExceptionally(failFirst ? fst : snd, ex); 2042 }} 2043 2044 /** 2045 * thenAcceptBoth result completes exceptionally if either source cancelled 2046 */ 2047 @Test testThenAcceptBoth_sourceCancelled()2048 public void testThenAcceptBoth_sourceCancelled() throws Throwable { 2049 for (ExecutionMode m : ExecutionMode.values()) 2050 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2051 for (boolean fFirst : new boolean[] { true, false }) 2052 for (boolean failFirst : new boolean[] { true, false }) 2053 for (Item v1 : new Item[] { itemOne, null }) 2054 { 2055 final CompletableFuture<Item> f = new CompletableFuture<>(); 2056 final CompletableFuture<Item> g = new CompletableFuture<>(); 2057 final SubtractAction r1 = new SubtractAction(m); 2058 final SubtractAction r2 = new SubtractAction(m); 2059 final SubtractAction r3 = new SubtractAction(m); 2060 2061 final CompletableFuture<Item> fst = fFirst ? f : g; 2062 final CompletableFuture<Item> snd = !fFirst ? f : g; 2063 final Callable<Boolean> complete1 = failFirst ? 2064 () -> fst.cancel(mayInterruptIfRunning) : 2065 () -> fst.complete(v1); 2066 final Callable<Boolean> complete2 = failFirst ? 2067 () -> snd.complete(v1) : 2068 () -> snd.cancel(mayInterruptIfRunning); 2069 2070 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1); 2071 assertTrue(complete1.call()); 2072 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2); 2073 checkIncomplete(h1); 2074 checkIncomplete(h2); 2075 assertTrue(complete2.call()); 2076 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3); 2077 2078 checkCompletedWithWrappedCancellationException(h1); 2079 checkCompletedWithWrappedCancellationException(h2); 2080 checkCompletedWithWrappedCancellationException(h3); 2081 r1.assertNotInvoked(); 2082 r2.assertNotInvoked(); 2083 r3.assertNotInvoked(); 2084 checkCompletedNormally(failFirst ? snd : fst, v1); 2085 checkCancelled(failFirst ? fst : snd); 2086 }} 2087 2088 /** 2089 * thenAcceptBoth result completes exceptionally if action does 2090 */ 2091 @Test testThenAcceptBoth_actionFailed()2092 public void testThenAcceptBoth_actionFailed() { 2093 for (ExecutionMode m : ExecutionMode.values()) 2094 for (boolean fFirst : new boolean[] { true, false }) 2095 for (Item v1 : new Item[] { itemOne, null }) 2096 for (Item v2 : new Item[] { itemTwo, null }) 2097 { 2098 final CompletableFuture<Item> f = new CompletableFuture<>(); 2099 final CompletableFuture<Item> g = new CompletableFuture<>(); 2100 final FailingBiConsumer r1 = new FailingBiConsumer(m); 2101 final FailingBiConsumer r2 = new FailingBiConsumer(m); 2102 final FailingBiConsumer r3 = new FailingBiConsumer(m); 2103 2104 final CompletableFuture<Item> fst = fFirst ? f : g; 2105 final CompletableFuture<Item> snd = !fFirst ? f : g; 2106 final Item w1 = fFirst ? v1 : v2; 2107 final Item w2 = !fFirst ? v1 : v2; 2108 2109 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1); 2110 assertTrue(fst.complete(w1)); 2111 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2); 2112 assertTrue(snd.complete(w2)); 2113 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3); 2114 2115 checkCompletedWithWrappedException(h1, r1.ex); 2116 checkCompletedWithWrappedException(h2, r2.ex); 2117 checkCompletedWithWrappedException(h3, r3.ex); 2118 r1.assertInvoked(); 2119 r2.assertInvoked(); 2120 r3.assertInvoked(); 2121 checkCompletedNormally(f, v1); 2122 checkCompletedNormally(g, v2); 2123 }} 2124 2125 /** 2126 * runAfterBoth result completes normally after normal 2127 * completion of sources 2128 */ 2129 @Test testRunAfterBoth_normalCompletion()2130 public void testRunAfterBoth_normalCompletion() { 2131 for (ExecutionMode m : ExecutionMode.values()) 2132 for (boolean fFirst : new boolean[] { true, false }) 2133 for (Item v1 : new Item[] { itemOne, null }) 2134 for (Item v2 : new Item[] { itemTwo, null }) 2135 { 2136 final CompletableFuture<Item> f = new CompletableFuture<>(); 2137 final CompletableFuture<Item> g = new CompletableFuture<>(); 2138 final Noop r1 = new Noop(m); 2139 final Noop r2 = new Noop(m); 2140 final Noop r3 = new Noop(m); 2141 2142 final CompletableFuture<Item> fst = fFirst ? f : g; 2143 final CompletableFuture<Item> snd = !fFirst ? f : g; 2144 final Item w1 = fFirst ? v1 : v2; 2145 final Item w2 = !fFirst ? v1 : v2; 2146 2147 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1); 2148 assertTrue(fst.complete(w1)); 2149 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2); 2150 checkIncomplete(h1); 2151 checkIncomplete(h2); 2152 r1.assertNotInvoked(); 2153 r2.assertNotInvoked(); 2154 assertTrue(snd.complete(w2)); 2155 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3); 2156 2157 checkCompletedNormally(h1, null); 2158 checkCompletedNormally(h2, null); 2159 checkCompletedNormally(h3, null); 2160 r1.assertInvoked(); 2161 r2.assertInvoked(); 2162 r3.assertInvoked(); 2163 checkCompletedNormally(f, v1); 2164 checkCompletedNormally(g, v2); 2165 }} 2166 2167 /** 2168 * runAfterBoth result completes exceptionally after exceptional 2169 * completion of either source 2170 */ 2171 @Test testRunAfterBoth_exceptionalCompletion()2172 public void testRunAfterBoth_exceptionalCompletion() throws Throwable { 2173 for (ExecutionMode m : ExecutionMode.values()) 2174 for (boolean fFirst : new boolean[] { true, false }) 2175 for (boolean failFirst : new boolean[] { true, false }) 2176 for (Item v1 : new Item[] { itemOne, null }) 2177 { 2178 final CompletableFuture<Item> f = new CompletableFuture<>(); 2179 final CompletableFuture<Item> g = new CompletableFuture<>(); 2180 final CFException ex = new CFException(); 2181 final Noop r1 = new Noop(m); 2182 final Noop r2 = new Noop(m); 2183 final Noop r3 = new Noop(m); 2184 2185 final CompletableFuture<Item> fst = fFirst ? f : g; 2186 final CompletableFuture<Item> snd = !fFirst ? f : g; 2187 final Callable<Boolean> complete1 = failFirst ? 2188 () -> fst.completeExceptionally(ex) : 2189 () -> fst.complete(v1); 2190 final Callable<Boolean> complete2 = failFirst ? 2191 () -> snd.complete(v1) : 2192 () -> snd.completeExceptionally(ex); 2193 2194 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1); 2195 assertTrue(complete1.call()); 2196 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2); 2197 checkIncomplete(h1); 2198 checkIncomplete(h2); 2199 assertTrue(complete2.call()); 2200 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3); 2201 2202 checkCompletedWithWrappedException(h1, ex); 2203 checkCompletedWithWrappedException(h2, ex); 2204 checkCompletedWithWrappedException(h3, ex); 2205 r1.assertNotInvoked(); 2206 r2.assertNotInvoked(); 2207 r3.assertNotInvoked(); 2208 checkCompletedNormally(failFirst ? snd : fst, v1); 2209 checkCompletedExceptionally(failFirst ? fst : snd, ex); 2210 }} 2211 2212 /** 2213 * runAfterBoth result completes exceptionally if either source cancelled 2214 */ 2215 @Test testRunAfterBoth_sourceCancelled()2216 public void testRunAfterBoth_sourceCancelled() throws Throwable { 2217 for (ExecutionMode m : ExecutionMode.values()) 2218 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2219 for (boolean fFirst : new boolean[] { true, false }) 2220 for (boolean failFirst : new boolean[] { true, false }) 2221 for (Item v1 : new Item[] { itemOne, null }) 2222 { 2223 final CompletableFuture<Item> f = new CompletableFuture<>(); 2224 final CompletableFuture<Item> g = new CompletableFuture<>(); 2225 final Noop r1 = new Noop(m); 2226 final Noop r2 = new Noop(m); 2227 final Noop r3 = new Noop(m); 2228 2229 final CompletableFuture<Item> fst = fFirst ? f : g; 2230 final CompletableFuture<Item> snd = !fFirst ? f : g; 2231 final Callable<Boolean> complete1 = failFirst ? 2232 () -> fst.cancel(mayInterruptIfRunning) : 2233 () -> fst.complete(v1); 2234 final Callable<Boolean> complete2 = failFirst ? 2235 () -> snd.complete(v1) : 2236 () -> snd.cancel(mayInterruptIfRunning); 2237 2238 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1); 2239 assertTrue(complete1.call()); 2240 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2); 2241 checkIncomplete(h1); 2242 checkIncomplete(h2); 2243 assertTrue(complete2.call()); 2244 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3); 2245 2246 checkCompletedWithWrappedCancellationException(h1); 2247 checkCompletedWithWrappedCancellationException(h2); 2248 checkCompletedWithWrappedCancellationException(h3); 2249 r1.assertNotInvoked(); 2250 r2.assertNotInvoked(); 2251 r3.assertNotInvoked(); 2252 checkCompletedNormally(failFirst ? snd : fst, v1); 2253 checkCancelled(failFirst ? fst : snd); 2254 }} 2255 2256 /** 2257 * runAfterBoth result completes exceptionally if action does 2258 */ 2259 @Test testRunAfterBoth_actionFailed()2260 public void testRunAfterBoth_actionFailed() { 2261 for (ExecutionMode m : ExecutionMode.values()) 2262 for (boolean fFirst : new boolean[] { true, false }) 2263 for (Item v1 : new Item[] { itemOne, null }) 2264 for (Item v2 : new Item[] { itemTwo, null }) 2265 { 2266 final CompletableFuture<Item> f = new CompletableFuture<>(); 2267 final CompletableFuture<Item> g = new CompletableFuture<>(); 2268 final FailingRunnable r1 = new FailingRunnable(m); 2269 final FailingRunnable r2 = new FailingRunnable(m); 2270 final FailingRunnable r3 = new FailingRunnable(m); 2271 2272 final CompletableFuture<Item> fst = fFirst ? f : g; 2273 final CompletableFuture<Item> snd = !fFirst ? f : g; 2274 final Item w1 = fFirst ? v1 : v2; 2275 final Item w2 = !fFirst ? v1 : v2; 2276 2277 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1); 2278 assertTrue(fst.complete(w1)); 2279 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2); 2280 assertTrue(snd.complete(w2)); 2281 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3); 2282 2283 checkCompletedWithWrappedException(h1, r1.ex); 2284 checkCompletedWithWrappedException(h2, r2.ex); 2285 checkCompletedWithWrappedException(h3, r3.ex); 2286 r1.assertInvoked(); 2287 r2.assertInvoked(); 2288 r3.assertInvoked(); 2289 checkCompletedNormally(f, v1); 2290 checkCompletedNormally(g, v2); 2291 }} 2292 2293 /** 2294 * applyToEither result completes normally after normal completion 2295 * of either source 2296 */ 2297 @Test testApplyToEither_normalCompletion()2298 public void testApplyToEither_normalCompletion() { 2299 for (ExecutionMode m : ExecutionMode.values()) 2300 for (Item v1 : new Item[] { itemOne, null }) 2301 for (Item v2 : new Item[] { itemTwo, null }) 2302 { 2303 final CompletableFuture<Item> f = new CompletableFuture<>(); 2304 final CompletableFuture<Item> g = new CompletableFuture<>(); 2305 final IncFunction[] rs = new IncFunction[6]; 2306 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2307 2308 final CompletableFuture<Item> h0 = m.applyToEither(f, g, rs[0]); 2309 final CompletableFuture<Item> h1 = m.applyToEither(g, f, rs[1]); 2310 checkIncomplete(h0); 2311 checkIncomplete(h1); 2312 rs[0].assertNotInvoked(); 2313 rs[1].assertNotInvoked(); 2314 f.complete(v1); 2315 checkCompletedNormally(h0, inc(v1)); 2316 checkCompletedNormally(h1, inc(v1)); 2317 final CompletableFuture<Item> h2 = m.applyToEither(f, g, rs[2]); 2318 final CompletableFuture<Item> h3 = m.applyToEither(g, f, rs[3]); 2319 checkCompletedNormally(h2, inc(v1)); 2320 checkCompletedNormally(h3, inc(v1)); 2321 g.complete(v2); 2322 2323 // unspecified behavior - both source completions available 2324 final CompletableFuture<Item> h4 = m.applyToEither(f, g, rs[4]); 2325 final CompletableFuture<Item> h5 = m.applyToEither(g, f, rs[5]); 2326 rs[4].assertValue(h4.join()); 2327 rs[5].assertValue(h5.join()); 2328 assertTrue(Objects.equals(inc(v1), h4.join()) || 2329 Objects.equals(inc(v2), h4.join())); 2330 assertTrue(Objects.equals(inc(v1), h5.join()) || 2331 Objects.equals(inc(v2), h5.join())); 2332 2333 checkCompletedNormally(f, v1); 2334 checkCompletedNormally(g, v2); 2335 checkCompletedNormally(h0, inc(v1)); 2336 checkCompletedNormally(h1, inc(v1)); 2337 checkCompletedNormally(h2, inc(v1)); 2338 checkCompletedNormally(h3, inc(v1)); 2339 for (int i = 0; i < 4; i++) rs[i].assertValue(inc(v1)); 2340 }} 2341 2342 /** 2343 * applyToEither result completes exceptionally after exceptional 2344 * completion of either source 2345 */ 2346 @Test testApplyToEither_exceptionalCompletion()2347 public void testApplyToEither_exceptionalCompletion() { 2348 for (ExecutionMode m : ExecutionMode.values()) 2349 for (Item v1 : new Item[] { itemOne, null }) 2350 { 2351 final CompletableFuture<Item> f = new CompletableFuture<>(); 2352 final CompletableFuture<Item> g = new CompletableFuture<>(); 2353 final CFException ex = new CFException(); 2354 final IncFunction[] rs = new IncFunction[6]; 2355 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2356 2357 final CompletableFuture<Item> h0 = m.applyToEither(f, g, rs[0]); 2358 final CompletableFuture<Item> h1 = m.applyToEither(g, f, rs[1]); 2359 checkIncomplete(h0); 2360 checkIncomplete(h1); 2361 rs[0].assertNotInvoked(); 2362 rs[1].assertNotInvoked(); 2363 f.completeExceptionally(ex); 2364 checkCompletedWithWrappedException(h0, ex); 2365 checkCompletedWithWrappedException(h1, ex); 2366 final CompletableFuture<Item> h2 = m.applyToEither(f, g, rs[2]); 2367 final CompletableFuture<Item> h3 = m.applyToEither(g, f, rs[3]); 2368 checkCompletedWithWrappedException(h2, ex); 2369 checkCompletedWithWrappedException(h3, ex); 2370 g.complete(v1); 2371 2372 // unspecified behavior - both source completions available 2373 final CompletableFuture<Item> h4 = m.applyToEither(f, g, rs[4]); 2374 final CompletableFuture<Item> h5 = m.applyToEither(g, f, rs[5]); 2375 try { 2376 mustEqual(inc(v1), h4.join()); 2377 rs[4].assertValue(inc(v1)); 2378 } catch (CompletionException ok) { 2379 checkCompletedWithWrappedException(h4, ex); 2380 rs[4].assertNotInvoked(); 2381 } 2382 try { 2383 mustEqual(inc(v1), h5.join()); 2384 rs[5].assertValue(inc(v1)); 2385 } catch (CompletionException ok) { 2386 checkCompletedWithWrappedException(h5, ex); 2387 rs[5].assertNotInvoked(); 2388 } 2389 2390 checkCompletedExceptionally(f, ex); 2391 checkCompletedNormally(g, v1); 2392 checkCompletedWithWrappedException(h0, ex); 2393 checkCompletedWithWrappedException(h1, ex); 2394 checkCompletedWithWrappedException(h2, ex); 2395 checkCompletedWithWrappedException(h3, ex); 2396 checkCompletedWithWrappedException(h4, ex); 2397 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2398 }} 2399 2400 @Test testApplyToEither_exceptionalCompletion2()2401 public void testApplyToEither_exceptionalCompletion2() { 2402 for (ExecutionMode m : ExecutionMode.values()) 2403 for (boolean fFirst : new boolean[] { true, false }) 2404 for (Item v1 : new Item[] { itemOne, null }) 2405 { 2406 final CompletableFuture<Item> f = new CompletableFuture<>(); 2407 final CompletableFuture<Item> g = new CompletableFuture<>(); 2408 final CFException ex = new CFException(); 2409 final IncFunction[] rs = new IncFunction[6]; 2410 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2411 2412 final CompletableFuture<Item> h0 = m.applyToEither(f, g, rs[0]); 2413 final CompletableFuture<Item> h1 = m.applyToEither(g, f, rs[1]); 2414 assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2415 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2416 final CompletableFuture<Item> h2 = m.applyToEither(f, g, rs[2]); 2417 final CompletableFuture<Item> h3 = m.applyToEither(g, f, rs[3]); 2418 2419 // unspecified behavior - both source completions available 2420 try { 2421 mustEqual(inc(v1), h0.join()); 2422 rs[0].assertValue(inc(v1)); 2423 } catch (CompletionException ok) { 2424 checkCompletedWithWrappedException(h0, ex); 2425 rs[0].assertNotInvoked(); 2426 } 2427 try { 2428 mustEqual(inc(v1), h1.join()); 2429 rs[1].assertValue(inc(v1)); 2430 } catch (CompletionException ok) { 2431 checkCompletedWithWrappedException(h1, ex); 2432 rs[1].assertNotInvoked(); 2433 } 2434 try { 2435 mustEqual(inc(v1), h2.join()); 2436 rs[2].assertValue(inc(v1)); 2437 } catch (CompletionException ok) { 2438 checkCompletedWithWrappedException(h2, ex); 2439 rs[2].assertNotInvoked(); 2440 } 2441 try { 2442 mustEqual(inc(v1), h3.join()); 2443 rs[3].assertValue(inc(v1)); 2444 } catch (CompletionException ok) { 2445 checkCompletedWithWrappedException(h3, ex); 2446 rs[3].assertNotInvoked(); 2447 } 2448 2449 checkCompletedNormally(f, v1); 2450 checkCompletedExceptionally(g, ex); 2451 }} 2452 2453 /** 2454 * applyToEither result completes exceptionally if either source cancelled 2455 */ 2456 @Test testApplyToEither_sourceCancelled()2457 public void testApplyToEither_sourceCancelled() { 2458 for (ExecutionMode m : ExecutionMode.values()) 2459 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2460 for (Item v1 : new Item[] { itemOne, null }) 2461 { 2462 final CompletableFuture<Item> f = new CompletableFuture<>(); 2463 final CompletableFuture<Item> g = new CompletableFuture<>(); 2464 final IncFunction[] rs = new IncFunction[6]; 2465 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2466 2467 final CompletableFuture<Item> h0 = m.applyToEither(f, g, rs[0]); 2468 final CompletableFuture<Item> h1 = m.applyToEither(g, f, rs[1]); 2469 checkIncomplete(h0); 2470 checkIncomplete(h1); 2471 rs[0].assertNotInvoked(); 2472 rs[1].assertNotInvoked(); 2473 f.cancel(mayInterruptIfRunning); 2474 checkCompletedWithWrappedCancellationException(h0); 2475 checkCompletedWithWrappedCancellationException(h1); 2476 final CompletableFuture<Item> h2 = m.applyToEither(f, g, rs[2]); 2477 final CompletableFuture<Item> h3 = m.applyToEither(g, f, rs[3]); 2478 checkCompletedWithWrappedCancellationException(h2); 2479 checkCompletedWithWrappedCancellationException(h3); 2480 g.complete(v1); 2481 2482 // unspecified behavior - both source completions available 2483 final CompletableFuture<Item> h4 = m.applyToEither(f, g, rs[4]); 2484 final CompletableFuture<Item> h5 = m.applyToEither(g, f, rs[5]); 2485 try { 2486 mustEqual(inc(v1), h4.join()); 2487 rs[4].assertValue(inc(v1)); 2488 } catch (CompletionException ok) { 2489 checkCompletedWithWrappedCancellationException(h4); 2490 rs[4].assertNotInvoked(); 2491 } 2492 try { 2493 mustEqual(inc(v1), h5.join()); 2494 rs[5].assertValue(inc(v1)); 2495 } catch (CompletionException ok) { 2496 checkCompletedWithWrappedCancellationException(h5); 2497 rs[5].assertNotInvoked(); 2498 } 2499 2500 checkCancelled(f); 2501 checkCompletedNormally(g, v1); 2502 checkCompletedWithWrappedCancellationException(h0); 2503 checkCompletedWithWrappedCancellationException(h1); 2504 checkCompletedWithWrappedCancellationException(h2); 2505 checkCompletedWithWrappedCancellationException(h3); 2506 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2507 }} 2508 2509 @Test testApplyToEither_sourceCancelled2()2510 public void testApplyToEither_sourceCancelled2() { 2511 for (ExecutionMode m : ExecutionMode.values()) 2512 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2513 for (boolean fFirst : new boolean[] { true, false }) 2514 for (Item v1 : new Item[] { itemOne, null }) 2515 { 2516 final CompletableFuture<Item> f = new CompletableFuture<>(); 2517 final CompletableFuture<Item> g = new CompletableFuture<>(); 2518 final IncFunction[] rs = new IncFunction[6]; 2519 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2520 2521 final CompletableFuture<Item> h0 = m.applyToEither(f, g, rs[0]); 2522 final CompletableFuture<Item> h1 = m.applyToEither(g, f, rs[1]); 2523 assertTrue(fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning)); 2524 assertTrue(!fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning)); 2525 final CompletableFuture<Item> h2 = m.applyToEither(f, g, rs[2]); 2526 final CompletableFuture<Item> h3 = m.applyToEither(g, f, rs[3]); 2527 2528 // unspecified behavior - both source completions available 2529 try { 2530 mustEqual(inc(v1), h0.join()); 2531 rs[0].assertValue(inc(v1)); 2532 } catch (CompletionException ok) { 2533 checkCompletedWithWrappedCancellationException(h0); 2534 rs[0].assertNotInvoked(); 2535 } 2536 try { 2537 mustEqual(inc(v1), h1.join()); 2538 rs[1].assertValue(inc(v1)); 2539 } catch (CompletionException ok) { 2540 checkCompletedWithWrappedCancellationException(h1); 2541 rs[1].assertNotInvoked(); 2542 } 2543 try { 2544 mustEqual(inc(v1), h2.join()); 2545 rs[2].assertValue(inc(v1)); 2546 } catch (CompletionException ok) { 2547 checkCompletedWithWrappedCancellationException(h2); 2548 rs[2].assertNotInvoked(); 2549 } 2550 try { 2551 mustEqual(inc(v1), h3.join()); 2552 rs[3].assertValue(inc(v1)); 2553 } catch (CompletionException ok) { 2554 checkCompletedWithWrappedCancellationException(h3); 2555 rs[3].assertNotInvoked(); 2556 } 2557 2558 checkCompletedNormally(f, v1); 2559 checkCancelled(g); 2560 }} 2561 2562 /** 2563 * applyToEither result completes exceptionally if action does 2564 */ 2565 @Test testApplyToEither_actionFailed()2566 public void testApplyToEither_actionFailed() { 2567 for (ExecutionMode m : ExecutionMode.values()) 2568 for (Item v1 : new Item[] { itemOne, null }) 2569 for (Item v2 : new Item[] { itemTwo, null }) 2570 { 2571 final CompletableFuture<Item> f = new CompletableFuture<>(); 2572 final CompletableFuture<Item> g = new CompletableFuture<>(); 2573 final FailingFunction[] rs = new FailingFunction[6]; 2574 for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m); 2575 2576 final CompletableFuture<Item> h0 = m.applyToEither(f, g, rs[0]); 2577 final CompletableFuture<Item> h1 = m.applyToEither(g, f, rs[1]); 2578 f.complete(v1); 2579 final CompletableFuture<Item> h2 = m.applyToEither(f, g, rs[2]); 2580 final CompletableFuture<Item> h3 = m.applyToEither(g, f, rs[3]); 2581 checkCompletedWithWrappedException(h0, rs[0].ex); 2582 checkCompletedWithWrappedException(h1, rs[1].ex); 2583 checkCompletedWithWrappedException(h2, rs[2].ex); 2584 checkCompletedWithWrappedException(h3, rs[3].ex); 2585 for (int i = 0; i < 4; i++) rs[i].assertValue(v1); 2586 2587 g.complete(v2); 2588 2589 // unspecified behavior - both source completions available 2590 final CompletableFuture<Item> h4 = m.applyToEither(f, g, rs[4]); 2591 final CompletableFuture<Item> h5 = m.applyToEither(g, f, rs[5]); 2592 2593 checkCompletedWithWrappedException(h4, rs[4].ex); 2594 assertTrue(Objects.equals(v1, rs[4].value) || 2595 Objects.equals(v2, rs[4].value)); 2596 checkCompletedWithWrappedException(h5, rs[5].ex); 2597 assertTrue(Objects.equals(v1, rs[5].value) || 2598 Objects.equals(v2, rs[5].value)); 2599 2600 checkCompletedNormally(f, v1); 2601 checkCompletedNormally(g, v2); 2602 }} 2603 2604 /** 2605 * acceptEither result completes normally after normal completion 2606 * of either source 2607 */ 2608 @Test testAcceptEither_normalCompletion()2609 public void testAcceptEither_normalCompletion() { 2610 for (ExecutionMode m : ExecutionMode.values()) 2611 for (Item v1 : new Item[] { itemOne, null }) 2612 for (Item v2 : new Item[] { itemTwo, null }) 2613 { 2614 final CompletableFuture<Item> f = new CompletableFuture<>(); 2615 final CompletableFuture<Item> g = new CompletableFuture<>(); 2616 final NoopConsumer[] rs = new NoopConsumer[6]; 2617 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 2618 2619 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2620 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2621 checkIncomplete(h0); 2622 checkIncomplete(h1); 2623 rs[0].assertNotInvoked(); 2624 rs[1].assertNotInvoked(); 2625 f.complete(v1); 2626 checkCompletedNormally(h0, null); 2627 checkCompletedNormally(h1, null); 2628 rs[0].assertValue(v1); 2629 rs[1].assertValue(v1); 2630 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2631 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2632 checkCompletedNormally(h2, null); 2633 checkCompletedNormally(h3, null); 2634 rs[2].assertValue(v1); 2635 rs[3].assertValue(v1); 2636 g.complete(v2); 2637 2638 // unspecified behavior - both source completions available 2639 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]); 2640 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]); 2641 checkCompletedNormally(h4, null); 2642 checkCompletedNormally(h5, null); 2643 assertTrue(Objects.equals(v1, rs[4].value) || 2644 Objects.equals(v2, rs[4].value)); 2645 assertTrue(Objects.equals(v1, rs[5].value) || 2646 Objects.equals(v2, rs[5].value)); 2647 2648 checkCompletedNormally(f, v1); 2649 checkCompletedNormally(g, v2); 2650 checkCompletedNormally(h0, null); 2651 checkCompletedNormally(h1, null); 2652 checkCompletedNormally(h2, null); 2653 checkCompletedNormally(h3, null); 2654 for (int i = 0; i < 4; i++) rs[i].assertValue(v1); 2655 }} 2656 2657 /** 2658 * acceptEither result completes exceptionally after exceptional 2659 * completion of either source 2660 */ 2661 @Test testAcceptEither_exceptionalCompletion()2662 public void testAcceptEither_exceptionalCompletion() { 2663 for (ExecutionMode m : ExecutionMode.values()) 2664 for (Item v1 : new Item[] { itemOne, null }) 2665 { 2666 final CompletableFuture<Item> f = new CompletableFuture<>(); 2667 final CompletableFuture<Item> g = new CompletableFuture<>(); 2668 final CFException ex = new CFException(); 2669 final NoopConsumer[] rs = new NoopConsumer[6]; 2670 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 2671 2672 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2673 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2674 checkIncomplete(h0); 2675 checkIncomplete(h1); 2676 rs[0].assertNotInvoked(); 2677 rs[1].assertNotInvoked(); 2678 f.completeExceptionally(ex); 2679 checkCompletedWithWrappedException(h0, ex); 2680 checkCompletedWithWrappedException(h1, ex); 2681 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2682 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2683 checkCompletedWithWrappedException(h2, ex); 2684 checkCompletedWithWrappedException(h3, ex); 2685 2686 g.complete(v1); 2687 2688 // unspecified behavior - both source completions available 2689 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]); 2690 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]); 2691 try { 2692 assertNull(h4.join()); 2693 rs[4].assertValue(v1); 2694 } catch (CompletionException ok) { 2695 checkCompletedWithWrappedException(h4, ex); 2696 rs[4].assertNotInvoked(); 2697 } 2698 try { 2699 assertNull(h5.join()); 2700 rs[5].assertValue(v1); 2701 } catch (CompletionException ok) { 2702 checkCompletedWithWrappedException(h5, ex); 2703 rs[5].assertNotInvoked(); 2704 } 2705 2706 checkCompletedExceptionally(f, ex); 2707 checkCompletedNormally(g, v1); 2708 checkCompletedWithWrappedException(h0, ex); 2709 checkCompletedWithWrappedException(h1, ex); 2710 checkCompletedWithWrappedException(h2, ex); 2711 checkCompletedWithWrappedException(h3, ex); 2712 checkCompletedWithWrappedException(h4, ex); 2713 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2714 }} 2715 2716 @Test testAcceptEither_exceptionalCompletion2()2717 public void testAcceptEither_exceptionalCompletion2() { 2718 for (ExecutionMode m : ExecutionMode.values()) 2719 for (boolean fFirst : new boolean[] { true, false }) 2720 for (Item v1 : new Item[] { itemOne, null }) 2721 { 2722 final CompletableFuture<Item> f = new CompletableFuture<>(); 2723 final CompletableFuture<Item> g = new CompletableFuture<>(); 2724 final CFException ex = new CFException(); 2725 final NoopConsumer[] rs = new NoopConsumer[6]; 2726 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 2727 2728 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2729 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2730 assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2731 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2732 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2733 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2734 2735 // unspecified behavior - both source completions available 2736 try { 2737 assertNull(h0.join()); 2738 rs[0].assertValue(v1); 2739 } catch (CompletionException ok) { 2740 checkCompletedWithWrappedException(h0, ex); 2741 rs[0].assertNotInvoked(); 2742 } 2743 try { 2744 assertNull(h1.join()); 2745 rs[1].assertValue(v1); 2746 } catch (CompletionException ok) { 2747 checkCompletedWithWrappedException(h1, ex); 2748 rs[1].assertNotInvoked(); 2749 } 2750 try { 2751 assertNull(h2.join()); 2752 rs[2].assertValue(v1); 2753 } catch (CompletionException ok) { 2754 checkCompletedWithWrappedException(h2, ex); 2755 rs[2].assertNotInvoked(); 2756 } 2757 try { 2758 assertNull(h3.join()); 2759 rs[3].assertValue(v1); 2760 } catch (CompletionException ok) { 2761 checkCompletedWithWrappedException(h3, ex); 2762 rs[3].assertNotInvoked(); 2763 } 2764 2765 checkCompletedNormally(f, v1); 2766 checkCompletedExceptionally(g, ex); 2767 }} 2768 2769 /** 2770 * acceptEither result completes exceptionally if either source cancelled 2771 */ 2772 @Test testAcceptEither_sourceCancelled()2773 public void testAcceptEither_sourceCancelled() { 2774 for (ExecutionMode m : ExecutionMode.values()) 2775 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2776 for (Item v1 : new Item[] { itemOne, null }) 2777 { 2778 final CompletableFuture<Item> f = new CompletableFuture<>(); 2779 final CompletableFuture<Item> g = new CompletableFuture<>(); 2780 final NoopConsumer[] rs = new NoopConsumer[6]; 2781 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 2782 2783 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2784 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2785 checkIncomplete(h0); 2786 checkIncomplete(h1); 2787 rs[0].assertNotInvoked(); 2788 rs[1].assertNotInvoked(); 2789 f.cancel(mayInterruptIfRunning); 2790 checkCompletedWithWrappedCancellationException(h0); 2791 checkCompletedWithWrappedCancellationException(h1); 2792 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2793 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2794 checkCompletedWithWrappedCancellationException(h2); 2795 checkCompletedWithWrappedCancellationException(h3); 2796 2797 g.complete(v1); 2798 2799 // unspecified behavior - both source completions available 2800 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]); 2801 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]); 2802 try { 2803 assertNull(h4.join()); 2804 rs[4].assertValue(v1); 2805 } catch (CompletionException ok) { 2806 checkCompletedWithWrappedCancellationException(h4); 2807 rs[4].assertNotInvoked(); 2808 } 2809 try { 2810 assertNull(h5.join()); 2811 rs[5].assertValue(v1); 2812 } catch (CompletionException ok) { 2813 checkCompletedWithWrappedCancellationException(h5); 2814 rs[5].assertNotInvoked(); 2815 } 2816 2817 checkCancelled(f); 2818 checkCompletedNormally(g, v1); 2819 checkCompletedWithWrappedCancellationException(h0); 2820 checkCompletedWithWrappedCancellationException(h1); 2821 checkCompletedWithWrappedCancellationException(h2); 2822 checkCompletedWithWrappedCancellationException(h3); 2823 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2824 }} 2825 2826 /** 2827 * acceptEither result completes exceptionally if action does 2828 */ 2829 @Test testAcceptEither_actionFailed()2830 public void testAcceptEither_actionFailed() { 2831 for (ExecutionMode m : ExecutionMode.values()) 2832 for (Item v1 : new Item[] { itemOne, null }) 2833 for (Item v2 : new Item[] { itemTwo, null }) 2834 { 2835 final CompletableFuture<Item> f = new CompletableFuture<>(); 2836 final CompletableFuture<Item> g = new CompletableFuture<>(); 2837 final FailingConsumer[] rs = new FailingConsumer[6]; 2838 for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m); 2839 2840 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2841 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2842 f.complete(v1); 2843 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2844 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2845 checkCompletedWithWrappedException(h0, rs[0].ex); 2846 checkCompletedWithWrappedException(h1, rs[1].ex); 2847 checkCompletedWithWrappedException(h2, rs[2].ex); 2848 checkCompletedWithWrappedException(h3, rs[3].ex); 2849 for (int i = 0; i < 4; i++) rs[i].assertValue(v1); 2850 2851 g.complete(v2); 2852 2853 // unspecified behavior - both source completions available 2854 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]); 2855 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]); 2856 2857 checkCompletedWithWrappedException(h4, rs[4].ex); 2858 assertTrue(Objects.equals(v1, rs[4].value) || 2859 Objects.equals(v2, rs[4].value)); 2860 checkCompletedWithWrappedException(h5, rs[5].ex); 2861 assertTrue(Objects.equals(v1, rs[5].value) || 2862 Objects.equals(v2, rs[5].value)); 2863 2864 checkCompletedNormally(f, v1); 2865 checkCompletedNormally(g, v2); 2866 }} 2867 2868 /** 2869 * runAfterEither result completes normally after normal completion 2870 * of either source 2871 */ 2872 @Test testRunAfterEither_normalCompletion()2873 public void testRunAfterEither_normalCompletion() { 2874 for (ExecutionMode m : ExecutionMode.values()) 2875 for (Item v1 : new Item[] { itemOne, null }) 2876 for (Item v2 : new Item[] { itemTwo, null }) 2877 for (boolean pushNop : new boolean[] { true, false }) 2878 { 2879 final CompletableFuture<Item> f = new CompletableFuture<>(); 2880 final CompletableFuture<Item> g = new CompletableFuture<>(); 2881 final Noop[] rs = new Noop[6]; 2882 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 2883 2884 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 2885 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 2886 checkIncomplete(h0); 2887 checkIncomplete(h1); 2888 rs[0].assertNotInvoked(); 2889 rs[1].assertNotInvoked(); 2890 if (pushNop) { // ad hoc test of intra-completion interference 2891 m.thenRun(f, () -> {}); 2892 m.thenRun(g, () -> {}); 2893 } 2894 f.complete(v1); 2895 checkCompletedNormally(h0, null); 2896 checkCompletedNormally(h1, null); 2897 rs[0].assertInvoked(); 2898 rs[1].assertInvoked(); 2899 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 2900 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 2901 checkCompletedNormally(h2, null); 2902 checkCompletedNormally(h3, null); 2903 rs[2].assertInvoked(); 2904 rs[3].assertInvoked(); 2905 2906 g.complete(v2); 2907 2908 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]); 2909 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]); 2910 2911 checkCompletedNormally(f, v1); 2912 checkCompletedNormally(g, v2); 2913 checkCompletedNormally(h0, null); 2914 checkCompletedNormally(h1, null); 2915 checkCompletedNormally(h2, null); 2916 checkCompletedNormally(h3, null); 2917 checkCompletedNormally(h4, null); 2918 checkCompletedNormally(h5, null); 2919 for (int i = 0; i < 6; i++) rs[i].assertInvoked(); 2920 }} 2921 2922 /** 2923 * runAfterEither result completes exceptionally after exceptional 2924 * completion of either source 2925 */ 2926 @Test testRunAfterEither_exceptionalCompletion()2927 public void testRunAfterEither_exceptionalCompletion() { 2928 for (ExecutionMode m : ExecutionMode.values()) 2929 for (Item v1 : new Item[] { itemOne, null }) 2930 { 2931 final CompletableFuture<Item> f = new CompletableFuture<>(); 2932 final CompletableFuture<Item> g = new CompletableFuture<>(); 2933 final CFException ex = new CFException(); 2934 final Noop[] rs = new Noop[6]; 2935 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 2936 2937 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 2938 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 2939 checkIncomplete(h0); 2940 checkIncomplete(h1); 2941 rs[0].assertNotInvoked(); 2942 rs[1].assertNotInvoked(); 2943 assertTrue(f.completeExceptionally(ex)); 2944 checkCompletedWithWrappedException(h0, ex); 2945 checkCompletedWithWrappedException(h1, ex); 2946 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 2947 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 2948 checkCompletedWithWrappedException(h2, ex); 2949 checkCompletedWithWrappedException(h3, ex); 2950 2951 assertTrue(g.complete(v1)); 2952 2953 // unspecified behavior - both source completions available 2954 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]); 2955 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]); 2956 try { 2957 assertNull(h4.join()); 2958 rs[4].assertInvoked(); 2959 } catch (CompletionException ok) { 2960 checkCompletedWithWrappedException(h4, ex); 2961 rs[4].assertNotInvoked(); 2962 } 2963 try { 2964 assertNull(h5.join()); 2965 rs[5].assertInvoked(); 2966 } catch (CompletionException ok) { 2967 checkCompletedWithWrappedException(h5, ex); 2968 rs[5].assertNotInvoked(); 2969 } 2970 2971 checkCompletedExceptionally(f, ex); 2972 checkCompletedNormally(g, v1); 2973 checkCompletedWithWrappedException(h0, ex); 2974 checkCompletedWithWrappedException(h1, ex); 2975 checkCompletedWithWrappedException(h2, ex); 2976 checkCompletedWithWrappedException(h3, ex); 2977 checkCompletedWithWrappedException(h4, ex); 2978 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2979 }} 2980 2981 @Test testRunAfterEither_exceptionalCompletion2()2982 public void testRunAfterEither_exceptionalCompletion2() { 2983 for (ExecutionMode m : ExecutionMode.values()) 2984 for (boolean fFirst : new boolean[] { true, false }) 2985 for (Item v1 : new Item[] { itemOne, null }) 2986 { 2987 final CompletableFuture<Item> f = new CompletableFuture<>(); 2988 final CompletableFuture<Item> g = new CompletableFuture<>(); 2989 final CFException ex = new CFException(); 2990 final Noop[] rs = new Noop[6]; 2991 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 2992 2993 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 2994 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 2995 assertTrue( fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2996 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2997 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 2998 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 2999 3000 // unspecified behavior - both source completions available 3001 try { 3002 assertNull(h0.join()); 3003 rs[0].assertInvoked(); 3004 } catch (CompletionException ok) { 3005 checkCompletedWithWrappedException(h0, ex); 3006 rs[0].assertNotInvoked(); 3007 } 3008 try { 3009 assertNull(h1.join()); 3010 rs[1].assertInvoked(); 3011 } catch (CompletionException ok) { 3012 checkCompletedWithWrappedException(h1, ex); 3013 rs[1].assertNotInvoked(); 3014 } 3015 try { 3016 assertNull(h2.join()); 3017 rs[2].assertInvoked(); 3018 } catch (CompletionException ok) { 3019 checkCompletedWithWrappedException(h2, ex); 3020 rs[2].assertNotInvoked(); 3021 } 3022 try { 3023 assertNull(h3.join()); 3024 rs[3].assertInvoked(); 3025 } catch (CompletionException ok) { 3026 checkCompletedWithWrappedException(h3, ex); 3027 rs[3].assertNotInvoked(); 3028 } 3029 3030 checkCompletedNormally(f, v1); 3031 checkCompletedExceptionally(g, ex); 3032 }} 3033 3034 /** 3035 * runAfterEither result completes exceptionally if either source cancelled 3036 */ 3037 @Test testRunAfterEither_sourceCancelled()3038 public void testRunAfterEither_sourceCancelled() { 3039 for (ExecutionMode m : ExecutionMode.values()) 3040 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 3041 for (Item v1 : new Item[] { itemOne, null }) 3042 { 3043 final CompletableFuture<Item> f = new CompletableFuture<>(); 3044 final CompletableFuture<Item> g = new CompletableFuture<>(); 3045 final Noop[] rs = new Noop[6]; 3046 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 3047 3048 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 3049 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 3050 checkIncomplete(h0); 3051 checkIncomplete(h1); 3052 rs[0].assertNotInvoked(); 3053 rs[1].assertNotInvoked(); 3054 f.cancel(mayInterruptIfRunning); 3055 checkCompletedWithWrappedCancellationException(h0); 3056 checkCompletedWithWrappedCancellationException(h1); 3057 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 3058 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 3059 checkCompletedWithWrappedCancellationException(h2); 3060 checkCompletedWithWrappedCancellationException(h3); 3061 3062 assertTrue(g.complete(v1)); 3063 3064 // unspecified behavior - both source completions available 3065 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]); 3066 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]); 3067 try { 3068 assertNull(h4.join()); 3069 rs[4].assertInvoked(); 3070 } catch (CompletionException ok) { 3071 checkCompletedWithWrappedCancellationException(h4); 3072 rs[4].assertNotInvoked(); 3073 } 3074 try { 3075 assertNull(h5.join()); 3076 rs[5].assertInvoked(); 3077 } catch (CompletionException ok) { 3078 checkCompletedWithWrappedCancellationException(h5); 3079 rs[5].assertNotInvoked(); 3080 } 3081 3082 checkCancelled(f); 3083 checkCompletedNormally(g, v1); 3084 checkCompletedWithWrappedCancellationException(h0); 3085 checkCompletedWithWrappedCancellationException(h1); 3086 checkCompletedWithWrappedCancellationException(h2); 3087 checkCompletedWithWrappedCancellationException(h3); 3088 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 3089 }} 3090 3091 /** 3092 * runAfterEither result completes exceptionally if action does 3093 */ 3094 @Test testRunAfterEither_actionFailed()3095 public void testRunAfterEither_actionFailed() { 3096 for (ExecutionMode m : ExecutionMode.values()) 3097 for (Item v1 : new Item[] { itemOne, null }) 3098 for (Item v2 : new Item[] { itemTwo, null }) 3099 { 3100 final CompletableFuture<Item> f = new CompletableFuture<>(); 3101 final CompletableFuture<Item> g = new CompletableFuture<>(); 3102 final FailingRunnable[] rs = new FailingRunnable[6]; 3103 for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m); 3104 3105 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 3106 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 3107 assertTrue(f.complete(v1)); 3108 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 3109 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 3110 checkCompletedWithWrappedException(h0, rs[0].ex); 3111 checkCompletedWithWrappedException(h1, rs[1].ex); 3112 checkCompletedWithWrappedException(h2, rs[2].ex); 3113 checkCompletedWithWrappedException(h3, rs[3].ex); 3114 for (int i = 0; i < 4; i++) rs[i].assertInvoked(); 3115 assertTrue(g.complete(v2)); 3116 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]); 3117 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]); 3118 checkCompletedWithWrappedException(h4, rs[4].ex); 3119 checkCompletedWithWrappedException(h5, rs[5].ex); 3120 3121 checkCompletedNormally(f, v1); 3122 checkCompletedNormally(g, v2); 3123 for (int i = 0; i < 6; i++) rs[i].assertInvoked(); 3124 }} 3125 3126 /** 3127 * thenCompose result completes normally after normal completion of source 3128 */ 3129 @Test testThenCompose_normalCompletion()3130 public void testThenCompose_normalCompletion() { 3131 for (ExecutionMode m : ExecutionMode.values()) 3132 for (boolean createIncomplete : new boolean[] { true, false }) 3133 for (Item v1 : new Item[] { itemOne, null }) 3134 { 3135 final CompletableFuture<Item> f = new CompletableFuture<>(); 3136 final CompletableFutureInc r = new CompletableFutureInc(m); 3137 if (!createIncomplete) assertTrue(f.complete(v1)); 3138 final CompletableFuture<Item> g = m.thenCompose(f, r); 3139 if (createIncomplete) assertTrue(f.complete(v1)); 3140 3141 checkCompletedNormally(g, inc(v1)); 3142 checkCompletedNormally(f, v1); 3143 r.assertValue(v1); 3144 }} 3145 3146 /** 3147 * thenCompose result completes exceptionally after exceptional 3148 * completion of source 3149 */ 3150 @Test testThenCompose_exceptionalCompletion()3151 public void testThenCompose_exceptionalCompletion() { 3152 for (ExecutionMode m : ExecutionMode.values()) 3153 for (boolean createIncomplete : new boolean[] { true, false }) 3154 { 3155 final CFException ex = new CFException(); 3156 final CompletableFutureInc r = new CompletableFutureInc(m); 3157 final CompletableFuture<Item> f = new CompletableFuture<>(); 3158 if (!createIncomplete) f.completeExceptionally(ex); 3159 final CompletableFuture<Item> g = m.thenCompose(f, r); 3160 if (createIncomplete) f.completeExceptionally(ex); 3161 3162 checkCompletedWithWrappedException(g, ex); 3163 checkCompletedExceptionally(f, ex); 3164 r.assertNotInvoked(); 3165 }} 3166 3167 /** 3168 * thenCompose result completes exceptionally if action does 3169 */ 3170 @Test testThenCompose_actionFailed()3171 public void testThenCompose_actionFailed() { 3172 for (ExecutionMode m : ExecutionMode.values()) 3173 for (boolean createIncomplete : new boolean[] { true, false }) 3174 for (Item v1 : new Item[] { itemOne, null }) 3175 { 3176 final CompletableFuture<Item> f = new CompletableFuture<>(); 3177 final FailingCompletableFutureFunction r 3178 = new FailingCompletableFutureFunction(m); 3179 if (!createIncomplete) assertTrue(f.complete(v1)); 3180 final CompletableFuture<Item> g = m.thenCompose(f, r); 3181 if (createIncomplete) assertTrue(f.complete(v1)); 3182 3183 checkCompletedWithWrappedException(g, r.ex); 3184 checkCompletedNormally(f, v1); 3185 }} 3186 3187 /** 3188 * thenCompose result completes exceptionally if source cancelled 3189 */ 3190 @Test testThenCompose_sourceCancelled()3191 public void testThenCompose_sourceCancelled() { 3192 for (ExecutionMode m : ExecutionMode.values()) 3193 for (boolean createIncomplete : new boolean[] { true, false }) 3194 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 3195 { 3196 final CompletableFuture<Item> f = new CompletableFuture<>(); 3197 final CompletableFutureInc r = new CompletableFutureInc(m); 3198 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 3199 final CompletableFuture<Item> g = m.thenCompose(f, r); 3200 if (createIncomplete) { 3201 checkIncomplete(g); 3202 assertTrue(f.cancel(mayInterruptIfRunning)); 3203 } 3204 3205 checkCompletedWithWrappedCancellationException(g); 3206 checkCancelled(f); 3207 }} 3208 3209 /** 3210 * thenCompose result completes exceptionally if the result of the action does 3211 */ 3212 @Test testThenCompose_actionReturnsFailingFuture()3213 public void testThenCompose_actionReturnsFailingFuture() { 3214 for (ExecutionMode m : ExecutionMode.values()) 3215 for (int order = 0; order < 6; order++) 3216 for (Item v1 : new Item[] { itemOne, null }) 3217 { 3218 final CFException ex = new CFException(); 3219 final CompletableFuture<Item> f = new CompletableFuture<>(); 3220 final CompletableFuture<Item> g = new CompletableFuture<>(); 3221 final CompletableFuture<Item> h; 3222 // Test all permutations of orders 3223 switch (order) { 3224 case 0: 3225 assertTrue(f.complete(v1)); 3226 assertTrue(g.completeExceptionally(ex)); 3227 h = m.thenCompose(f, x -> g); 3228 break; 3229 case 1: 3230 assertTrue(f.complete(v1)); 3231 h = m.thenCompose(f, x -> g); 3232 assertTrue(g.completeExceptionally(ex)); 3233 break; 3234 case 2: 3235 assertTrue(g.completeExceptionally(ex)); 3236 assertTrue(f.complete(v1)); 3237 h = m.thenCompose(f, x -> g); 3238 break; 3239 case 3: 3240 assertTrue(g.completeExceptionally(ex)); 3241 h = m.thenCompose(f, x -> g); 3242 assertTrue(f.complete(v1)); 3243 break; 3244 case 4: 3245 h = m.thenCompose(f, x -> g); 3246 assertTrue(f.complete(v1)); 3247 assertTrue(g.completeExceptionally(ex)); 3248 break; 3249 case 5: 3250 h = m.thenCompose(f, x -> g); 3251 assertTrue(f.complete(v1)); 3252 assertTrue(g.completeExceptionally(ex)); 3253 break; 3254 default: throw new AssertionError(); 3255 } 3256 3257 checkCompletedExceptionally(g, ex); 3258 checkCompletedWithWrappedException(h, ex); 3259 checkCompletedNormally(f, v1); 3260 }} 3261 3262 /** 3263 * exceptionallyCompose result completes normally after normal 3264 * completion of source 3265 */ 3266 @Test testExceptionallyCompose_normalCompletion()3267 public void testExceptionallyCompose_normalCompletion() { 3268 for (ExecutionMode m : ExecutionMode.values()) 3269 for (boolean createIncomplete : new boolean[] { true, false }) 3270 for (Item v1 : new Item[] { itemOne, null }) 3271 { 3272 final CompletableFuture<Item> f = new CompletableFuture<>(); 3273 final ExceptionalCompletableFutureFunction r = 3274 new ExceptionalCompletableFutureFunction(m); 3275 if (!createIncomplete) assertTrue(f.complete(v1)); 3276 final CompletableFuture<Item> g = m.exceptionallyCompose(f, r); 3277 if (createIncomplete) assertTrue(f.complete(v1)); 3278 3279 checkCompletedNormally(f, v1); 3280 checkCompletedNormally(g, v1); 3281 r.assertNotInvoked(); 3282 }} 3283 3284 /** 3285 * exceptionallyCompose result completes normally after exceptional 3286 * completion of source 3287 */ 3288 @Test testExceptionallyCompose_exceptionalCompletion()3289 public void testExceptionallyCompose_exceptionalCompletion() { 3290 for (ExecutionMode m : ExecutionMode.values()) 3291 for (boolean createIncomplete : new boolean[] { true, false }) 3292 { 3293 final CFException ex = new CFException(); 3294 final ExceptionalCompletableFutureFunction r = 3295 new ExceptionalCompletableFutureFunction(m); 3296 final CompletableFuture<Item> f = new CompletableFuture<>(); 3297 if (!createIncomplete) f.completeExceptionally(ex); 3298 final CompletableFuture<Item> g = m.exceptionallyCompose(f, r); 3299 if (createIncomplete) f.completeExceptionally(ex); 3300 3301 checkCompletedExceptionally(f, ex); 3302 checkCompletedNormally(g, r.value); 3303 r.assertInvoked(); 3304 }} 3305 3306 /** 3307 * exceptionallyCompose completes exceptionally on exception if action does 3308 */ 3309 @Test testExceptionallyCompose_actionFailed()3310 public void testExceptionallyCompose_actionFailed() { 3311 for (ExecutionMode m : ExecutionMode.values()) 3312 for (boolean createIncomplete : new boolean[] { true, false }) 3313 { 3314 final CFException ex = new CFException(); 3315 final CompletableFuture<Item> f = new CompletableFuture<>(); 3316 final FailingExceptionalCompletableFutureFunction r 3317 = new FailingExceptionalCompletableFutureFunction(m); 3318 if (!createIncomplete) f.completeExceptionally(ex); 3319 final CompletableFuture<Item> g = m.exceptionallyCompose(f, r); 3320 if (createIncomplete) f.completeExceptionally(ex); 3321 3322 checkCompletedExceptionally(f, ex); 3323 checkCompletedWithWrappedException(g, r.ex); 3324 r.assertInvoked(); 3325 }} 3326 3327 /** 3328 * exceptionallyCompose result completes exceptionally if the 3329 * result of the action does 3330 */ 3331 @Test testExceptionallyCompose_actionReturnsFailingFuture()3332 public void testExceptionallyCompose_actionReturnsFailingFuture() { 3333 for (ExecutionMode m : ExecutionMode.values()) 3334 for (int order = 0; order < 6; order++) 3335 { 3336 final CFException ex0 = new CFException(); 3337 final CFException ex = new CFException(); 3338 final CompletableFuture<Item> f = new CompletableFuture<>(); 3339 final CompletableFuture<Item> g = new CompletableFuture<>(); 3340 final CompletableFuture<Item> h; 3341 // Test all permutations of orders 3342 switch (order) { 3343 case 0: 3344 assertTrue(f.completeExceptionally(ex0)); 3345 assertTrue(g.completeExceptionally(ex)); 3346 h = m.exceptionallyCompose(f, x -> g); 3347 break; 3348 case 1: 3349 assertTrue(f.completeExceptionally(ex0)); 3350 h = m.exceptionallyCompose(f, x -> g); 3351 assertTrue(g.completeExceptionally(ex)); 3352 break; 3353 case 2: 3354 assertTrue(g.completeExceptionally(ex)); 3355 assertTrue(f.completeExceptionally(ex0)); 3356 h = m.exceptionallyCompose(f, x -> g); 3357 break; 3358 case 3: 3359 assertTrue(g.completeExceptionally(ex)); 3360 h = m.exceptionallyCompose(f, x -> g); 3361 assertTrue(f.completeExceptionally(ex0)); 3362 break; 3363 case 4: 3364 h = m.exceptionallyCompose(f, x -> g); 3365 assertTrue(f.completeExceptionally(ex0)); 3366 assertTrue(g.completeExceptionally(ex)); 3367 break; 3368 case 5: 3369 h = m.exceptionallyCompose(f, x -> g); 3370 assertTrue(f.completeExceptionally(ex0)); 3371 assertTrue(g.completeExceptionally(ex)); 3372 break; 3373 default: throw new AssertionError(); 3374 } 3375 3376 checkCompletedExceptionally(g, ex); 3377 checkCompletedWithWrappedException(h, ex); 3378 checkCompletedExceptionally(f, ex0); 3379 }} 3380 3381 // other static methods 3382 3383 /** 3384 * allOf(no component futures) returns a future completed normally 3385 * with the value null 3386 */ 3387 @Test testAllOf_empty()3388 public void testAllOf_empty() throws Exception { 3389 CompletableFuture<Void> f = CompletableFuture.allOf(); 3390 checkCompletedNormally(f, null); 3391 } 3392 3393 /** 3394 * allOf returns a future completed normally with the value null 3395 * when all components complete normally 3396 */ 3397 @Test testAllOf_normal()3398 public void testAllOf_normal() throws Exception { 3399 for (int k = 1; k < 10; k++) { 3400 @SuppressWarnings("unchecked") 3401 CompletableFuture<Item>[] fs 3402 = (CompletableFuture<Item>[]) new CompletableFuture[k]; 3403 for (int i = 0; i < k; i++) 3404 fs[i] = new CompletableFuture<>(); 3405 CompletableFuture<Void> f = CompletableFuture.allOf(fs); 3406 for (int i = 0; i < k; i++) { 3407 checkIncomplete(f); 3408 checkIncomplete(CompletableFuture.allOf(fs)); 3409 fs[i].complete(itemOne); 3410 } 3411 checkCompletedNormally(f, null); 3412 checkCompletedNormally(CompletableFuture.allOf(fs), null); 3413 } 3414 } 3415 3416 @Test testAllOf_normal_backwards()3417 public void testAllOf_normal_backwards() throws Exception { 3418 for (int k = 1; k < 10; k++) { 3419 @SuppressWarnings("unchecked") 3420 CompletableFuture<Item>[] fs 3421 = (CompletableFuture<Item>[]) new CompletableFuture[k]; 3422 for (int i = 0; i < k; i++) 3423 fs[i] = new CompletableFuture<>(); 3424 CompletableFuture<Void> f = CompletableFuture.allOf(fs); 3425 for (int i = k - 1; i >= 0; i--) { 3426 checkIncomplete(f); 3427 checkIncomplete(CompletableFuture.allOf(fs)); 3428 fs[i].complete(itemOne); 3429 } 3430 checkCompletedNormally(f, null); 3431 checkCompletedNormally(CompletableFuture.allOf(fs), null); 3432 } 3433 } 3434 3435 @Test testAllOf_exceptional()3436 public void testAllOf_exceptional() throws Exception { 3437 for (int k = 1; k < 10; k++) { 3438 @SuppressWarnings("unchecked") 3439 CompletableFuture<Item>[] fs 3440 = (CompletableFuture<Item>[]) new CompletableFuture[k]; 3441 CFException ex = new CFException(); 3442 for (int i = 0; i < k; i++) 3443 fs[i] = new CompletableFuture<>(); 3444 CompletableFuture<Void> f = CompletableFuture.allOf(fs); 3445 for (int i = 0; i < k; i++) { 3446 Item I = itemFor(i); 3447 checkIncomplete(f); 3448 checkIncomplete(CompletableFuture.allOf(fs)); 3449 if (i != k / 2) { 3450 fs[i].complete(I); 3451 checkCompletedNormally(fs[i], I); 3452 } else { 3453 fs[i].completeExceptionally(ex); 3454 checkCompletedExceptionally(fs[i], ex); 3455 } 3456 } 3457 checkCompletedWithWrappedException(f, ex); 3458 checkCompletedWithWrappedException(CompletableFuture.allOf(fs), ex); 3459 } 3460 } 3461 3462 /** 3463 * anyOf(no component futures) returns an incomplete future 3464 */ 3465 @Test testAnyOf_empty()3466 public void testAnyOf_empty() throws Exception { 3467 for (Item v1 : new Item[] { itemOne, null }) 3468 { 3469 CompletableFuture<Object> f = CompletableFuture.anyOf(); 3470 checkIncomplete(f); 3471 3472 f.complete(v1); 3473 checkCompletedNormally(f, v1); 3474 }} 3475 3476 /** 3477 * anyOf returns a future completed normally with a value when 3478 * a component future does 3479 */ 3480 @Test testAnyOf_normal()3481 public void testAnyOf_normal() throws Exception { 3482 for (int k = 0; k < 10; k++) { 3483 @SuppressWarnings("unchecked") 3484 CompletableFuture<Item>[] fs = 3485 (CompletableFuture<Item>[])new CompletableFuture[k]; 3486 for (int i = 0; i < k; i++) 3487 fs[i] = new CompletableFuture<>(); 3488 CompletableFuture<Object> f = CompletableFuture.anyOf(fs); 3489 checkIncomplete(f); 3490 for (int i = 0; i < k; i++) { 3491 fs[i].complete(itemFor(i)); 3492 checkCompletedNormally(f, itemZero); 3493 Item x = (Item)CompletableFuture.anyOf(fs).join(); 3494 assertTrue(0 <= x.value && x.value <= i); 3495 } 3496 } 3497 } 3498 @Test testAnyOf_normal_backwards()3499 public void testAnyOf_normal_backwards() throws Exception { 3500 for (int k = 0; k < 10; k++) { 3501 @SuppressWarnings("unchecked") 3502 CompletableFuture<Item>[] fs = 3503 (CompletableFuture<Item>[])new CompletableFuture[k]; 3504 for (int i = 0; i < k; i++) 3505 fs[i] = new CompletableFuture<>(); 3506 CompletableFuture<Object> f = CompletableFuture.anyOf(fs); 3507 checkIncomplete(f); 3508 for (int i = k - 1; i >= 0; i--) { 3509 fs[i].complete(itemFor(i)); 3510 checkCompletedNormally(f, itemFor(k - 1)); 3511 Item x = (Item)CompletableFuture.anyOf(fs).join(); 3512 assertTrue(i <= x.value && x.value <= k - 1); 3513 } 3514 } 3515 } 3516 3517 /** 3518 * anyOf result completes exceptionally when any component does. 3519 */ 3520 @Test testAnyOf_exceptional()3521 public void testAnyOf_exceptional() throws Exception { 3522 for (int k = 0; k < 10; k++) { 3523 @SuppressWarnings("unchecked") 3524 CompletableFuture<Item>[] fs = 3525 (CompletableFuture<Item>[])new CompletableFuture[k]; 3526 CFException[] exs = new CFException[k]; 3527 for (int i = 0; i < k; i++) { 3528 fs[i] = new CompletableFuture<>(); 3529 exs[i] = new CFException(); 3530 } 3531 CompletableFuture<Object> f = CompletableFuture.anyOf(fs); 3532 checkIncomplete(f); 3533 for (int i = 0; i < k; i++) { 3534 fs[i].completeExceptionally(exs[i]); 3535 checkCompletedWithWrappedException(f, exs[0]); 3536 checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs)); 3537 } 3538 } 3539 } 3540 3541 @Test testAnyOf_exceptional_backwards()3542 public void testAnyOf_exceptional_backwards() throws Exception { 3543 for (int k = 0; k < 10; k++) { 3544 @SuppressWarnings("unchecked") 3545 CompletableFuture<Object>[] fs = 3546 (CompletableFuture<Object>[])new CompletableFuture[k]; 3547 CFException[] exs = new CFException[k]; 3548 for (int i = 0; i < k; i++) { 3549 fs[i] = new CompletableFuture<>(); 3550 exs[i] = new CFException(); 3551 } 3552 CompletableFuture<Object> f = CompletableFuture.anyOf(fs); 3553 checkIncomplete(f); 3554 for (int i = k - 1; i >= 0; i--) { 3555 fs[i].completeExceptionally(exs[i]); 3556 checkCompletedWithWrappedException(f, exs[k - 1]); 3557 checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs)); 3558 } 3559 } 3560 } 3561 3562 /** 3563 * Completion methods throw NullPointerException with null arguments 3564 */ 3565 @SuppressWarnings("FutureReturnValueIgnored") 3566 @Test testNPE()3567 public void testNPE() { 3568 CompletableFuture<Item> f = new CompletableFuture<>(); 3569 CompletableFuture<Item> g = new CompletableFuture<>(); 3570 CompletableFuture<Item> nullFuture = (CompletableFuture<Item>)null; 3571 ThreadExecutor exec = new ThreadExecutor(); 3572 3573 assertThrows( 3574 NullPointerException.class, 3575 3576 () -> CompletableFuture.supplyAsync(null), 3577 () -> CompletableFuture.supplyAsync(null, exec), 3578 () -> CompletableFuture.supplyAsync(new ItemSupplier(ExecutionMode.SYNC, fortytwo), null), 3579 3580 () -> CompletableFuture.runAsync(null), 3581 () -> CompletableFuture.runAsync(null, exec), 3582 () -> CompletableFuture.runAsync(() -> {}, null), 3583 3584 () -> f.completeExceptionally(null), 3585 3586 () -> f.thenApply(null), 3587 () -> f.thenApplyAsync(null), 3588 () -> f.thenApplyAsync(x -> x, null), 3589 () -> f.thenApplyAsync(null, exec), 3590 3591 () -> f.thenAccept(null), 3592 () -> f.thenAcceptAsync(null), 3593 () -> f.thenAcceptAsync(x -> {} , null), 3594 () -> f.thenAcceptAsync(null, exec), 3595 3596 () -> f.thenRun(null), 3597 () -> f.thenRunAsync(null), 3598 () -> f.thenRunAsync(() -> {} , null), 3599 () -> f.thenRunAsync(null, exec), 3600 3601 () -> f.thenCombine(g, null), 3602 () -> f.thenCombineAsync(g, null), 3603 () -> f.thenCombineAsync(g, null, exec), 3604 () -> f.thenCombine(nullFuture, (x, y) -> x), 3605 () -> f.thenCombineAsync(nullFuture, (x, y) -> x), 3606 () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec), 3607 () -> f.thenCombineAsync(g, (x, y) -> x, null), 3608 3609 () -> f.thenAcceptBoth(g, null), 3610 () -> f.thenAcceptBothAsync(g, null), 3611 () -> f.thenAcceptBothAsync(g, null, exec), 3612 () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}), 3613 () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}), 3614 () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec), 3615 () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null), 3616 3617 () -> f.runAfterBoth(g, null), 3618 () -> f.runAfterBothAsync(g, null), 3619 () -> f.runAfterBothAsync(g, null, exec), 3620 () -> f.runAfterBoth(nullFuture, () -> {}), 3621 () -> f.runAfterBothAsync(nullFuture, () -> {}), 3622 () -> f.runAfterBothAsync(nullFuture, () -> {}, exec), 3623 () -> f.runAfterBothAsync(g, () -> {}, null), 3624 3625 () -> f.applyToEither(g, null), 3626 () -> f.applyToEitherAsync(g, null), 3627 () -> f.applyToEitherAsync(g, null, exec), 3628 () -> f.applyToEither(nullFuture, x -> x), 3629 () -> f.applyToEitherAsync(nullFuture, x -> x), 3630 () -> f.applyToEitherAsync(nullFuture, x -> x, exec), 3631 () -> f.applyToEitherAsync(g, x -> x, null), 3632 3633 () -> f.acceptEither(g, null), 3634 () -> f.acceptEitherAsync(g, null), 3635 () -> f.acceptEitherAsync(g, null, exec), 3636 () -> f.acceptEither(nullFuture, x -> {}), 3637 () -> f.acceptEitherAsync(nullFuture, x -> {}), 3638 () -> f.acceptEitherAsync(nullFuture, x -> {}, exec), 3639 () -> f.acceptEitherAsync(g, x -> {}, null), 3640 3641 () -> f.runAfterEither(g, null), 3642 () -> f.runAfterEitherAsync(g, null), 3643 () -> f.runAfterEitherAsync(g, null, exec), 3644 () -> f.runAfterEither(nullFuture, () -> {}), 3645 () -> f.runAfterEitherAsync(nullFuture, () -> {}), 3646 () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec), 3647 () -> f.runAfterEitherAsync(g, () -> {}, null), 3648 3649 () -> f.thenCompose(null), 3650 () -> f.thenComposeAsync(null), 3651 () -> f.thenComposeAsync(new CompletableFutureInc(ExecutionMode.EXECUTOR), null), 3652 () -> f.thenComposeAsync(null, exec), 3653 3654 () -> f.exceptionally(null), 3655 3656 () -> f.handle(null), 3657 3658 () -> CompletableFuture.allOf((CompletableFuture<?>)null), 3659 () -> CompletableFuture.allOf((CompletableFuture<?>[])null), 3660 () -> CompletableFuture.allOf(f, null), 3661 () -> CompletableFuture.allOf(null, f), 3662 3663 () -> CompletableFuture.anyOf((CompletableFuture<?>)null), 3664 () -> CompletableFuture.anyOf((CompletableFuture<?>[])null), 3665 () -> CompletableFuture.anyOf(f, null), 3666 () -> CompletableFuture.anyOf(null, f), 3667 3668 () -> f.obtrudeException(null), 3669 3670 () -> CompletableFuture.delayedExecutor(1L, SECONDS, null), 3671 () -> CompletableFuture.delayedExecutor(1L, null, exec), 3672 () -> CompletableFuture.delayedExecutor(1L, null), 3673 3674 () -> f.orTimeout(1L, null), 3675 () -> f.completeOnTimeout(fortytwo, 1L, null), 3676 3677 () -> CompletableFuture.failedFuture(null), 3678 () -> CompletableFuture.failedStage(null)); 3679 3680 mustEqual(0, exec.count.get()); 3681 } 3682 3683 /** 3684 * Test submissions to an executor that rejects all tasks. 3685 */ 3686 @Test testRejectingExecutor()3687 public void testRejectingExecutor() { 3688 for (Item v : new Item[] { itemOne, null }) 3689 { 3690 final CountingRejectingExecutor e = new CountingRejectingExecutor(); 3691 3692 final CompletableFuture<Item> complete = CompletableFuture.completedFuture(v); 3693 final CompletableFuture<Item> incomplete = new CompletableFuture<>(); 3694 3695 List<CompletableFuture<?>> futures = new ArrayList<>(); 3696 3697 List<CompletableFuture<Item>> srcs = new ArrayList<>(); 3698 srcs.add(complete); 3699 srcs.add(incomplete); 3700 3701 for (CompletableFuture<Item> src : srcs) { 3702 List<CompletableFuture<?>> fs = new ArrayList<>(); 3703 fs.add(src.thenRunAsync(() -> {}, e)); 3704 fs.add(src.thenAcceptAsync(z -> {}, e)); 3705 fs.add(src.thenApplyAsync(z -> z, e)); 3706 3707 fs.add(src.thenCombineAsync(src, (x, y) -> x, e)); 3708 fs.add(src.thenAcceptBothAsync(src, (x, y) -> {}, e)); 3709 fs.add(src.runAfterBothAsync(src, () -> {}, e)); 3710 3711 fs.add(src.applyToEitherAsync(src, z -> z, e)); 3712 fs.add(src.acceptEitherAsync(src, z -> {}, e)); 3713 fs.add(src.runAfterEitherAsync(src, () -> {}, e)); 3714 3715 fs.add(src.thenComposeAsync(z -> null, e)); 3716 fs.add(src.whenCompleteAsync((z, t) -> {}, e)); 3717 fs.add(src.handleAsync((z, t) -> null, e)); 3718 3719 for (CompletableFuture<?> future : fs) { 3720 if (src.isDone()) 3721 checkCompletedWithWrappedException(future, e.ex); 3722 else 3723 checkIncomplete(future); 3724 } 3725 futures.addAll(fs); 3726 } 3727 3728 { 3729 List<CompletableFuture<?>> fs = new ArrayList<>(); 3730 3731 fs.add(complete.thenCombineAsync(incomplete, (x, y) -> x, e)); 3732 fs.add(incomplete.thenCombineAsync(complete, (x, y) -> x, e)); 3733 3734 fs.add(complete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e)); 3735 fs.add(incomplete.thenAcceptBothAsync(complete, (x, y) -> {}, e)); 3736 3737 fs.add(complete.runAfterBothAsync(incomplete, () -> {}, e)); 3738 fs.add(incomplete.runAfterBothAsync(complete, () -> {}, e)); 3739 3740 for (CompletableFuture<?> future : fs) 3741 checkIncomplete(future); 3742 futures.addAll(fs); 3743 } 3744 3745 { 3746 List<CompletableFuture<?>> fs = new ArrayList<>(); 3747 3748 fs.add(complete.applyToEitherAsync(incomplete, z -> z, e)); 3749 fs.add(incomplete.applyToEitherAsync(complete, z -> z, e)); 3750 3751 fs.add(complete.acceptEitherAsync(incomplete, z -> {}, e)); 3752 fs.add(incomplete.acceptEitherAsync(complete, z -> {}, e)); 3753 3754 fs.add(complete.runAfterEitherAsync(incomplete, () -> {}, e)); 3755 fs.add(incomplete.runAfterEitherAsync(complete, () -> {}, e)); 3756 3757 for (CompletableFuture<?> future : fs) 3758 checkCompletedWithWrappedException(future, e.ex); 3759 futures.addAll(fs); 3760 } 3761 3762 incomplete.complete(v); 3763 3764 for (CompletableFuture<?> future : futures) 3765 checkCompletedWithWrappedException(future, e.ex); 3766 3767 mustEqual(futures.size(), e.count.get()); 3768 }} 3769 3770 /** 3771 * Test submissions to an executor that rejects all tasks, but 3772 * should never be invoked because the dependent future is 3773 * explicitly completed. 3774 */ 3775 @Test testRejectingExecutorNeverInvoked()3776 public void testRejectingExecutorNeverInvoked() { 3777 for (Item v : new Item[] { itemOne, null }) 3778 { 3779 final CountingRejectingExecutor e = new CountingRejectingExecutor(); 3780 3781 final CompletableFuture<Item> complete = CompletableFuture.completedFuture(v); 3782 final CompletableFuture<Item> incomplete = new CompletableFuture<>(); 3783 3784 List<CompletableFuture<?>> fs = new ArrayList<>(); 3785 fs.add(incomplete.thenRunAsync(() -> {}, e)); 3786 fs.add(incomplete.thenAcceptAsync(z -> {}, e)); 3787 fs.add(incomplete.thenApplyAsync(z -> z, e)); 3788 3789 fs.add(incomplete.thenCombineAsync(incomplete, (x, y) -> x, e)); 3790 fs.add(incomplete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e)); 3791 fs.add(incomplete.runAfterBothAsync(incomplete, () -> {}, e)); 3792 3793 fs.add(incomplete.applyToEitherAsync(incomplete, z -> z, e)); 3794 fs.add(incomplete.acceptEitherAsync(incomplete, z -> {}, e)); 3795 fs.add(incomplete.runAfterEitherAsync(incomplete, () -> {}, e)); 3796 3797 fs.add(incomplete.thenComposeAsync(z -> null, e)); 3798 fs.add(incomplete.whenCompleteAsync((z, t) -> {}, e)); 3799 fs.add(incomplete.handleAsync((z, t) -> null, e)); 3800 3801 fs.add(complete.thenCombineAsync(incomplete, (x, y) -> x, e)); 3802 fs.add(incomplete.thenCombineAsync(complete, (x, y) -> x, e)); 3803 3804 fs.add(complete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e)); 3805 fs.add(incomplete.thenAcceptBothAsync(complete, (x, y) -> {}, e)); 3806 3807 fs.add(complete.runAfterBothAsync(incomplete, () -> {}, e)); 3808 fs.add(incomplete.runAfterBothAsync(complete, () -> {}, e)); 3809 3810 for (CompletableFuture<?> future : fs) 3811 checkIncomplete(future); 3812 3813 for (CompletableFuture<?> future : fs) 3814 future.complete(null); 3815 3816 incomplete.complete(v); 3817 3818 for (CompletableFuture<?> future : fs) 3819 checkCompletedNormally(future, null); 3820 3821 mustEqual(0, e.count.get()); 3822 }} 3823 3824 /** 3825 * toCompletableFuture returns this CompletableFuture. 3826 */ 3827 @Test testToCompletableFuture()3828 public void testToCompletableFuture() { 3829 CompletableFuture<Item> f = new CompletableFuture<>(); 3830 assertSame(f, f.toCompletableFuture()); 3831 } 3832 3833 // jdk9 3834 3835 /** 3836 * newIncompleteFuture returns an incomplete CompletableFuture 3837 */ 3838 @Test testNewIncompleteFuture()3839 public void testNewIncompleteFuture() { 3840 for (Item v1 : new Item[] { itemOne, null }) 3841 { 3842 CompletableFuture<Item> f = new CompletableFuture<>(); 3843 CompletableFuture<Item> g = f.newIncompleteFuture(); 3844 checkIncomplete(f); 3845 checkIncomplete(g); 3846 f.complete(v1); 3847 checkCompletedNormally(f, v1); 3848 checkIncomplete(g); 3849 g.complete(v1); 3850 checkCompletedNormally(g, v1); 3851 assertSame(g.getClass(), CompletableFuture.class); 3852 }} 3853 3854 /** 3855 * completedStage returns a completed CompletionStage 3856 */ 3857 @Test testCompletedStage()3858 public void testCompletedStage() { 3859 AtomicInteger x = new AtomicInteger(0); 3860 AtomicReference<Throwable> r = new AtomicReference<>(); 3861 CompletionStage<Item> f = CompletableFuture.completedStage(itemOne); 3862 f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v.value);}); 3863 mustEqual(x.get(), 1); 3864 assertNull(r.get()); 3865 } 3866 3867 /** 3868 * defaultExecutor by default returns the commonPool if 3869 * it supports more than one thread. 3870 */ 3871 @Test testDefaultExecutor()3872 public void testDefaultExecutor() { 3873 CompletableFuture<Item> f = new CompletableFuture<>(); 3874 Executor e = f.defaultExecutor(); 3875 Executor c = ForkJoinPool.commonPool(); 3876 if (ForkJoinPool.getCommonPoolParallelism() > 1) 3877 assertSame(e, c); 3878 else 3879 assertNotSame(e, c); 3880 } 3881 3882 /** 3883 * failedFuture returns a CompletableFuture completed 3884 * exceptionally with the given Exception 3885 */ 3886 @Test testFailedFuture()3887 public void testFailedFuture() { 3888 CFException ex = new CFException(); 3889 CompletableFuture<Item> f = CompletableFuture.failedFuture(ex); 3890 checkCompletedExceptionally(f, ex); 3891 } 3892 3893 /** 3894 * copy returns a CompletableFuture that is completed normally, 3895 * with the same value, when source is. 3896 */ 3897 @Test testCopy_normalCompletion()3898 public void testCopy_normalCompletion() { 3899 for (boolean createIncomplete : new boolean[] { true, false }) 3900 for (Item v1 : new Item[] { itemOne, null }) 3901 { 3902 CompletableFuture<Item> f = new CompletableFuture<>(); 3903 if (!createIncomplete) assertTrue(f.complete(v1)); 3904 CompletableFuture<Item> g = f.copy(); 3905 if (createIncomplete) { 3906 checkIncomplete(f); 3907 checkIncomplete(g); 3908 assertTrue(f.complete(v1)); 3909 } 3910 checkCompletedNormally(f, v1); 3911 checkCompletedNormally(g, v1); 3912 }} 3913 3914 /** 3915 * copy returns a CompletableFuture that is completed exceptionally 3916 * when source is. 3917 */ 3918 @Test testCopy_exceptionalCompletion()3919 public void testCopy_exceptionalCompletion() { 3920 for (boolean createIncomplete : new boolean[] { true, false }) 3921 { 3922 CFException ex = new CFException(); 3923 CompletableFuture<Item> f = new CompletableFuture<>(); 3924 if (!createIncomplete) f.completeExceptionally(ex); 3925 CompletableFuture<Item> g = f.copy(); 3926 if (createIncomplete) { 3927 checkIncomplete(f); 3928 checkIncomplete(g); 3929 f.completeExceptionally(ex); 3930 } 3931 checkCompletedExceptionally(f, ex); 3932 checkCompletedWithWrappedException(g, ex); 3933 }} 3934 3935 /** 3936 * Completion of a copy does not complete its source. 3937 */ 3938 @Test testCopy_oneWayPropagation()3939 public void testCopy_oneWayPropagation() { 3940 CompletableFuture<Item> f = new CompletableFuture<>(); 3941 assertTrue(f.copy().complete(itemOne)); 3942 assertTrue(f.copy().complete(null)); 3943 assertTrue(f.copy().cancel(true)); 3944 assertTrue(f.copy().cancel(false)); 3945 assertTrue(f.copy().completeExceptionally(new CFException())); 3946 checkIncomplete(f); 3947 } 3948 3949 /** 3950 * minimalCompletionStage returns a CompletableFuture that is 3951 * completed normally, with the same value, when source is. 3952 */ 3953 @Test testMinimalCompletionStage()3954 public void testMinimalCompletionStage() { 3955 CompletableFuture<Item> f = new CompletableFuture<>(); 3956 CompletionStage<Item> g = f.minimalCompletionStage(); 3957 AtomicInteger x = new AtomicInteger(0); 3958 AtomicReference<Throwable> r = new AtomicReference<>(); 3959 checkIncomplete(f); 3960 g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v.value);}); 3961 f.complete(itemOne); 3962 checkCompletedNormally(f, itemOne); 3963 mustEqual(x.get(), 1); 3964 assertNull(r.get()); 3965 } 3966 3967 /** 3968 * minimalCompletionStage returns a CompletableFuture that is 3969 * completed exceptionally when source is. 3970 */ 3971 @Test testMinimalCompletionStage2()3972 public void testMinimalCompletionStage2() { 3973 CompletableFuture<Item> f = new CompletableFuture<>(); 3974 CompletionStage<Item> g = f.minimalCompletionStage(); 3975 AtomicInteger x = new AtomicInteger(0); 3976 AtomicReference<Throwable> r = new AtomicReference<>(); 3977 g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v.value);}); 3978 checkIncomplete(f); 3979 CFException ex = new CFException(); 3980 f.completeExceptionally(ex); 3981 checkCompletedExceptionally(f, ex); 3982 mustEqual(x.get(), 0); 3983 mustEqual(r.get().getCause(), ex); 3984 } 3985 3986 /** 3987 * failedStage returns a CompletionStage completed 3988 * exceptionally with the given Exception 3989 */ 3990 @Test testFailedStage()3991 public void testFailedStage() { 3992 CFException ex = new CFException(); 3993 CompletionStage<Item> f = CompletableFuture.failedStage(ex); 3994 AtomicInteger x = new AtomicInteger(0); 3995 AtomicReference<Throwable> r = new AtomicReference<>(); 3996 f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v.value);}); 3997 mustEqual(x.get(), 0); 3998 mustEqual(r.get(), ex); 3999 } 4000 4001 /** 4002 * completeAsync completes with value of given supplier 4003 */ 4004 @Test testCompleteAsync()4005 public void testCompleteAsync() { 4006 for (Item v1 : new Item[] { itemOne, null }) 4007 { 4008 CompletableFuture<Item> f = new CompletableFuture<>(); 4009 f.completeAsync(() -> v1); 4010 f.join(); 4011 checkCompletedNormally(f, v1); 4012 }} 4013 4014 /** 4015 * completeAsync completes exceptionally if given supplier throws 4016 */ 4017 @Test testCompleteAsync2()4018 public void testCompleteAsync2() { 4019 CompletableFuture<Item> f = new CompletableFuture<>(); 4020 CFException ex = new CFException(); 4021 f.completeAsync(() -> { throw ex; }); 4022 try { 4023 f.join(); 4024 shouldThrow(); 4025 } catch (CompletionException success) {} 4026 checkCompletedWithWrappedException(f, ex); 4027 } 4028 4029 /** 4030 * completeAsync with given executor completes with value of given supplier 4031 */ 4032 @Test testCompleteAsync3()4033 public void testCompleteAsync3() { 4034 for (Item v1 : new Item[] { itemOne, null }) 4035 { 4036 CompletableFuture<Item> f = new CompletableFuture<>(); 4037 ThreadExecutor executor = new ThreadExecutor(); 4038 f.completeAsync(() -> v1, executor); 4039 assertSame(v1, f.join()); 4040 checkCompletedNormally(f, v1); 4041 mustEqual(1, executor.count.get()); 4042 }} 4043 4044 /** 4045 * completeAsync with given executor completes exceptionally if 4046 * given supplier throws 4047 */ 4048 @Test testCompleteAsync4()4049 public void testCompleteAsync4() { 4050 CompletableFuture<Item> f = new CompletableFuture<>(); 4051 CFException ex = new CFException(); 4052 ThreadExecutor executor = new ThreadExecutor(); 4053 f.completeAsync(() -> { throw ex; }, executor); 4054 try { 4055 f.join(); 4056 shouldThrow(); 4057 } catch (CompletionException success) {} 4058 checkCompletedWithWrappedException(f, ex); 4059 mustEqual(1, executor.count.get()); 4060 } 4061 4062 /** 4063 * orTimeout completes with TimeoutException if not complete 4064 */ 4065 @Test testOrTimeout_timesOut()4066 public void testOrTimeout_timesOut() { 4067 long timeoutMillis = timeoutMillis(); 4068 CompletableFuture<Item> f = new CompletableFuture<>(); 4069 long startTime = System.nanoTime(); 4070 assertSame(f, f.orTimeout(timeoutMillis, MILLISECONDS)); 4071 checkCompletedWithTimeoutException(f); 4072 assertTrue(millisElapsedSince(startTime) >= timeoutMillis); 4073 } 4074 4075 /** 4076 * orTimeout completes normally if completed before timeout 4077 */ 4078 @Test testOrTimeout_completed()4079 public void testOrTimeout_completed() { 4080 for (Item v1 : new Item[] { itemOne, null }) 4081 { 4082 CompletableFuture<Item> f = new CompletableFuture<>(); 4083 CompletableFuture<Item> g = new CompletableFuture<>(); 4084 long startTime = System.nanoTime(); 4085 f.complete(v1); 4086 assertSame(f, f.orTimeout(LONG_DELAY_MS, MILLISECONDS)); 4087 assertSame(g, g.orTimeout(LONG_DELAY_MS, MILLISECONDS)); 4088 g.complete(v1); 4089 checkCompletedNormally(f, v1); 4090 checkCompletedNormally(g, v1); 4091 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); 4092 }} 4093 4094 /** 4095 * completeOnTimeout completes with given value if not complete 4096 */ 4097 @Test 4098 public void testCompleteOnTimeout_timesOut() { 4099 testInParallel(() -> testCompleteOnTimeout_timesOut(fortytwo), 4100 () -> testCompleteOnTimeout_timesOut(null)); 4101 } 4102 4103 /** 4104 * completeOnTimeout completes with given value if not complete 4105 */ testCompleteOnTimeout_timesOut(Item v)4106 private void testCompleteOnTimeout_timesOut(Item v) { 4107 long timeoutMillis = timeoutMillis(); 4108 CompletableFuture<Item> f = new CompletableFuture<>(); 4109 long startTime = System.nanoTime(); 4110 assertSame(f, f.completeOnTimeout(v, timeoutMillis, MILLISECONDS)); 4111 assertSame(v, f.join()); 4112 assertTrue(millisElapsedSince(startTime) >= timeoutMillis); 4113 f.complete(ninetynine); // should have no effect 4114 checkCompletedNormally(f, v); 4115 } 4116 4117 /** 4118 * completeOnTimeout has no effect if completed within timeout 4119 */ 4120 @Test testCompleteOnTimeout_completed()4121 public void testCompleteOnTimeout_completed() { 4122 for (Item v1 : new Item[] { itemOne, null }) 4123 { 4124 CompletableFuture<Item> f = new CompletableFuture<>(); 4125 CompletableFuture<Item> g = new CompletableFuture<>(); 4126 long startTime = System.nanoTime(); 4127 f.complete(v1); 4128 mustEqual(f, f.completeOnTimeout(minusOne, LONG_DELAY_MS, MILLISECONDS)); 4129 mustEqual(g, g.completeOnTimeout(minusOne, LONG_DELAY_MS, MILLISECONDS)); 4130 g.complete(v1); 4131 checkCompletedNormally(f, v1); 4132 checkCompletedNormally(g, v1); 4133 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); 4134 }} 4135 4136 /** 4137 * delayedExecutor returns an executor that delays submission 4138 */ 4139 @Test 4140 public void testDelayedExecutor() { 4141 testInParallel(() -> testDelayedExecutor(null, null), 4142 () -> testDelayedExecutor(null, itemOne), 4143 () -> testDelayedExecutor(new ThreadExecutor(), itemOne), 4144 () -> testDelayedExecutor(new ThreadExecutor(), itemOne)); 4145 } 4146 testDelayedExecutor(Executor executor, Item v)4147 private void testDelayedExecutor(Executor executor, Item v) throws Exception { 4148 long timeoutMillis = timeoutMillis(); 4149 // Use an "unreasonably long" long timeout to catch lingering threads 4150 long longTimeoutMillis = 1000 * 60 * 60 * 24; 4151 final Executor delayer, longDelayer; 4152 if (executor == null) { 4153 delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS); 4154 longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS); 4155 } else { 4156 delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS, executor); 4157 longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS, executor); 4158 } 4159 long startTime = System.nanoTime(); 4160 CompletableFuture<Item> f = 4161 CompletableFuture.supplyAsync(() -> v, delayer); 4162 CompletableFuture<Item> g = 4163 CompletableFuture.supplyAsync(() -> v, longDelayer); 4164 4165 assertNull(g.getNow(null)); 4166 4167 assertSame(v, f.get(LONG_DELAY_MS, MILLISECONDS)); 4168 long millisElapsed = millisElapsedSince(startTime); 4169 assertTrue(millisElapsed >= timeoutMillis); 4170 assertTrue(millisElapsed < LONG_DELAY_MS / 2); 4171 4172 checkCompletedNormally(f, v); 4173 4174 checkIncomplete(g); 4175 assertTrue(g.cancel(true)); 4176 } 4177 4178 //--- tests of implementation details; not part of official tck --- 4179 4180 Object resultOf(CompletableFuture<?> f) { 4181 SecurityManager sm = System.getSecurityManager(); 4182 if (sm != null) { 4183 try { 4184 System.setSecurityManager(null); 4185 } catch (SecurityException giveUp) { 4186 return "Reflection not available"; 4187 } 4188 } 4189 4190 try { 4191 java.lang.reflect.Field resultField 4192 = CompletableFuture.class.getDeclaredField("result"); 4193 resultField.setAccessible(true); 4194 return resultField.get(f); 4195 } catch (Throwable t) { 4196 throw new AssertionError(t); 4197 } finally { 4198 if (sm != null) System.setSecurityManager(sm); 4199 } 4200 } 4201 4202 @Test 4203 public void testExceptionPropagationReusesResultObject() { 4204 if (!testImplementationDetails) return; 4205 for (ExecutionMode m : ExecutionMode.values()) 4206 { 4207 final CFException ex = new CFException(); 4208 final CompletableFuture<Item> v42 = CompletableFuture.completedFuture(fortytwo); 4209 final CompletableFuture<Item> incomplete = new CompletableFuture<>(); 4210 4211 final Runnable noopRunnable = new Noop(m); 4212 final Consumer<Item> noopConsumer = new NoopConsumer(m); 4213 final Function<Item, Item> incFunction = new IncFunction(m); 4214 4215 List<Function<CompletableFuture<Item>, CompletableFuture<?>>> funs 4216 = new ArrayList<>(); 4217 4218 funs.add(y -> m.thenRun(y, noopRunnable)); 4219 funs.add(y -> m.thenAccept(y, noopConsumer)); 4220 funs.add(y -> m.thenApply(y, incFunction)); 4221 4222 funs.add(y -> m.runAfterEither(y, incomplete, noopRunnable)); 4223 funs.add(y -> m.acceptEither(y, incomplete, noopConsumer)); 4224 funs.add(y -> m.applyToEither(y, incomplete, incFunction)); 4225 4226 funs.add(y -> m.runAfterBoth(y, v42, noopRunnable)); 4227 funs.add(y -> m.runAfterBoth(v42, y, noopRunnable)); 4228 funs.add(y -> m.thenAcceptBoth(y, v42, new SubtractAction(m))); 4229 funs.add(y -> m.thenAcceptBoth(v42, y, new SubtractAction(m))); 4230 funs.add(y -> m.thenCombine(y, v42, new SubtractFunction(m))); 4231 funs.add(y -> m.thenCombine(v42, y, new SubtractFunction(m))); 4232 4233 funs.add(y -> m.whenComplete(y, (Item r, Throwable t) -> {})); 4234 4235 funs.add(y -> m.thenCompose(y, new CompletableFutureInc(m))); 4236 4237 funs.add(y -> CompletableFuture.allOf(y)); 4238 funs.add(y -> CompletableFuture.allOf(y, v42)); 4239 funs.add(y -> CompletableFuture.allOf(v42, y)); 4240 funs.add(y -> CompletableFuture.anyOf(y)); 4241 funs.add(y -> CompletableFuture.anyOf(y, incomplete)); 4242 funs.add(y -> CompletableFuture.anyOf(incomplete, y)); 4243 4244 for (Function<CompletableFuture<Item>, CompletableFuture<?>> 4245 fun : funs) { 4246 CompletableFuture<Item> f = new CompletableFuture<>(); 4247 f.completeExceptionally(ex); 4248 CompletableFuture<Item> src = m.thenApply(f, incFunction); 4249 checkCompletedWithWrappedException(src, ex); 4250 CompletableFuture<?> dep = fun.apply(src); 4251 checkCompletedWithWrappedException(dep, ex); 4252 assertSame(resultOf(src), resultOf(dep)); 4253 } 4254 4255 for (Function<CompletableFuture<Item>, CompletableFuture<?>> 4256 fun : funs) { 4257 CompletableFuture<Item> f = new CompletableFuture<>(); 4258 CompletableFuture<Item> src = m.thenApply(f, incFunction); 4259 CompletableFuture<?> dep = fun.apply(src); 4260 f.completeExceptionally(ex); 4261 checkCompletedWithWrappedException(src, ex); 4262 checkCompletedWithWrappedException(dep, ex); 4263 assertSame(resultOf(src), resultOf(dep)); 4264 } 4265 4266 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 4267 for (Function<CompletableFuture<Item>, CompletableFuture<?>> 4268 fun : funs) { 4269 CompletableFuture<Item> f = new CompletableFuture<>(); 4270 f.cancel(mayInterruptIfRunning); 4271 checkCancelled(f); 4272 CompletableFuture<Item> src = m.thenApply(f, incFunction); 4273 checkCompletedWithWrappedCancellationException(src); 4274 CompletableFuture<?> dep = fun.apply(src); 4275 checkCompletedWithWrappedCancellationException(dep); 4276 assertSame(resultOf(src), resultOf(dep)); 4277 } 4278 4279 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 4280 for (Function<CompletableFuture<Item>, CompletableFuture<?>> 4281 fun : funs) { 4282 CompletableFuture<Item> f = new CompletableFuture<>(); 4283 CompletableFuture<Item> src = m.thenApply(f, incFunction); 4284 CompletableFuture<?> dep = fun.apply(src); 4285 f.cancel(mayInterruptIfRunning); 4286 checkCancelled(f); 4287 checkCompletedWithWrappedCancellationException(src); 4288 checkCompletedWithWrappedCancellationException(dep); 4289 assertSame(resultOf(src), resultOf(dep)); 4290 } 4291 }} 4292 4293 /** 4294 * Minimal completion stages throw UOE for most non-CompletionStage methods 4295 */ 4296 @Test testMinimalCompletionStage_minimality()4297 public void testMinimalCompletionStage_minimality() { 4298 if (!testImplementationDetails) return; 4299 Function<Method, String> toSignature = 4300 method -> method.getName() + Arrays.toString(method.getParameterTypes()); 4301 Predicate<Method> isNotStatic = 4302 method -> (method.getModifiers() & Modifier.STATIC) == 0; 4303 List<Method> minimalMethods = 4304 Stream.of(Object.class, CompletionStage.class) 4305 .flatMap(klazz -> Stream.of(klazz.getMethods())) 4306 .filter(isNotStatic) 4307 .collect(Collectors.toList()); 4308 // Methods from CompletableFuture permitted NOT to throw UOE 4309 String[] signatureWhitelist = { 4310 "newIncompleteFuture[]", 4311 "defaultExecutor[]", 4312 "minimalCompletionStage[]", 4313 "copy[]", 4314 }; 4315 Set<String> permittedMethodSignatures = 4316 Stream.concat(minimalMethods.stream().map(toSignature), 4317 Stream.of(signatureWhitelist)) 4318 .collect(Collectors.toSet()); 4319 List<Method> allMethods = Stream.of(CompletableFuture.class.getMethods()) 4320 .filter(isNotStatic) 4321 .filter(method -> !permittedMethodSignatures.contains(toSignature.apply(method))) 4322 .collect(Collectors.toList()); 4323 4324 List<CompletionStage<Item>> stages = new ArrayList<>(); 4325 CompletionStage<Item> min = 4326 new CompletableFuture<Item>().minimalCompletionStage(); 4327 stages.add(min); 4328 stages.add(min.thenApply(x -> x)); 4329 stages.add(CompletableFuture.completedStage(itemOne)); 4330 stages.add(CompletableFuture.failedStage(new CFException())); 4331 4332 List<Method> bugs = new ArrayList<>(); 4333 for (Method method : allMethods) { 4334 Class<?>[] parameterTypes = method.getParameterTypes(); 4335 Object[] args = new Object[parameterTypes.length]; 4336 // Manufacture boxed primitives for primitive params 4337 for (int i = 0; i < args.length; i++) { 4338 Class<?> type = parameterTypes[i]; 4339 if (type == boolean.class) args[i] = false; 4340 else if (type == int.class) args[i] = 0; 4341 else if (type == long.class) args[i] = 0L; 4342 } 4343 for (CompletionStage<Item> stage : stages) { 4344 try { 4345 method.invoke(stage, args); 4346 bugs.add(method); 4347 } 4348 catch (java.lang.reflect.InvocationTargetException expected) { 4349 if (! (expected.getCause() instanceof UnsupportedOperationException)) { 4350 bugs.add(method); 4351 // expected.getCause().printStackTrace(); 4352 } 4353 } 4354 catch (ReflectiveOperationException bad) { throw new Error(bad); } 4355 } 4356 } 4357 if (!bugs.isEmpty()) 4358 throw new Error("Methods did not throw UOE: " + bugs); 4359 } 4360 4361 /** 4362 * minimalStage.toCompletableFuture() returns a CompletableFuture that 4363 * is completed normally, with the same value, when source is. 4364 */ 4365 @Test testMinimalCompletionStage_toCompletableFuture_normalCompletion()4366 public void testMinimalCompletionStage_toCompletableFuture_normalCompletion() { 4367 for (boolean createIncomplete : new boolean[] { true, false }) 4368 for (Item v1 : new Item[] { itemOne, null }) 4369 { 4370 CompletableFuture<Item> f = new CompletableFuture<>(); 4371 CompletionStage<Item> minimal = f.minimalCompletionStage(); 4372 if (!createIncomplete) assertTrue(f.complete(v1)); 4373 CompletableFuture<Item> g = minimal.toCompletableFuture(); 4374 if (createIncomplete) { 4375 checkIncomplete(f); 4376 checkIncomplete(g); 4377 assertTrue(f.complete(v1)); 4378 } 4379 checkCompletedNormally(f, v1); 4380 checkCompletedNormally(g, v1); 4381 }} 4382 4383 /** 4384 * minimalStage.toCompletableFuture() returns a CompletableFuture that 4385 * is completed exceptionally when source is. 4386 */ 4387 @Test testMinimalCompletionStage_toCompletableFuture_exceptionalCompletion()4388 public void testMinimalCompletionStage_toCompletableFuture_exceptionalCompletion() { 4389 for (boolean createIncomplete : new boolean[] { true, false }) 4390 { 4391 CFException ex = new CFException(); 4392 CompletableFuture<Item> f = new CompletableFuture<>(); 4393 CompletionStage<Item> minimal = f.minimalCompletionStage(); 4394 if (!createIncomplete) f.completeExceptionally(ex); 4395 CompletableFuture<Item> g = minimal.toCompletableFuture(); 4396 if (createIncomplete) { 4397 checkIncomplete(f); 4398 checkIncomplete(g); 4399 f.completeExceptionally(ex); 4400 } 4401 checkCompletedExceptionally(f, ex); 4402 checkCompletedWithWrappedException(g, ex); 4403 }} 4404 4405 /** 4406 * minimalStage.toCompletableFuture() gives mutable CompletableFuture 4407 */ 4408 @Test testMinimalCompletionStage_toCompletableFuture_mutable()4409 public void testMinimalCompletionStage_toCompletableFuture_mutable() { 4410 for (Item v1 : new Item[] { itemOne, null }) 4411 { 4412 CompletableFuture<Item> f = new CompletableFuture<>(); 4413 CompletionStage<Item> minimal = f.minimalCompletionStage(); 4414 CompletableFuture<Item> g = minimal.toCompletableFuture(); 4415 assertTrue(g.complete(v1)); 4416 checkCompletedNormally(g, v1); 4417 checkIncomplete(f); 4418 checkIncomplete(minimal.toCompletableFuture()); 4419 }} 4420 4421 /** 4422 * minimalStage.toCompletableFuture().join() awaits completion 4423 */ 4424 @Test testMinimalCompletionStage_toCompletableFuture_join()4425 public void testMinimalCompletionStage_toCompletableFuture_join() throws Exception { 4426 for (boolean createIncomplete : new boolean[] { true, false }) 4427 for (Item v1 : new Item[] { itemOne, null }) 4428 { 4429 CompletableFuture<Item> f = new CompletableFuture<>(); 4430 if (!createIncomplete) assertTrue(f.complete(v1)); 4431 CompletionStage<Item> minimal = f.minimalCompletionStage(); 4432 if (createIncomplete) assertTrue(f.complete(v1)); 4433 mustEqual(v1, minimal.toCompletableFuture().join()); 4434 mustEqual(v1, minimal.toCompletableFuture().get()); 4435 checkCompletedNormally(minimal.toCompletableFuture(), v1); 4436 }} 4437 4438 /** 4439 * Completion of a toCompletableFuture copy of a minimal stage 4440 * does not complete its source. 4441 */ 4442 @Test testMinimalCompletionStage_toCompletableFuture_oneWayPropagation()4443 public void testMinimalCompletionStage_toCompletableFuture_oneWayPropagation() { 4444 CompletableFuture<Item> f = new CompletableFuture<>(); 4445 CompletionStage<Item> g = f.minimalCompletionStage(); 4446 assertTrue(g.toCompletableFuture().complete(itemOne)); 4447 assertTrue(g.toCompletableFuture().complete(null)); 4448 assertTrue(g.toCompletableFuture().cancel(true)); 4449 assertTrue(g.toCompletableFuture().cancel(false)); 4450 assertTrue(g.toCompletableFuture().completeExceptionally(new CFException())); 4451 checkIncomplete(g.toCompletableFuture()); 4452 f.complete(itemOne); 4453 checkCompletedNormally(g.toCompletableFuture(), itemOne); 4454 } 4455 4456 /** Demo utility method for external reliable toCompletableFuture */ toCompletableFuture(CompletionStage<T> stage)4457 static <T> CompletableFuture<T> toCompletableFuture(CompletionStage<T> stage) { 4458 CompletableFuture<T> f = new CompletableFuture<>(); 4459 stage.handle((T t, Throwable ex) -> { 4460 if (ex != null) f.completeExceptionally(ex); 4461 else f.complete(t); 4462 return null; 4463 }); 4464 return f; 4465 } 4466 4467 /** Demo utility method to join a CompletionStage */ join(CompletionStage<T> stage)4468 static <T> T join(CompletionStage<T> stage) { 4469 return toCompletableFuture(stage).join(); 4470 } 4471 4472 /** 4473 * Joining a minimal stage "by hand" works 4474 */ 4475 @Test testMinimalCompletionStage_join_by_hand()4476 public void testMinimalCompletionStage_join_by_hand() { 4477 for (boolean createIncomplete : new boolean[] { true, false }) 4478 for (Item v1 : new Item[] { itemOne, null }) 4479 { 4480 CompletableFuture<Item> f = new CompletableFuture<>(); 4481 CompletionStage<Item> minimal = f.minimalCompletionStage(); 4482 CompletableFuture<Item> g = new CompletableFuture<>(); 4483 if (!createIncomplete) assertTrue(f.complete(v1)); 4484 minimal.thenAccept(x -> g.complete(x)); 4485 if (createIncomplete) assertTrue(f.complete(v1)); 4486 g.join(); 4487 checkCompletedNormally(g, v1); 4488 checkCompletedNormally(f, v1); 4489 mustEqual(v1, join(minimal)); 4490 }} 4491 4492 static class Monad { 4493 static class ZeroException extends RuntimeException { ZeroException()4494 public ZeroException() { super("monadic zero"); } 4495 } 4496 // "return", "unit" unit(T value)4497 static <T> CompletableFuture<T> unit(T value) { 4498 return completedFuture(value); 4499 } 4500 // monadic zero ? zero()4501 static <T> CompletableFuture<T> zero() { 4502 return failedFuture(new ZeroException()); 4503 } 4504 // >=> compose(Function<T, CompletableFuture<U>> f, Function<U, CompletableFuture<V>> g)4505 static <T,U,V> Function<T, CompletableFuture<V>> compose 4506 (Function<T, CompletableFuture<U>> f, 4507 Function<U, CompletableFuture<V>> g) { 4508 return x -> f.apply(x).thenCompose(g); 4509 } 4510 assertZero(CompletableFuture<?> f)4511 static void assertZero(CompletableFuture<?> f) { 4512 try { 4513 f.getNow(null); 4514 throw new AssertionError("should throw"); 4515 } catch (CompletionException success) { 4516 assertTrue(success.getCause() instanceof ZeroException); 4517 } 4518 } 4519 assertFutureEquals(CompletableFuture<T> f, CompletableFuture<T> g)4520 static <T> void assertFutureEquals(CompletableFuture<T> f, 4521 CompletableFuture<T> g) { 4522 T fval = null, gval = null; 4523 Throwable fex = null, gex = null; 4524 4525 try { fval = f.get(); } 4526 catch (ExecutionException ex) { fex = ex.getCause(); } 4527 catch (Throwable ex) { fex = ex; } 4528 4529 try { gval = g.get(); } 4530 catch (ExecutionException ex) { gex = ex.getCause(); } 4531 catch (Throwable ex) { gex = ex; } 4532 4533 if (fex != null || gex != null) 4534 assertSame(fex.getClass(), gex.getClass()); 4535 else 4536 mustEqual(fval, gval); 4537 } 4538 4539 static class PlusFuture<T> extends CompletableFuture<T> { 4540 AtomicReference<Throwable> firstFailure = new AtomicReference<>(null); 4541 } 4542 4543 /** Implements "monadic plus". */ plus(CompletableFuture<? extends T> f, CompletableFuture<? extends T> g)4544 static <T> CompletableFuture<T> plus(CompletableFuture<? extends T> f, 4545 CompletableFuture<? extends T> g) { 4546 PlusFuture<T> plus = new PlusFuture<T>(); 4547 BiConsumer<T, Throwable> action = (T result, Throwable ex) -> { 4548 try { 4549 if (ex == null) { 4550 if (plus.complete(result)) 4551 if (plus.firstFailure.get() != null) 4552 plus.firstFailure.set(null); 4553 } 4554 else if (plus.firstFailure.compareAndSet(null, ex)) { 4555 if (plus.isDone()) 4556 plus.firstFailure.set(null); 4557 } 4558 else { 4559 // first failure has precedence 4560 Throwable first = plus.firstFailure.getAndSet(null); 4561 4562 // may fail with "Self-suppression not permitted" 4563 try { first.addSuppressed(ex); } 4564 catch (Exception ignored) {} 4565 4566 plus.completeExceptionally(first); 4567 } 4568 } catch (Throwable unexpected) { 4569 plus.completeExceptionally(unexpected); 4570 } 4571 }; 4572 f.whenComplete(action); 4573 g.whenComplete(action); 4574 return plus; 4575 } 4576 } 4577 4578 /** 4579 * CompletableFuture is an additive monad - sort of. 4580 * https://en.wikipedia.org/wiki/Monad_(functional_programming)#Additive_monads 4581 */ 4582 @Test testAdditiveMonad()4583 public void testAdditiveMonad() throws Throwable { 4584 Function<Long, CompletableFuture<Long>> unit = Monad::unit; 4585 CompletableFuture<Long> zero = Monad.zero(); 4586 4587 // Some mutually non-commutative functions 4588 Function<Long, CompletableFuture<Long>> triple 4589 = x -> Monad.unit(3 * x); 4590 Function<Long, CompletableFuture<Long>> inc 4591 = x -> Monad.unit(x + 1); 4592 4593 // unit is a right identity: m >>= unit === m 4594 Monad.assertFutureEquals(inc.apply(5L).thenCompose(unit), 4595 inc.apply(5L)); 4596 // unit is a left identity: (unit x) >>= f === f x 4597 Monad.assertFutureEquals(unit.apply(5L).thenCompose(inc), 4598 inc.apply(5L)); 4599 4600 // associativity: (m >>= f) >>= g === m >>= ( \x -> (f x >>= g) ) 4601 Monad.assertFutureEquals( 4602 unit.apply(5L).thenCompose(inc).thenCompose(triple), 4603 unit.apply(5L).thenCompose(x -> inc.apply(x).thenCompose(triple))); 4604 4605 // The case for CompletableFuture as an additive monad is weaker... 4606 4607 // zero is a monadic zero 4608 Monad.assertZero(zero); 4609 4610 // left zero: zero >>= f === zero 4611 Monad.assertZero(zero.thenCompose(inc)); 4612 // right zero: f >>= (\x -> zero) === zero 4613 Monad.assertZero(inc.apply(5L).thenCompose(x -> zero)); 4614 4615 // f plus zero === f 4616 Monad.assertFutureEquals(Monad.unit(5L), 4617 Monad.plus(Monad.unit(5L), zero)); 4618 // zero plus f === f 4619 Monad.assertFutureEquals(Monad.unit(5L), 4620 Monad.plus(zero, Monad.unit(5L))); 4621 // zero plus zero === zero 4622 Monad.assertZero(Monad.plus(zero, zero)); 4623 { 4624 CompletableFuture<Long> f = Monad.plus(Monad.unit(5L), 4625 Monad.unit(8L)); 4626 // non-determinism 4627 assertTrue(f.get() == 5L || f.get() == 8L); 4628 } 4629 4630 CompletableFuture<Long> godot = new CompletableFuture<>(); 4631 // f plus godot === f (doesn't wait for godot) 4632 Monad.assertFutureEquals(Monad.unit(5L), 4633 Monad.plus(Monad.unit(5L), godot)); 4634 // godot plus f === f (doesn't wait for godot) 4635 Monad.assertFutureEquals(Monad.unit(5L), 4636 Monad.plus(godot, Monad.unit(5L))); 4637 } 4638 4639 /** Test long recursive chains of CompletableFutures with cascading completions */ 4640 @SuppressWarnings("FutureReturnValueIgnored") 4641 @Test testRecursiveChains()4642 public void testRecursiveChains() throws Throwable { 4643 for (ExecutionMode m : ExecutionMode.values()) 4644 for (boolean addDeadEnds : new boolean[] { true, false }) 4645 { 4646 final int val = 42; 4647 final int n = expensiveTests ? 1_000 : 2; 4648 CompletableFuture<Item> head = new CompletableFuture<>(); 4649 CompletableFuture<Item> tail = head; 4650 for (int i = 0; i < n; i++) { 4651 if (addDeadEnds) m.thenApply(tail, v -> new Item(v.value + 1)); 4652 tail = m.thenApply(tail, v -> new Item(v.value + 1)); 4653 if (addDeadEnds) m.applyToEither(tail, tail, v -> new Item(v.value + 1)); 4654 tail = m.applyToEither(tail, tail, v -> new Item(v.value + 1)); 4655 if (addDeadEnds) m.thenCombine(tail, tail, (v, w) -> new Item(v.value + 1)); 4656 tail = m.thenCombine(tail, tail, (v, w) -> new Item(v.value + 1)); 4657 } 4658 head.complete(itemFor(val)); 4659 mustEqual(val + 3 * n, tail.join()); 4660 }} 4661 4662 /** 4663 * A single CompletableFuture with many dependents. 4664 * A demo of scalability - runtime is O(n). 4665 */ 4666 @SuppressWarnings("FutureReturnValueIgnored") 4667 @Test testManyDependents()4668 public void testManyDependents() throws Throwable { 4669 final int n = expensiveTests ? 1_000_000 : 10; 4670 final CompletableFuture<Void> head = new CompletableFuture<>(); 4671 final CompletableFuture<Void> complete = CompletableFuture.completedFuture((Void)null); 4672 final AtomicInteger count = new AtomicInteger(0); 4673 for (int i = 0; i < n; i++) { 4674 head.thenRun(() -> count.getAndIncrement()); 4675 head.thenAccept(x -> count.getAndIncrement()); 4676 head.thenApply(x -> count.getAndIncrement()); 4677 4678 head.runAfterBoth(complete, () -> count.getAndIncrement()); 4679 head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement()); 4680 head.thenCombine(complete, (x, y) -> count.getAndIncrement()); 4681 complete.runAfterBoth(head, () -> count.getAndIncrement()); 4682 complete.thenAcceptBoth(head, (x, y) -> count.getAndIncrement()); 4683 complete.thenCombine(head, (x, y) -> count.getAndIncrement()); 4684 4685 head.runAfterEither(new CompletableFuture<Void>(), () -> count.getAndIncrement()); 4686 head.acceptEither(new CompletableFuture<Void>(), x -> count.getAndIncrement()); 4687 head.applyToEither(new CompletableFuture<Void>(), x -> count.getAndIncrement()); 4688 new CompletableFuture<Void>().runAfterEither(head, () -> count.getAndIncrement()); 4689 new CompletableFuture<Void>().acceptEither(head, x -> count.getAndIncrement()); 4690 new CompletableFuture<Void>().applyToEither(head, x -> count.getAndIncrement()); 4691 } 4692 head.complete(null); 4693 mustEqual(5 * 3 * n, count.get()); 4694 } 4695 4696 /** ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest tck */ 4697 @SuppressWarnings("FutureReturnValueIgnored") 4698 @Test testCoCompletionGarbageRetention()4699 public void testCoCompletionGarbageRetention() throws Throwable { 4700 final int n = expensiveTests ? 1_000_000 : 10; 4701 final CompletableFuture<Item> incomplete = new CompletableFuture<>(); 4702 CompletableFuture<Item> f; 4703 for (int i = 0; i < n; i++) { 4704 f = new CompletableFuture<>(); 4705 f.runAfterEither(incomplete, () -> {}); 4706 f.complete(null); 4707 4708 f = new CompletableFuture<>(); 4709 f.acceptEither(incomplete, x -> {}); 4710 f.complete(null); 4711 4712 f = new CompletableFuture<>(); 4713 f.applyToEither(incomplete, x -> x); 4714 f.complete(null); 4715 4716 f = new CompletableFuture<>(); 4717 CompletableFuture.anyOf(f, incomplete); 4718 f.complete(null); 4719 } 4720 4721 for (int i = 0; i < n; i++) { 4722 f = new CompletableFuture<>(); 4723 incomplete.runAfterEither(f, () -> {}); 4724 f.complete(null); 4725 4726 f = new CompletableFuture<>(); 4727 incomplete.acceptEither(f, x -> {}); 4728 f.complete(null); 4729 4730 f = new CompletableFuture<>(); 4731 incomplete.applyToEither(f, x -> x); 4732 f.complete(null); 4733 4734 f = new CompletableFuture<>(); 4735 CompletableFuture.anyOf(incomplete, f); 4736 f.complete(null); 4737 } 4738 } 4739 4740 /** 4741 * Reproduction recipe for: 4742 * 8160402: Garbage retention with CompletableFuture.anyOf 4743 * cvs update -D '2016-05-01' ./src/main/java/util/concurrent/CompletableFuture.java && ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testAnyOfGarbageRetention tck; cvs update -A 4744 */ 4745 @Test testAnyOfGarbageRetention()4746 public void testAnyOfGarbageRetention() throws Throwable { 4747 for (Item v : new Item[] { itemOne, null }) 4748 { 4749 final int n = expensiveTests ? 100_000 : 10; 4750 @SuppressWarnings("unchecked") 4751 CompletableFuture<Item>[] fs = 4752 (CompletableFuture<Item>[])new CompletableFuture[100]; 4753 for (int i = 0; i < fs.length; i++) 4754 fs[i] = new CompletableFuture<>(); 4755 fs[fs.length - 1].complete(v); 4756 for (int i = 0; i < n; i++) 4757 checkCompletedNormally(CompletableFuture.anyOf(fs), v); 4758 }} 4759 4760 /** 4761 * Checks for garbage retention with allOf. 4762 * 4763 * As of 2016-07, fails with OOME: 4764 * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testCancelledAllOfGarbageRetention tck 4765 */ 4766 @Test testCancelledAllOfGarbageRetention()4767 public void testCancelledAllOfGarbageRetention() throws Throwable { 4768 final int n = expensiveTests ? 100_000 : 10; 4769 @SuppressWarnings("unchecked") 4770 CompletableFuture<Item>[] fs 4771 = (CompletableFuture<Item>[]) new CompletableFuture<?>[100]; 4772 for (int i = 0; i < fs.length; i++) 4773 fs[i] = new CompletableFuture<>(); 4774 for (int i = 0; i < n; i++) 4775 assertTrue(CompletableFuture.allOf(fs).cancel(false)); 4776 } 4777 4778 /** 4779 * Checks for garbage retention when a dependent future is 4780 * cancelled and garbage-collected. 4781 * 8161600: Garbage retention when source CompletableFutures are never completed 4782 * 4783 * As of 2016-07, fails with OOME: 4784 * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testCancelledGarbageRetention tck 4785 */ 4786 @Test testCancelledGarbageRetention()4787 public void testCancelledGarbageRetention() throws Throwable { 4788 final int n = expensiveTests ? 100_000 : 10; 4789 CompletableFuture<Item> neverCompleted = new CompletableFuture<>(); 4790 for (int i = 0; i < n; i++) 4791 assertTrue(neverCompleted.thenRun(() -> {}).cancel(true)); 4792 } 4793 4794 /** 4795 * Checks for garbage retention when MinimalStage.toCompletableFuture() 4796 * is invoked many times. 4797 * 8161600: Garbage retention when source CompletableFutures are never completed 4798 * 4799 * As of 2016-07, fails with OOME: 4800 * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testToCompletableFutureGarbageRetention tck 4801 */ 4802 @Test testToCompletableFutureGarbageRetention()4803 public void testToCompletableFutureGarbageRetention() throws Throwable { 4804 final int n = expensiveTests ? 900_000 : 10; 4805 CompletableFuture<Item> neverCompleted = new CompletableFuture<>(); 4806 CompletionStage<Item> minimal = neverCompleted.minimalCompletionStage(); 4807 for (int i = 0; i < n; i++) 4808 assertTrue(minimal.toCompletableFuture().cancel(true)); 4809 } 4810 4811 // static <U> U join(CompletionStage<U> stage) { 4812 // CompletableFuture<U> f = new CompletableFuture<>(); 4813 // stage.whenComplete((v, ex) -> { 4814 // if (ex != null) f.completeExceptionally(ex); else f.complete(v); 4815 // }); 4816 // return f.join(); 4817 // } 4818 4819 // static <U> boolean isDone(CompletionStage<U> stage) { 4820 // CompletableFuture<U> f = new CompletableFuture<>(); 4821 // stage.whenComplete((v, ex) -> { 4822 // if (ex != null) f.completeExceptionally(ex); else f.complete(v); 4823 // }); 4824 // return f.isDone(); 4825 // } 4826 4827 // static <U> U join2(CompletionStage<U> stage) { 4828 // return stage.toCompletableFuture().copy().join(); 4829 // } 4830 4831 // static <U> boolean isDone2(CompletionStage<U> stage) { 4832 // return stage.toCompletableFuture().copy().isDone(); 4833 // } 4834 4835 // For testing default implementations 4836 // Only non-default interface methods defined. 4837 static final class DelegatedCompletionStage<T> implements CompletionStage<T> { 4838 final CompletableFuture<T> cf; DelegatedCompletionStage(CompletableFuture<T> cf)4839 DelegatedCompletionStage(CompletableFuture<T> cf) { this.cf = cf; } toCompletableFuture()4840 public CompletableFuture<T> toCompletableFuture() { 4841 return cf; } thenRun(Runnable action)4842 public CompletionStage<Void> thenRun 4843 (Runnable action) { 4844 return cf.thenRun(action); } thenRunAsync(Runnable action)4845 public CompletionStage<Void> thenRunAsync 4846 (Runnable action) { 4847 return cf.thenRunAsync(action); } thenRunAsync(Runnable action, Executor executor)4848 public CompletionStage<Void> thenRunAsync 4849 (Runnable action, 4850 Executor executor) { 4851 return cf.thenRunAsync(action, executor); } thenAccept(Consumer<? super T> action)4852 public CompletionStage<Void> thenAccept 4853 (Consumer<? super T> action) { 4854 return cf.thenAccept(action); } thenAcceptAsync(Consumer<? super T> action)4855 public CompletionStage<Void> thenAcceptAsync 4856 (Consumer<? super T> action) { 4857 return cf.thenAcceptAsync(action); } thenAcceptAsync(Consumer<? super T> action, Executor executor)4858 public CompletionStage<Void> thenAcceptAsync 4859 (Consumer<? super T> action, 4860 Executor executor) { 4861 return cf.thenAcceptAsync(action, executor); } thenApply(Function<? super T,? extends U> a)4862 public <U> CompletionStage<U> thenApply 4863 (Function<? super T,? extends U> a) { 4864 return cf.thenApply(a); } thenApplyAsync(Function<? super T,? extends U> fn)4865 public <U> CompletionStage<U> thenApplyAsync 4866 (Function<? super T,? extends U> fn) { 4867 return cf.thenApplyAsync(fn); } thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)4868 public <U> CompletionStage<U> thenApplyAsync 4869 (Function<? super T,? extends U> fn, 4870 Executor executor) { 4871 return cf.thenApplyAsync(fn, executor); } thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)4872 public <U,V> CompletionStage<V> thenCombine 4873 (CompletionStage<? extends U> other, 4874 BiFunction<? super T,? super U,? extends V> fn) { 4875 return cf.thenCombine(other, fn); } thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)4876 public <U,V> CompletionStage<V> thenCombineAsync 4877 (CompletionStage<? extends U> other, 4878 BiFunction<? super T,? super U,? extends V> fn) { 4879 return cf.thenCombineAsync(other, fn); } thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor)4880 public <U,V> CompletionStage<V> thenCombineAsync 4881 (CompletionStage<? extends U> other, 4882 BiFunction<? super T,? super U,? extends V> fn, 4883 Executor executor) { 4884 return cf.thenCombineAsync(other, fn, executor); } thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)4885 public <U> CompletionStage<Void> thenAcceptBoth 4886 (CompletionStage<? extends U> other, 4887 BiConsumer<? super T, ? super U> action) { 4888 return cf.thenAcceptBoth(other, action); } thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)4889 public <U> CompletionStage<Void> thenAcceptBothAsync 4890 (CompletionStage<? extends U> other, 4891 BiConsumer<? super T, ? super U> action) { 4892 return cf.thenAcceptBothAsync(other, action); } thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor)4893 public <U> CompletionStage<Void> thenAcceptBothAsync 4894 (CompletionStage<? extends U> other, 4895 BiConsumer<? super T, ? super U> action, 4896 Executor executor) { 4897 return cf.thenAcceptBothAsync(other, action, executor); } runAfterBoth(CompletionStage<?> other, Runnable action)4898 public CompletionStage<Void> runAfterBoth 4899 (CompletionStage<?> other, 4900 Runnable action) { 4901 return cf.runAfterBoth(other, action); } runAfterBothAsync(CompletionStage<?> other, Runnable action)4902 public CompletionStage<Void> runAfterBothAsync 4903 (CompletionStage<?> other, 4904 Runnable action) { 4905 return cf.runAfterBothAsync(other, action); } runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor)4906 public CompletionStage<Void> runAfterBothAsync 4907 (CompletionStage<?> other, 4908 Runnable action, 4909 Executor executor) { 4910 return cf.runAfterBothAsync(other, action, executor); } applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn)4911 public <U> CompletionStage<U> applyToEither 4912 (CompletionStage<? extends T> other, 4913 Function<? super T, U> fn) { 4914 return cf.applyToEither(other, fn); } applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn)4915 public <U> CompletionStage<U> applyToEitherAsync 4916 (CompletionStage<? extends T> other, 4917 Function<? super T, U> fn) { 4918 return cf.applyToEitherAsync(other, fn); } applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor)4919 public <U> CompletionStage<U> applyToEitherAsync 4920 (CompletionStage<? extends T> other, 4921 Function<? super T, U> fn, 4922 Executor executor) { 4923 return cf.applyToEitherAsync(other, fn, executor); } acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)4924 public CompletionStage<Void> acceptEither 4925 (CompletionStage<? extends T> other, 4926 Consumer<? super T> action) { 4927 return cf.acceptEither(other, action); } acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action)4928 public CompletionStage<Void> acceptEitherAsync 4929 (CompletionStage<? extends T> other, 4930 Consumer<? super T> action) { 4931 return cf.acceptEitherAsync(other, action); } acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor)4932 public CompletionStage<Void> acceptEitherAsync 4933 (CompletionStage<? extends T> other, 4934 Consumer<? super T> action, 4935 Executor executor) { 4936 return cf.acceptEitherAsync(other, action, executor); } runAfterEither(CompletionStage<?> other, Runnable action)4937 public CompletionStage<Void> runAfterEither 4938 (CompletionStage<?> other, 4939 Runnable action) { 4940 return cf.runAfterEither(other, action); } runAfterEitherAsync(CompletionStage<?> other, Runnable action)4941 public CompletionStage<Void> runAfterEitherAsync 4942 (CompletionStage<?> other, 4943 Runnable action) { 4944 return cf.runAfterEitherAsync(other, action); } runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor)4945 public CompletionStage<Void> runAfterEitherAsync 4946 (CompletionStage<?> other, 4947 Runnable action, 4948 Executor executor) { 4949 return cf.runAfterEitherAsync(other, action, executor); } thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)4950 public <U> CompletionStage<U> thenCompose 4951 (Function<? super T, ? extends CompletionStage<U>> fn) { 4952 return cf.thenCompose(fn); } thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn)4953 public <U> CompletionStage<U> thenComposeAsync 4954 (Function<? super T, ? extends CompletionStage<U>> fn) { 4955 return cf.thenComposeAsync(fn); } thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor)4956 public <U> CompletionStage<U> thenComposeAsync 4957 (Function<? super T, ? extends CompletionStage<U>> fn, 4958 Executor executor) { 4959 return cf.thenComposeAsync(fn, executor); } handle(BiFunction<? super T, Throwable, ? extends U> fn)4960 public <U> CompletionStage<U> handle 4961 (BiFunction<? super T, Throwable, ? extends U> fn) { 4962 return cf.handle(fn); } handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)4963 public <U> CompletionStage<U> handleAsync 4964 (BiFunction<? super T, Throwable, ? extends U> fn) { 4965 return cf.handleAsync(fn); } handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)4966 public <U> CompletionStage<U> handleAsync 4967 (BiFunction<? super T, Throwable, ? extends U> fn, 4968 Executor executor) { 4969 return cf.handleAsync(fn, executor); } whenComplete(BiConsumer<? super T, ? super Throwable> action)4970 public CompletionStage<T> whenComplete 4971 (BiConsumer<? super T, ? super Throwable> action) { 4972 return cf.whenComplete(action); } whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)4973 public CompletionStage<T> whenCompleteAsync 4974 (BiConsumer<? super T, ? super Throwable> action) { 4975 return cf.whenCompleteAsync(action); } whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)4976 public CompletionStage<T> whenCompleteAsync 4977 (BiConsumer<? super T, ? super Throwable> action, 4978 Executor executor) { 4979 return cf.whenCompleteAsync(action, executor); } exceptionally(Function<Throwable, ? extends T> fn)4980 public CompletionStage<T> exceptionally 4981 (Function<Throwable, ? extends T> fn) { 4982 return cf.exceptionally(fn); } 4983 } 4984 4985 /** 4986 * default-implemented exceptionallyAsync action is not invoked when 4987 * source completes normally, and source result is propagated 4988 */ 4989 @Test testDefaultExceptionallyAsync_normalCompletion()4990 public void testDefaultExceptionallyAsync_normalCompletion() { 4991 for (boolean createIncomplete : new boolean[] { true, false }) 4992 for (Item v1 : new Item[] { itemOne, null }) 4993 { 4994 final AtomicInteger ran = new AtomicInteger(0); 4995 final CompletableFuture<Item> f = new CompletableFuture<>(); 4996 final DelegatedCompletionStage<Item> d = 4997 new DelegatedCompletionStage<>(f); 4998 if (!createIncomplete) assertTrue(f.complete(v1)); 4999 final CompletionStage<Item> g = d.exceptionallyAsync 5000 ((Throwable t) -> { 5001 ran.getAndIncrement(); 5002 throw new AssertionError("should not be called"); 5003 }); 5004 if (createIncomplete) assertTrue(f.complete(v1)); 5005 5006 checkCompletedNormally(g.toCompletableFuture(), v1); 5007 checkCompletedNormally(f, v1); 5008 mustEqual(0, ran.get()); 5009 }} 5010 5011 /** 5012 * default-implemented exceptionallyAsync action completes with 5013 * function value on source exception 5014 */ 5015 @Test testDefaultExceptionallyAsync_exceptionalCompletion()5016 public void testDefaultExceptionallyAsync_exceptionalCompletion() { 5017 for (boolean createIncomplete : new boolean[] { true, false }) 5018 for (Item v1 : new Item[] { itemOne, null }) 5019 { 5020 final AtomicInteger ran = new AtomicInteger(0); 5021 final CFException ex = new CFException(); 5022 final CompletableFuture<Item> f = new CompletableFuture<>(); 5023 final DelegatedCompletionStage<Item> d = 5024 new DelegatedCompletionStage<>(f); 5025 if (!createIncomplete) f.completeExceptionally(ex); 5026 final CompletionStage<Item> g = d.exceptionallyAsync 5027 ((Throwable t) -> { 5028 assertSame(t, ex); 5029 ran.getAndIncrement(); 5030 return v1; 5031 }); 5032 if (createIncomplete) f.completeExceptionally(ex); 5033 5034 checkCompletedNormally(g.toCompletableFuture(), v1); 5035 checkCompletedExceptionally(f, ex); 5036 mustEqual(1, ran.get()); 5037 }} 5038 5039 /** 5040 * Under default implementation, if an "exceptionally action" 5041 * throws an exception, it completes exceptionally with that 5042 * exception 5043 */ 5044 @Test testDefaultExceptionallyAsync_exceptionalCompletionActionFailed()5045 public void testDefaultExceptionallyAsync_exceptionalCompletionActionFailed() { 5046 for (boolean createIncomplete : new boolean[] { true, false }) 5047 { 5048 final AtomicInteger ran = new AtomicInteger(0); 5049 final CFException ex1 = new CFException(); 5050 final CFException ex2 = new CFException(); 5051 final CompletableFuture<Item> f = new CompletableFuture<>(); 5052 final DelegatedCompletionStage<Item> d = 5053 new DelegatedCompletionStage<>(f); 5054 if (!createIncomplete) f.completeExceptionally(ex1); 5055 final CompletionStage<Item> g = d.exceptionallyAsync 5056 ((Throwable t) -> { 5057 assertSame(t, ex1); 5058 ran.getAndIncrement(); 5059 throw ex2; 5060 }); 5061 if (createIncomplete) f.completeExceptionally(ex1); 5062 5063 checkCompletedWithWrappedException(g.toCompletableFuture(), ex2); 5064 checkCompletedExceptionally(f, ex1); 5065 checkCompletedExceptionally(d.toCompletableFuture(), ex1); 5066 mustEqual(1, ran.get()); 5067 }} 5068 5069 /** 5070 * default-implemented exceptionallyCompose result completes 5071 * normally after normal completion of source 5072 */ 5073 @Test testDefaultExceptionallyCompose_normalCompletion()5074 public void testDefaultExceptionallyCompose_normalCompletion() { 5075 for (boolean createIncomplete : new boolean[] { true, false }) 5076 for (Item v1 : new Item[] { itemOne, null }) 5077 { 5078 final CompletableFuture<Item> f = new CompletableFuture<>(); 5079 final ExceptionalCompletableFutureFunction r = 5080 new ExceptionalCompletableFutureFunction(ExecutionMode.SYNC); 5081 final DelegatedCompletionStage<Item> d = 5082 new DelegatedCompletionStage<>(f); 5083 if (!createIncomplete) assertTrue(f.complete(v1)); 5084 final CompletionStage<Item> g = d.exceptionallyCompose(r); 5085 if (createIncomplete) assertTrue(f.complete(v1)); 5086 5087 checkCompletedNormally(f, v1); 5088 checkCompletedNormally(g.toCompletableFuture(), v1); 5089 r.assertNotInvoked(); 5090 }} 5091 5092 /** 5093 * default-implemented exceptionallyCompose result completes 5094 * normally after exceptional completion of source 5095 */ 5096 @Test testDefaultExceptionallyCompose_exceptionalCompletion()5097 public void testDefaultExceptionallyCompose_exceptionalCompletion() { 5098 for (boolean createIncomplete : new boolean[] { true, false }) 5099 { 5100 final CFException ex = new CFException(); 5101 final ExceptionalCompletableFutureFunction r = 5102 new ExceptionalCompletableFutureFunction(ExecutionMode.SYNC); 5103 final CompletableFuture<Item> f = new CompletableFuture<>(); 5104 final DelegatedCompletionStage<Item> d = 5105 new DelegatedCompletionStage<>(f); 5106 if (!createIncomplete) f.completeExceptionally(ex); 5107 final CompletionStage<Item> g = d.exceptionallyCompose(r); 5108 if (createIncomplete) f.completeExceptionally(ex); 5109 5110 checkCompletedExceptionally(f, ex); 5111 checkCompletedNormally(g.toCompletableFuture(), r.value); 5112 r.assertInvoked(); 5113 }} 5114 5115 /** 5116 * default-implemented exceptionallyCompose completes 5117 * exceptionally on exception if action does 5118 */ 5119 @Test testDefaultExceptionallyCompose_actionFailed()5120 public void testDefaultExceptionallyCompose_actionFailed() { 5121 for (boolean createIncomplete : new boolean[] { true, false }) 5122 { 5123 final CFException ex = new CFException(); 5124 final CompletableFuture<Item> f = new CompletableFuture<>(); 5125 final FailingExceptionalCompletableFutureFunction r 5126 = new FailingExceptionalCompletableFutureFunction(ExecutionMode.SYNC); 5127 final DelegatedCompletionStage<Item> d = 5128 new DelegatedCompletionStage<>(f); 5129 if (!createIncomplete) f.completeExceptionally(ex); 5130 final CompletionStage<Item> g = d.exceptionallyCompose(r); 5131 if (createIncomplete) f.completeExceptionally(ex); 5132 5133 checkCompletedExceptionally(f, ex); 5134 checkCompletedWithWrappedException(g.toCompletableFuture(), r.ex); 5135 r.assertInvoked(); 5136 }} 5137 5138 /** 5139 * default-implemented exceptionallyComposeAsync result completes 5140 * normally after normal completion of source 5141 */ 5142 @Test testDefaultExceptionallyComposeAsync_normalCompletion()5143 public void testDefaultExceptionallyComposeAsync_normalCompletion() { 5144 for (boolean createIncomplete : new boolean[] { true, false }) 5145 for (Item v1 : new Item[] { itemOne, null }) 5146 { 5147 final CompletableFuture<Item> f = new CompletableFuture<>(); 5148 final ExceptionalCompletableFutureFunction r = 5149 new ExceptionalCompletableFutureFunction(ExecutionMode.ASYNC); 5150 final DelegatedCompletionStage<Item> d = 5151 new DelegatedCompletionStage<>(f); 5152 if (!createIncomplete) assertTrue(f.complete(v1)); 5153 final CompletionStage<Item> g = d.exceptionallyComposeAsync(r); 5154 if (createIncomplete) assertTrue(f.complete(v1)); 5155 5156 checkCompletedNormally(f, v1); 5157 checkCompletedNormally(g.toCompletableFuture(), v1); 5158 r.assertNotInvoked(); 5159 }} 5160 5161 /** 5162 * default-implemented exceptionallyComposeAsync result completes 5163 * normally after exceptional completion of source 5164 */ 5165 @Test testDefaultExceptionallyComposeAsync_exceptionalCompletion()5166 public void testDefaultExceptionallyComposeAsync_exceptionalCompletion() { 5167 for (boolean createIncomplete : new boolean[] { true, false }) 5168 { 5169 final CFException ex = new CFException(); 5170 final ExceptionalCompletableFutureFunction r = 5171 new ExceptionalCompletableFutureFunction(ExecutionMode.ASYNC); 5172 final CompletableFuture<Item> f = new CompletableFuture<>(); 5173 final DelegatedCompletionStage<Item> d = 5174 new DelegatedCompletionStage<>(f); 5175 if (!createIncomplete) f.completeExceptionally(ex); 5176 final CompletionStage<Item> g = d.exceptionallyComposeAsync(r); 5177 if (createIncomplete) f.completeExceptionally(ex); 5178 5179 checkCompletedExceptionally(f, ex); 5180 checkCompletedNormally(g.toCompletableFuture(), r.value); 5181 r.assertInvoked(); 5182 }} 5183 5184 /** 5185 * default-implemented exceptionallyComposeAsync completes 5186 * exceptionally on exception if action does 5187 */ 5188 @Test testDefaultExceptionallyComposeAsync_actionFailed()5189 public void testDefaultExceptionallyComposeAsync_actionFailed() { 5190 for (boolean createIncomplete : new boolean[] { true, false }) 5191 { 5192 final CFException ex = new CFException(); 5193 final CompletableFuture<Item> f = new CompletableFuture<>(); 5194 final FailingExceptionalCompletableFutureFunction r 5195 = new FailingExceptionalCompletableFutureFunction(ExecutionMode.ASYNC); 5196 final DelegatedCompletionStage<Item> d = 5197 new DelegatedCompletionStage<>(f); 5198 if (!createIncomplete) f.completeExceptionally(ex); 5199 final CompletionStage<Item> g = d.exceptionallyComposeAsync(r); 5200 if (createIncomplete) f.completeExceptionally(ex); 5201 5202 checkCompletedExceptionally(f, ex); 5203 checkCompletedWithWrappedException(g.toCompletableFuture(), r.ex); 5204 r.assertInvoked(); 5205 }} 5206 5207 /** 5208 * default-implemented exceptionallyComposeAsync result completes 5209 * normally after normal completion of source 5210 */ 5211 @Test testDefaultExceptionallyComposeAsyncExecutor_normalCompletion()5212 public void testDefaultExceptionallyComposeAsyncExecutor_normalCompletion() { 5213 for (boolean createIncomplete : new boolean[] { true, false }) 5214 for (Item v1 : new Item[] { itemOne, null }) 5215 { 5216 final CompletableFuture<Item> f = new CompletableFuture<>(); 5217 final ExceptionalCompletableFutureFunction r = 5218 new ExceptionalCompletableFutureFunction(ExecutionMode.EXECUTOR); 5219 final DelegatedCompletionStage<Item> d = 5220 new DelegatedCompletionStage<>(f); 5221 if (!createIncomplete) assertTrue(f.complete(v1)); 5222 final CompletionStage<Item> g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); 5223 if (createIncomplete) assertTrue(f.complete(v1)); 5224 5225 checkCompletedNormally(f, v1); 5226 checkCompletedNormally(g.toCompletableFuture(), v1); 5227 r.assertNotInvoked(); 5228 }} 5229 5230 /** 5231 * default-implemented exceptionallyComposeAsync result completes 5232 * normally after exceptional completion of source 5233 */ 5234 @Test testDefaultExceptionallyComposeAsyncExecutor_exceptionalCompletion()5235 public void testDefaultExceptionallyComposeAsyncExecutor_exceptionalCompletion() { 5236 for (boolean createIncomplete : new boolean[] { true, false }) 5237 { 5238 final CFException ex = new CFException(); 5239 final ExceptionalCompletableFutureFunction r = 5240 new ExceptionalCompletableFutureFunction(ExecutionMode.EXECUTOR); 5241 final CompletableFuture<Item> f = new CompletableFuture<>(); 5242 final DelegatedCompletionStage<Item> d = 5243 new DelegatedCompletionStage<>(f); 5244 if (!createIncomplete) f.completeExceptionally(ex); 5245 final CompletionStage<Item> g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); 5246 if (createIncomplete) f.completeExceptionally(ex); 5247 5248 checkCompletedExceptionally(f, ex); 5249 checkCompletedNormally(g.toCompletableFuture(), r.value); 5250 r.assertInvoked(); 5251 }} 5252 5253 /** 5254 * default-implemented exceptionallyComposeAsync completes 5255 * exceptionally on exception if action does 5256 */ 5257 @Test testDefaultExceptionallyComposeAsyncExecutor_actionFailed()5258 public void testDefaultExceptionallyComposeAsyncExecutor_actionFailed() { 5259 for (boolean createIncomplete : new boolean[] { true, false }) 5260 { 5261 final CFException ex = new CFException(); 5262 final CompletableFuture<Item> f = new CompletableFuture<>(); 5263 final FailingExceptionalCompletableFutureFunction r 5264 = new FailingExceptionalCompletableFutureFunction(ExecutionMode.EXECUTOR); 5265 final DelegatedCompletionStage<Item> d = 5266 new DelegatedCompletionStage<>(f); 5267 if (!createIncomplete) f.completeExceptionally(ex); 5268 final CompletionStage<Item> g = d.exceptionallyComposeAsync(r, new ThreadExecutor()); 5269 if (createIncomplete) f.completeExceptionally(ex); 5270 5271 checkCompletedExceptionally(f, ex); 5272 checkCompletedWithWrappedException(g.toCompletableFuture(), r.ex); 5273 r.assertInvoked(); 5274 }} 5275 5276 } 5277