1 /* 2 * Written by Doug Lea and Martin Buchholz with assistance from 3 * members of JCP JSR-166 Expert Group and released to the public 4 * domain, as explained at 5 * http://creativecommons.org/publicdomain/zero/1.0/ 6 */ 7 8 package jsr166; 9 10 import static java.util.concurrent.TimeUnit.MILLISECONDS; 11 import static java.util.concurrent.TimeUnit.SECONDS; 12 import static java.util.concurrent.CompletableFuture.completedFuture; 13 import static java.util.concurrent.CompletableFuture.failedFuture; 14 15 import java.lang.reflect.Method; 16 import java.lang.reflect.Modifier; 17 18 import java.util.stream.Collectors; 19 import java.util.stream.Stream; 20 21 import java.util.ArrayList; 22 import java.util.Arrays; 23 import java.util.List; 24 import java.util.Objects; 25 import java.util.Set; 26 import java.util.concurrent.Callable; 27 import java.util.concurrent.CancellationException; 28 import java.util.concurrent.CompletableFuture; 29 import java.util.concurrent.CompletionException; 30 import java.util.concurrent.CompletionStage; 31 import java.util.concurrent.ExecutionException; 32 import java.util.concurrent.Executor; 33 import java.util.concurrent.ForkJoinPool; 34 import java.util.concurrent.ForkJoinTask; 35 import java.util.concurrent.TimeoutException; 36 import java.util.concurrent.TimeUnit; 37 import java.util.concurrent.atomic.AtomicInteger; 38 import java.util.concurrent.atomic.AtomicReference; 39 import java.util.function.BiConsumer; 40 import java.util.function.BiFunction; 41 import java.util.function.Consumer; 42 import java.util.function.Function; 43 import java.util.function.Predicate; 44 import java.util.function.Supplier; 45 46 import junit.framework.AssertionFailedError; 47 import junit.framework.Test; 48 import junit.framework.TestSuite; 49 50 public class CompletableFutureTest extends JSR166TestCase { 51 52 // android-note: Removed because the CTS runner does a bad job of 53 // retrying tests that have suite() declarations. 54 // 55 // public static void main(String[] args) { 56 // main(suite(), args); 57 // } 58 // public static Test suite() { 59 // return new TestSuite(CompletableFutureTest.class); 60 // } 61 62 static class CFException extends RuntimeException {} 63 checkIncomplete(CompletableFuture<?> f)64 void checkIncomplete(CompletableFuture<?> f) { 65 assertFalse(f.isDone()); 66 assertFalse(f.isCancelled()); 67 assertTrue(f.toString().contains("Not completed")); 68 try { 69 assertNull(f.getNow(null)); 70 } catch (Throwable fail) { threadUnexpectedException(fail); } 71 try { 72 f.get(0L, SECONDS); 73 shouldThrow(); 74 } 75 catch (TimeoutException success) {} 76 catch (Throwable fail) { threadUnexpectedException(fail); } 77 } 78 checkCompletedNormally(CompletableFuture<T> f, T value)79 <T> void checkCompletedNormally(CompletableFuture<T> f, T value) { 80 checkTimedGet(f, value); 81 82 try { 83 assertEquals(value, f.join()); 84 } catch (Throwable fail) { threadUnexpectedException(fail); } 85 try { 86 assertEquals(value, f.getNow(null)); 87 } catch (Throwable fail) { threadUnexpectedException(fail); } 88 try { 89 assertEquals(value, f.get()); 90 } catch (Throwable fail) { threadUnexpectedException(fail); } 91 assertTrue(f.isDone()); 92 assertFalse(f.isCancelled()); 93 assertFalse(f.isCompletedExceptionally()); 94 assertTrue(f.toString().contains("[Completed normally]")); 95 } 96 97 /** 98 * Returns the "raw" internal exceptional completion of f, 99 * without any additional wrapping with CompletionException. 100 */ exceptionalCompletion(CompletableFuture<U> f)101 <U> Throwable exceptionalCompletion(CompletableFuture<U> f) { 102 // handle (and whenComplete) can distinguish between "direct" 103 // and "wrapped" exceptional completion 104 return f.handle((U u, Throwable t) -> t).join(); 105 } 106 checkCompletedExceptionally(CompletableFuture<?> f, boolean wrapped, Consumer<Throwable> checker)107 void checkCompletedExceptionally(CompletableFuture<?> f, 108 boolean wrapped, 109 Consumer<Throwable> checker) { 110 Throwable cause = exceptionalCompletion(f); 111 if (wrapped) { 112 assertTrue(cause instanceof CompletionException); 113 cause = cause.getCause(); 114 } 115 checker.accept(cause); 116 117 long startTime = System.nanoTime(); 118 try { 119 f.get(LONG_DELAY_MS, MILLISECONDS); 120 shouldThrow(); 121 } catch (ExecutionException success) { 122 assertSame(cause, success.getCause()); 123 } catch (Throwable fail) { threadUnexpectedException(fail); } 124 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); 125 126 try { 127 f.join(); 128 shouldThrow(); 129 } catch (CompletionException success) { 130 assertSame(cause, success.getCause()); 131 } catch (Throwable fail) { threadUnexpectedException(fail); } 132 133 try { 134 f.getNow(null); 135 shouldThrow(); 136 } catch (CompletionException success) { 137 assertSame(cause, success.getCause()); 138 } catch (Throwable fail) { threadUnexpectedException(fail); } 139 140 try { 141 f.get(); 142 shouldThrow(); 143 } catch (ExecutionException success) { 144 assertSame(cause, success.getCause()); 145 } catch (Throwable fail) { threadUnexpectedException(fail); } 146 147 assertFalse(f.isCancelled()); 148 assertTrue(f.isDone()); 149 assertTrue(f.isCompletedExceptionally()); 150 assertTrue(f.toString().contains("[Completed exceptionally]")); 151 } 152 153 void checkCompletedWithWrappedCFException(CompletableFuture<?> f) { 154 checkCompletedExceptionally(f, true, 155 (t) -> assertTrue(t instanceof CFException)); 156 } 157 checkCompletedWithWrappedCancellationException(CompletableFuture<?> f)158 void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) { 159 checkCompletedExceptionally(f, true, 160 (t) -> assertTrue(t instanceof CancellationException)); 161 } 162 checkCompletedWithTimeoutException(CompletableFuture<?> f)163 void checkCompletedWithTimeoutException(CompletableFuture<?> f) { 164 checkCompletedExceptionally(f, false, 165 (t) -> assertTrue(t instanceof TimeoutException)); 166 } 167 checkCompletedWithWrappedException(CompletableFuture<?> f, Throwable ex)168 void checkCompletedWithWrappedException(CompletableFuture<?> f, 169 Throwable ex) { 170 checkCompletedExceptionally(f, true, (t) -> assertSame(t, ex)); 171 } 172 checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex)173 void checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex) { 174 checkCompletedExceptionally(f, false, (t) -> assertSame(t, ex)); 175 } 176 checkCancelled(CompletableFuture<?> f)177 void checkCancelled(CompletableFuture<?> f) { 178 long startTime = System.nanoTime(); 179 try { 180 f.get(LONG_DELAY_MS, MILLISECONDS); 181 shouldThrow(); 182 } catch (CancellationException success) { 183 } catch (Throwable fail) { threadUnexpectedException(fail); } 184 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); 185 186 try { 187 f.join(); 188 shouldThrow(); 189 } catch (CancellationException success) {} 190 try { 191 f.getNow(null); 192 shouldThrow(); 193 } catch (CancellationException success) {} 194 try { 195 f.get(); 196 shouldThrow(); 197 } catch (CancellationException success) { 198 } catch (Throwable fail) { threadUnexpectedException(fail); } 199 200 assertTrue(exceptionalCompletion(f) instanceof CancellationException); 201 202 assertTrue(f.isDone()); 203 assertTrue(f.isCompletedExceptionally()); 204 assertTrue(f.isCancelled()); 205 assertTrue(f.toString().contains("[Completed exceptionally]")); 206 } 207 208 /** 209 * A newly constructed CompletableFuture is incomplete, as indicated 210 * by methods isDone, isCancelled, and getNow 211 */ 212 public void testConstructor() { 213 CompletableFuture<Integer> f = new CompletableFuture<>(); 214 checkIncomplete(f); 215 } 216 217 /** 218 * complete completes normally, as indicated by methods isDone, 219 * isCancelled, join, get, and getNow 220 */ 221 public void testComplete() { 222 for (Integer v1 : new Integer[] { 1, null }) 223 { 224 CompletableFuture<Integer> f = new CompletableFuture<>(); 225 checkIncomplete(f); 226 assertTrue(f.complete(v1)); 227 assertFalse(f.complete(v1)); 228 checkCompletedNormally(f, v1); 229 }} 230 231 /** 232 * completeExceptionally completes exceptionally, as indicated by 233 * methods isDone, isCancelled, join, get, and getNow 234 */ 235 public void testCompleteExceptionally() { 236 CompletableFuture<Integer> f = new CompletableFuture<>(); 237 CFException ex = new CFException(); 238 checkIncomplete(f); 239 f.completeExceptionally(ex); 240 checkCompletedExceptionally(f, ex); 241 } 242 243 /** 244 * cancel completes exceptionally and reports cancelled, as indicated by 245 * methods isDone, isCancelled, join, get, and getNow 246 */ 247 public void testCancel() { 248 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 249 { 250 CompletableFuture<Integer> f = new CompletableFuture<>(); 251 checkIncomplete(f); 252 assertTrue(f.cancel(mayInterruptIfRunning)); 253 assertTrue(f.cancel(mayInterruptIfRunning)); 254 assertTrue(f.cancel(!mayInterruptIfRunning)); 255 checkCancelled(f); 256 }} 257 258 /** 259 * obtrudeValue forces completion with given value 260 */ 261 public void testObtrudeValue() { 262 CompletableFuture<Integer> f = new CompletableFuture<>(); 263 checkIncomplete(f); 264 assertTrue(f.complete(one)); 265 checkCompletedNormally(f, one); 266 f.obtrudeValue(three); 267 checkCompletedNormally(f, three); 268 f.obtrudeValue(two); 269 checkCompletedNormally(f, two); 270 f = new CompletableFuture<>(); 271 f.obtrudeValue(three); 272 checkCompletedNormally(f, three); 273 f.obtrudeValue(null); 274 checkCompletedNormally(f, null); 275 f = new CompletableFuture<>(); 276 f.completeExceptionally(new CFException()); 277 f.obtrudeValue(four); 278 checkCompletedNormally(f, four); 279 } 280 281 /** 282 * obtrudeException forces completion with given exception 283 */ 284 public void testObtrudeException() { 285 for (Integer v1 : new Integer[] { 1, null }) 286 { 287 CFException ex; 288 CompletableFuture<Integer> f; 289 290 f = new CompletableFuture<>(); 291 assertTrue(f.complete(v1)); 292 for (int i = 0; i < 2; i++) { 293 f.obtrudeException(ex = new CFException()); 294 checkCompletedExceptionally(f, ex); 295 } 296 297 f = new CompletableFuture<>(); 298 for (int i = 0; i < 2; i++) { 299 f.obtrudeException(ex = new CFException()); 300 checkCompletedExceptionally(f, ex); 301 } 302 303 f = new CompletableFuture<>(); 304 f.completeExceptionally(ex = new CFException()); 305 f.obtrudeValue(v1); 306 checkCompletedNormally(f, v1); 307 f.obtrudeException(ex = new CFException()); 308 checkCompletedExceptionally(f, ex); 309 f.completeExceptionally(new CFException()); 310 checkCompletedExceptionally(f, ex); 311 assertFalse(f.complete(v1)); 312 checkCompletedExceptionally(f, ex); 313 }} 314 315 /** 316 * getNumberOfDependents returns number of dependent tasks 317 */ 318 public void testGetNumberOfDependents() { 319 for (ExecutionMode m : ExecutionMode.values()) 320 for (Integer v1 : new Integer[] { 1, null }) 321 { 322 CompletableFuture<Integer> f = new CompletableFuture<>(); 323 assertEquals(0, f.getNumberOfDependents()); 324 final CompletableFuture<Void> g = m.thenRun(f, new Noop(m)); 325 assertEquals(1, f.getNumberOfDependents()); 326 assertEquals(0, g.getNumberOfDependents()); 327 final CompletableFuture<Void> h = m.thenRun(f, new Noop(m)); 328 assertEquals(2, f.getNumberOfDependents()); 329 assertEquals(0, h.getNumberOfDependents()); 330 assertTrue(f.complete(v1)); 331 checkCompletedNormally(g, null); 332 checkCompletedNormally(h, null); 333 assertEquals(0, f.getNumberOfDependents()); 334 assertEquals(0, g.getNumberOfDependents()); 335 assertEquals(0, h.getNumberOfDependents()); 336 }} 337 338 /** 339 * toString indicates current completion state 340 */ 341 public void testToString() { 342 CompletableFuture<String> f; 343 344 f = new CompletableFuture<String>(); 345 assertTrue(f.toString().contains("[Not completed]")); 346 347 assertTrue(f.complete("foo")); 348 assertTrue(f.toString().contains("[Completed normally]")); 349 350 f = new CompletableFuture<String>(); 351 assertTrue(f.completeExceptionally(new IndexOutOfBoundsException())); 352 assertTrue(f.toString().contains("[Completed exceptionally]")); 353 354 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) { 355 f = new CompletableFuture<String>(); 356 assertTrue(f.cancel(mayInterruptIfRunning)); 357 assertTrue(f.toString().contains("[Completed exceptionally]")); 358 } 359 } 360 361 /** 362 * completedFuture returns a completed CompletableFuture with given value 363 */ 364 public void testCompletedFuture() { 365 CompletableFuture<String> f = CompletableFuture.completedFuture("test"); 366 checkCompletedNormally(f, "test"); 367 } 368 369 abstract class CheckedAction { 370 int invocationCount = 0; 371 final ExecutionMode m; 372 CheckedAction(ExecutionMode m) { this.m = m; } 373 void invoked() { 374 m.checkExecutionMode(); 375 assertEquals(0, invocationCount++); 376 } 377 void assertNotInvoked() { assertEquals(0, invocationCount); } 378 void assertInvoked() { assertEquals(1, invocationCount); } 379 } 380 381 abstract class CheckedIntegerAction extends CheckedAction { 382 Integer value; 383 CheckedIntegerAction(ExecutionMode m) { super(m); } 384 void assertValue(Integer expected) { 385 assertInvoked(); 386 assertEquals(expected, value); 387 } 388 } 389 390 class IntegerSupplier extends CheckedAction 391 implements Supplier<Integer> 392 { 393 final Integer value; 394 IntegerSupplier(ExecutionMode m, Integer value) { 395 super(m); 396 this.value = value; 397 } 398 public Integer get() { 399 invoked(); 400 return value; 401 } 402 } 403 404 // A function that handles and produces null values as well. 405 static Integer inc(Integer x) { 406 return (x == null) ? null : x + 1; 407 } 408 409 class NoopConsumer extends CheckedIntegerAction 410 implements Consumer<Integer> 411 { 412 NoopConsumer(ExecutionMode m) { super(m); } 413 public void accept(Integer x) { 414 invoked(); 415 value = x; 416 } 417 } 418 419 class IncFunction extends CheckedIntegerAction 420 implements Function<Integer,Integer> 421 { 422 IncFunction(ExecutionMode m) { super(m); } 423 public Integer apply(Integer x) { 424 invoked(); 425 return value = inc(x); 426 } 427 } 428 429 // Choose non-commutative actions for better coverage 430 // A non-commutative function that handles and produces null values as well. 431 static Integer subtract(Integer x, Integer y) { 432 return (x == null && y == null) ? null : 433 ((x == null) ? 42 : x.intValue()) 434 - ((y == null) ? 99 : y.intValue()); 435 } 436 437 class SubtractAction extends CheckedIntegerAction 438 implements BiConsumer<Integer, Integer> 439 { 440 SubtractAction(ExecutionMode m) { super(m); } 441 public void accept(Integer x, Integer y) { 442 invoked(); 443 value = subtract(x, y); 444 } 445 } 446 447 class SubtractFunction extends CheckedIntegerAction 448 implements BiFunction<Integer, Integer, Integer> 449 { 450 SubtractFunction(ExecutionMode m) { super(m); } 451 public Integer apply(Integer x, Integer y) { 452 invoked(); 453 return value = subtract(x, y); 454 } 455 } 456 457 class Noop extends CheckedAction implements Runnable { 458 Noop(ExecutionMode m) { super(m); } 459 public void run() { 460 invoked(); 461 } 462 } 463 464 class FailingSupplier extends CheckedAction 465 implements Supplier<Integer> 466 { 467 FailingSupplier(ExecutionMode m) { super(m); } 468 public Integer get() { 469 invoked(); 470 throw new CFException(); 471 } 472 } 473 474 class FailingConsumer extends CheckedIntegerAction 475 implements Consumer<Integer> 476 { 477 FailingConsumer(ExecutionMode m) { super(m); } 478 public void accept(Integer x) { 479 invoked(); 480 value = x; 481 throw new CFException(); 482 } 483 } 484 485 class FailingBiConsumer extends CheckedIntegerAction 486 implements BiConsumer<Integer, Integer> 487 { 488 FailingBiConsumer(ExecutionMode m) { super(m); } 489 public void accept(Integer x, Integer y) { 490 invoked(); 491 value = subtract(x, y); 492 throw new CFException(); 493 } 494 } 495 496 class FailingFunction extends CheckedIntegerAction 497 implements Function<Integer, Integer> 498 { 499 FailingFunction(ExecutionMode m) { super(m); } 500 public Integer apply(Integer x) { 501 invoked(); 502 value = x; 503 throw new CFException(); 504 } 505 } 506 507 class FailingBiFunction extends CheckedIntegerAction 508 implements BiFunction<Integer, Integer, Integer> 509 { 510 FailingBiFunction(ExecutionMode m) { super(m); } 511 public Integer apply(Integer x, Integer y) { 512 invoked(); 513 value = subtract(x, y); 514 throw new CFException(); 515 } 516 } 517 518 class FailingRunnable extends CheckedAction implements Runnable { 519 FailingRunnable(ExecutionMode m) { super(m); } 520 public void run() { 521 invoked(); 522 throw new CFException(); 523 } 524 } 525 526 class CompletableFutureInc extends CheckedIntegerAction 527 implements Function<Integer, CompletableFuture<Integer>> 528 { 529 CompletableFutureInc(ExecutionMode m) { super(m); } 530 public CompletableFuture<Integer> apply(Integer x) { 531 invoked(); 532 value = x; 533 CompletableFuture<Integer> f = new CompletableFuture<>(); 534 assertTrue(f.complete(inc(x))); 535 return f; 536 } 537 } 538 539 class FailingCompletableFutureFunction extends CheckedIntegerAction 540 implements Function<Integer, CompletableFuture<Integer>> 541 { 542 FailingCompletableFutureFunction(ExecutionMode m) { super(m); } 543 public CompletableFuture<Integer> apply(Integer x) { 544 invoked(); 545 value = x; 546 throw new CFException(); 547 } 548 } 549 550 // Used for explicit executor tests 551 static final class ThreadExecutor implements Executor { 552 final AtomicInteger count = new AtomicInteger(0); 553 static final ThreadGroup tg = new ThreadGroup("ThreadExecutor"); 554 static boolean startedCurrentThread() { 555 return Thread.currentThread().getThreadGroup() == tg; 556 } 557 558 public void execute(Runnable r) { 559 count.getAndIncrement(); 560 new Thread(tg, r).start(); 561 } 562 } 563 564 static final boolean defaultExecutorIsCommonPool 565 = ForkJoinPool.getCommonPoolParallelism() > 1; 566 567 /** 568 * Permits the testing of parallel code for the 3 different 569 * execution modes without copy/pasting all the test methods. 570 */ 571 enum ExecutionMode { 572 SYNC { 573 public void checkExecutionMode() { 574 assertFalse(ThreadExecutor.startedCurrentThread()); 575 assertNull(ForkJoinTask.getPool()); 576 } 577 public CompletableFuture<Void> runAsync(Runnable a) { 578 throw new UnsupportedOperationException(); 579 } 580 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) { 581 throw new UnsupportedOperationException(); 582 } 583 public <T> CompletableFuture<Void> thenRun 584 (CompletableFuture<T> f, Runnable a) { 585 return f.thenRun(a); 586 } 587 public <T> CompletableFuture<Void> thenAccept 588 (CompletableFuture<T> f, Consumer<? super T> a) { 589 return f.thenAccept(a); 590 } 591 public <T,U> CompletableFuture<U> thenApply 592 (CompletableFuture<T> f, Function<? super T,U> a) { 593 return f.thenApply(a); 594 } 595 public <T,U> CompletableFuture<U> thenCompose 596 (CompletableFuture<T> f, 597 Function<? super T,? extends CompletionStage<U>> a) { 598 return f.thenCompose(a); 599 } 600 public <T,U> CompletableFuture<U> handle 601 (CompletableFuture<T> f, 602 BiFunction<? super T,Throwable,? extends U> a) { 603 return f.handle(a); 604 } 605 public <T> CompletableFuture<T> whenComplete 606 (CompletableFuture<T> f, 607 BiConsumer<? super T,? super Throwable> a) { 608 return f.whenComplete(a); 609 } 610 public <T,U> CompletableFuture<Void> runAfterBoth 611 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) { 612 return f.runAfterBoth(g, a); 613 } 614 public <T,U> CompletableFuture<Void> thenAcceptBoth 615 (CompletableFuture<T> f, 616 CompletionStage<? extends U> g, 617 BiConsumer<? super T,? super U> a) { 618 return f.thenAcceptBoth(g, a); 619 } 620 public <T,U,V> CompletableFuture<V> thenCombine 621 (CompletableFuture<T> f, 622 CompletionStage<? extends U> g, 623 BiFunction<? super T,? super U,? extends V> a) { 624 return f.thenCombine(g, a); 625 } 626 public <T> CompletableFuture<Void> runAfterEither 627 (CompletableFuture<T> f, 628 CompletionStage<?> g, 629 java.lang.Runnable a) { 630 return f.runAfterEither(g, a); 631 } 632 public <T> CompletableFuture<Void> acceptEither 633 (CompletableFuture<T> f, 634 CompletionStage<? extends T> g, 635 Consumer<? super T> a) { 636 return f.acceptEither(g, a); 637 } 638 public <T,U> CompletableFuture<U> applyToEither 639 (CompletableFuture<T> f, 640 CompletionStage<? extends T> g, 641 Function<? super T,U> a) { 642 return f.applyToEither(g, a); 643 } 644 }, 645 646 ASYNC { 647 public void checkExecutionMode() { 648 assertEquals(defaultExecutorIsCommonPool, 649 (ForkJoinPool.commonPool() == ForkJoinTask.getPool())); 650 } 651 public CompletableFuture<Void> runAsync(Runnable a) { 652 return CompletableFuture.runAsync(a); 653 } 654 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) { 655 return CompletableFuture.supplyAsync(a); 656 } 657 public <T> CompletableFuture<Void> thenRun 658 (CompletableFuture<T> f, Runnable a) { 659 return f.thenRunAsync(a); 660 } 661 public <T> CompletableFuture<Void> thenAccept 662 (CompletableFuture<T> f, Consumer<? super T> a) { 663 return f.thenAcceptAsync(a); 664 } 665 public <T,U> CompletableFuture<U> thenApply 666 (CompletableFuture<T> f, Function<? super T,U> a) { 667 return f.thenApplyAsync(a); 668 } 669 public <T,U> CompletableFuture<U> thenCompose 670 (CompletableFuture<T> f, 671 Function<? super T,? extends CompletionStage<U>> a) { 672 return f.thenComposeAsync(a); 673 } 674 public <T,U> CompletableFuture<U> handle 675 (CompletableFuture<T> f, 676 BiFunction<? super T,Throwable,? extends U> a) { 677 return f.handleAsync(a); 678 } 679 public <T> CompletableFuture<T> whenComplete 680 (CompletableFuture<T> f, 681 BiConsumer<? super T,? super Throwable> a) { 682 return f.whenCompleteAsync(a); 683 } 684 public <T,U> CompletableFuture<Void> runAfterBoth 685 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) { 686 return f.runAfterBothAsync(g, a); 687 } 688 public <T,U> CompletableFuture<Void> thenAcceptBoth 689 (CompletableFuture<T> f, 690 CompletionStage<? extends U> g, 691 BiConsumer<? super T,? super U> a) { 692 return f.thenAcceptBothAsync(g, a); 693 } 694 public <T,U,V> CompletableFuture<V> thenCombine 695 (CompletableFuture<T> f, 696 CompletionStage<? extends U> g, 697 BiFunction<? super T,? super U,? extends V> a) { 698 return f.thenCombineAsync(g, a); 699 } 700 public <T> CompletableFuture<Void> runAfterEither 701 (CompletableFuture<T> f, 702 CompletionStage<?> g, 703 java.lang.Runnable a) { 704 return f.runAfterEitherAsync(g, a); 705 } 706 public <T> CompletableFuture<Void> acceptEither 707 (CompletableFuture<T> f, 708 CompletionStage<? extends T> g, 709 Consumer<? super T> a) { 710 return f.acceptEitherAsync(g, a); 711 } 712 public <T,U> CompletableFuture<U> applyToEither 713 (CompletableFuture<T> f, 714 CompletionStage<? extends T> g, 715 Function<? super T,U> a) { 716 return f.applyToEitherAsync(g, a); 717 } 718 }, 719 720 EXECUTOR { 721 public void checkExecutionMode() { 722 assertTrue(ThreadExecutor.startedCurrentThread()); 723 } 724 public CompletableFuture<Void> runAsync(Runnable a) { 725 return CompletableFuture.runAsync(a, new ThreadExecutor()); 726 } 727 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) { 728 return CompletableFuture.supplyAsync(a, new ThreadExecutor()); 729 } 730 public <T> CompletableFuture<Void> thenRun 731 (CompletableFuture<T> f, Runnable a) { 732 return f.thenRunAsync(a, new ThreadExecutor()); 733 } 734 public <T> CompletableFuture<Void> thenAccept 735 (CompletableFuture<T> f, Consumer<? super T> a) { 736 return f.thenAcceptAsync(a, new ThreadExecutor()); 737 } 738 public <T,U> CompletableFuture<U> thenApply 739 (CompletableFuture<T> f, Function<? super T,U> a) { 740 return f.thenApplyAsync(a, new ThreadExecutor()); 741 } 742 public <T,U> CompletableFuture<U> thenCompose 743 (CompletableFuture<T> f, 744 Function<? super T,? extends CompletionStage<U>> a) { 745 return f.thenComposeAsync(a, new ThreadExecutor()); 746 } 747 public <T,U> CompletableFuture<U> handle 748 (CompletableFuture<T> f, 749 BiFunction<? super T,Throwable,? extends U> a) { 750 return f.handleAsync(a, new ThreadExecutor()); 751 } 752 public <T> CompletableFuture<T> whenComplete 753 (CompletableFuture<T> f, 754 BiConsumer<? super T,? super Throwable> a) { 755 return f.whenCompleteAsync(a, new ThreadExecutor()); 756 } 757 public <T,U> CompletableFuture<Void> runAfterBoth 758 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) { 759 return f.runAfterBothAsync(g, a, new ThreadExecutor()); 760 } 761 public <T,U> CompletableFuture<Void> thenAcceptBoth 762 (CompletableFuture<T> f, 763 CompletionStage<? extends U> g, 764 BiConsumer<? super T,? super U> a) { 765 return f.thenAcceptBothAsync(g, a, new ThreadExecutor()); 766 } 767 public <T,U,V> CompletableFuture<V> thenCombine 768 (CompletableFuture<T> f, 769 CompletionStage<? extends U> g, 770 BiFunction<? super T,? super U,? extends V> a) { 771 return f.thenCombineAsync(g, a, new ThreadExecutor()); 772 } 773 public <T> CompletableFuture<Void> runAfterEither 774 (CompletableFuture<T> f, 775 CompletionStage<?> g, 776 java.lang.Runnable a) { 777 return f.runAfterEitherAsync(g, a, new ThreadExecutor()); 778 } 779 public <T> CompletableFuture<Void> acceptEither 780 (CompletableFuture<T> f, 781 CompletionStage<? extends T> g, 782 Consumer<? super T> a) { 783 return f.acceptEitherAsync(g, a, new ThreadExecutor()); 784 } 785 public <T,U> CompletableFuture<U> applyToEither 786 (CompletableFuture<T> f, 787 CompletionStage<? extends T> g, 788 Function<? super T,U> a) { 789 return f.applyToEitherAsync(g, a, new ThreadExecutor()); 790 } 791 }; 792 793 public abstract void checkExecutionMode(); 794 public abstract CompletableFuture<Void> runAsync(Runnable a); 795 public abstract <U> CompletableFuture<U> supplyAsync(Supplier<U> a); 796 public abstract <T> CompletableFuture<Void> thenRun 797 (CompletableFuture<T> f, Runnable a); 798 public abstract <T> CompletableFuture<Void> thenAccept 799 (CompletableFuture<T> f, Consumer<? super T> a); 800 public abstract <T,U> CompletableFuture<U> thenApply 801 (CompletableFuture<T> f, Function<? super T,U> a); 802 public abstract <T,U> CompletableFuture<U> thenCompose 803 (CompletableFuture<T> f, 804 Function<? super T,? extends CompletionStage<U>> a); 805 public abstract <T,U> CompletableFuture<U> handle 806 (CompletableFuture<T> f, 807 BiFunction<? super T,Throwable,? extends U> a); 808 public abstract <T> CompletableFuture<T> whenComplete 809 (CompletableFuture<T> f, 810 BiConsumer<? super T,? super Throwable> a); 811 public abstract <T,U> CompletableFuture<Void> runAfterBoth 812 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a); 813 public abstract <T,U> CompletableFuture<Void> thenAcceptBoth 814 (CompletableFuture<T> f, 815 CompletionStage<? extends U> g, 816 BiConsumer<? super T,? super U> a); 817 public abstract <T,U,V> CompletableFuture<V> thenCombine 818 (CompletableFuture<T> f, 819 CompletionStage<? extends U> g, 820 BiFunction<? super T,? super U,? extends V> a); 821 public abstract <T> CompletableFuture<Void> runAfterEither 822 (CompletableFuture<T> f, 823 CompletionStage<?> g, 824 java.lang.Runnable a); 825 public abstract <T> CompletableFuture<Void> acceptEither 826 (CompletableFuture<T> f, 827 CompletionStage<? extends T> g, 828 Consumer<? super T> a); 829 public abstract <T,U> CompletableFuture<U> applyToEither 830 (CompletableFuture<T> f, 831 CompletionStage<? extends T> g, 832 Function<? super T,U> a); 833 } 834 835 /** 836 * exceptionally action is not invoked when source completes 837 * normally, and source result is propagated 838 */ 839 public void testExceptionally_normalCompletion() { 840 for (boolean createIncomplete : new boolean[] { true, false }) 841 for (Integer v1 : new Integer[] { 1, null }) 842 { 843 final AtomicInteger a = new AtomicInteger(0); 844 final CompletableFuture<Integer> f = new CompletableFuture<>(); 845 if (!createIncomplete) assertTrue(f.complete(v1)); 846 final CompletableFuture<Integer> g = f.exceptionally 847 ((Throwable t) -> { 848 a.getAndIncrement(); 849 threadFail("should not be called"); 850 return null; // unreached 851 }); 852 if (createIncomplete) assertTrue(f.complete(v1)); 853 854 checkCompletedNormally(g, v1); 855 checkCompletedNormally(f, v1); 856 assertEquals(0, a.get()); 857 }} 858 859 /** 860 * exceptionally action completes with function value on source 861 * exception 862 */ 863 public void testExceptionally_exceptionalCompletion() { 864 for (boolean createIncomplete : new boolean[] { true, false }) 865 for (Integer v1 : new Integer[] { 1, null }) 866 { 867 final AtomicInteger a = new AtomicInteger(0); 868 final CFException ex = new CFException(); 869 final CompletableFuture<Integer> f = new CompletableFuture<>(); 870 if (!createIncomplete) f.completeExceptionally(ex); 871 final CompletableFuture<Integer> g = f.exceptionally 872 ((Throwable t) -> { 873 ExecutionMode.SYNC.checkExecutionMode(); 874 threadAssertSame(t, ex); 875 a.getAndIncrement(); 876 return v1; 877 }); 878 if (createIncomplete) f.completeExceptionally(ex); 879 880 checkCompletedNormally(g, v1); 881 assertEquals(1, a.get()); 882 }} 883 884 /** 885 * If an "exceptionally action" throws an exception, it completes 886 * exceptionally with that exception 887 */ testExceptionally_exceptionalCompletionActionFailed()888 public void testExceptionally_exceptionalCompletionActionFailed() { 889 for (boolean createIncomplete : new boolean[] { true, false }) 890 { 891 final AtomicInteger a = new AtomicInteger(0); 892 final CFException ex1 = new CFException(); 893 final CFException ex2 = new CFException(); 894 final CompletableFuture<Integer> f = new CompletableFuture<>(); 895 if (!createIncomplete) f.completeExceptionally(ex1); 896 final CompletableFuture<Integer> g = f.exceptionally 897 ((Throwable t) -> { 898 ExecutionMode.SYNC.checkExecutionMode(); 899 threadAssertSame(t, ex1); 900 a.getAndIncrement(); 901 throw ex2; 902 }); 903 if (createIncomplete) f.completeExceptionally(ex1); 904 905 checkCompletedWithWrappedException(g, ex2); 906 checkCompletedExceptionally(f, ex1); 907 assertEquals(1, a.get()); 908 }} 909 910 /** 911 * whenComplete action executes on normal completion, propagating 912 * source result. 913 */ testWhenComplete_normalCompletion()914 public void testWhenComplete_normalCompletion() { 915 for (ExecutionMode m : ExecutionMode.values()) 916 for (boolean createIncomplete : new boolean[] { true, false }) 917 for (Integer v1 : new Integer[] { 1, null }) 918 { 919 final AtomicInteger a = new AtomicInteger(0); 920 final CompletableFuture<Integer> f = new CompletableFuture<>(); 921 if (!createIncomplete) assertTrue(f.complete(v1)); 922 final CompletableFuture<Integer> g = m.whenComplete 923 (f, 924 (Integer result, Throwable t) -> { 925 m.checkExecutionMode(); 926 threadAssertSame(result, v1); 927 threadAssertNull(t); 928 a.getAndIncrement(); 929 }); 930 if (createIncomplete) assertTrue(f.complete(v1)); 931 932 checkCompletedNormally(g, v1); 933 checkCompletedNormally(f, v1); 934 assertEquals(1, a.get()); 935 }} 936 937 /** 938 * whenComplete action executes on exceptional completion, propagating 939 * source result. 940 */ testWhenComplete_exceptionalCompletion()941 public void testWhenComplete_exceptionalCompletion() { 942 for (ExecutionMode m : ExecutionMode.values()) 943 for (boolean createIncomplete : new boolean[] { true, false }) 944 { 945 final AtomicInteger a = new AtomicInteger(0); 946 final CFException ex = new CFException(); 947 final CompletableFuture<Integer> f = new CompletableFuture<>(); 948 if (!createIncomplete) f.completeExceptionally(ex); 949 final CompletableFuture<Integer> g = m.whenComplete 950 (f, 951 (Integer result, Throwable t) -> { 952 m.checkExecutionMode(); 953 threadAssertNull(result); 954 threadAssertSame(t, ex); 955 a.getAndIncrement(); 956 }); 957 if (createIncomplete) f.completeExceptionally(ex); 958 959 checkCompletedWithWrappedException(g, ex); 960 checkCompletedExceptionally(f, ex); 961 assertEquals(1, a.get()); 962 }} 963 964 /** 965 * whenComplete action executes on cancelled source, propagating 966 * CancellationException. 967 */ testWhenComplete_sourceCancelled()968 public void testWhenComplete_sourceCancelled() { 969 for (ExecutionMode m : ExecutionMode.values()) 970 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 971 for (boolean createIncomplete : new boolean[] { true, false }) 972 { 973 final AtomicInteger a = new AtomicInteger(0); 974 final CompletableFuture<Integer> f = new CompletableFuture<>(); 975 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 976 final CompletableFuture<Integer> g = m.whenComplete 977 (f, 978 (Integer result, Throwable t) -> { 979 m.checkExecutionMode(); 980 threadAssertNull(result); 981 threadAssertTrue(t instanceof CancellationException); 982 a.getAndIncrement(); 983 }); 984 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 985 986 checkCompletedWithWrappedCancellationException(g); 987 checkCancelled(f); 988 assertEquals(1, a.get()); 989 }} 990 991 /** 992 * If a whenComplete action throws an exception when triggered by 993 * a normal completion, it completes exceptionally 994 */ testWhenComplete_sourceCompletedNormallyActionFailed()995 public void testWhenComplete_sourceCompletedNormallyActionFailed() { 996 for (boolean createIncomplete : new boolean[] { true, false }) 997 for (ExecutionMode m : ExecutionMode.values()) 998 for (Integer v1 : new Integer[] { 1, null }) 999 { 1000 final AtomicInteger a = new AtomicInteger(0); 1001 final CFException ex = new CFException(); 1002 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1003 if (!createIncomplete) assertTrue(f.complete(v1)); 1004 final CompletableFuture<Integer> g = m.whenComplete 1005 (f, 1006 (Integer result, Throwable t) -> { 1007 m.checkExecutionMode(); 1008 threadAssertSame(result, v1); 1009 threadAssertNull(t); 1010 a.getAndIncrement(); 1011 throw ex; 1012 }); 1013 if (createIncomplete) assertTrue(f.complete(v1)); 1014 1015 checkCompletedWithWrappedException(g, ex); 1016 checkCompletedNormally(f, v1); 1017 assertEquals(1, a.get()); 1018 }} 1019 1020 /** 1021 * If a whenComplete action throws an exception when triggered by 1022 * a source completion that also throws an exception, the source 1023 * exception takes precedence (unlike handle) 1024 */ testWhenComplete_sourceFailedActionFailed()1025 public void testWhenComplete_sourceFailedActionFailed() { 1026 for (boolean createIncomplete : new boolean[] { true, false }) 1027 for (ExecutionMode m : ExecutionMode.values()) 1028 { 1029 final AtomicInteger a = new AtomicInteger(0); 1030 final CFException ex1 = new CFException(); 1031 final CFException ex2 = new CFException(); 1032 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1033 1034 if (!createIncomplete) f.completeExceptionally(ex1); 1035 final CompletableFuture<Integer> g = m.whenComplete 1036 (f, 1037 (Integer result, Throwable t) -> { 1038 m.checkExecutionMode(); 1039 threadAssertSame(t, ex1); 1040 threadAssertNull(result); 1041 a.getAndIncrement(); 1042 throw ex2; 1043 }); 1044 if (createIncomplete) f.completeExceptionally(ex1); 1045 1046 checkCompletedWithWrappedException(g, ex1); 1047 checkCompletedExceptionally(f, ex1); 1048 if (testImplementationDetails) { 1049 assertEquals(1, ex1.getSuppressed().length); 1050 assertSame(ex2, ex1.getSuppressed()[0]); 1051 } 1052 assertEquals(1, a.get()); 1053 }} 1054 1055 /** 1056 * handle action completes normally with function value on normal 1057 * completion of source 1058 */ testHandle_normalCompletion()1059 public void testHandle_normalCompletion() { 1060 for (ExecutionMode m : ExecutionMode.values()) 1061 for (boolean createIncomplete : new boolean[] { true, false }) 1062 for (Integer v1 : new Integer[] { 1, null }) 1063 { 1064 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1065 final AtomicInteger a = new AtomicInteger(0); 1066 if (!createIncomplete) assertTrue(f.complete(v1)); 1067 final CompletableFuture<Integer> g = m.handle 1068 (f, 1069 (Integer result, Throwable t) -> { 1070 m.checkExecutionMode(); 1071 threadAssertSame(result, v1); 1072 threadAssertNull(t); 1073 a.getAndIncrement(); 1074 return inc(v1); 1075 }); 1076 if (createIncomplete) assertTrue(f.complete(v1)); 1077 1078 checkCompletedNormally(g, inc(v1)); 1079 checkCompletedNormally(f, v1); 1080 assertEquals(1, a.get()); 1081 }} 1082 1083 /** 1084 * handle action completes normally with function value on 1085 * exceptional completion of source 1086 */ testHandle_exceptionalCompletion()1087 public void testHandle_exceptionalCompletion() { 1088 for (ExecutionMode m : ExecutionMode.values()) 1089 for (boolean createIncomplete : new boolean[] { true, false }) 1090 for (Integer v1 : new Integer[] { 1, null }) 1091 { 1092 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1093 final AtomicInteger a = new AtomicInteger(0); 1094 final CFException ex = new CFException(); 1095 if (!createIncomplete) f.completeExceptionally(ex); 1096 final CompletableFuture<Integer> g = m.handle 1097 (f, 1098 (Integer result, Throwable t) -> { 1099 m.checkExecutionMode(); 1100 threadAssertNull(result); 1101 threadAssertSame(t, ex); 1102 a.getAndIncrement(); 1103 return v1; 1104 }); 1105 if (createIncomplete) f.completeExceptionally(ex); 1106 1107 checkCompletedNormally(g, v1); 1108 checkCompletedExceptionally(f, ex); 1109 assertEquals(1, a.get()); 1110 }} 1111 1112 /** 1113 * handle action completes normally with function value on 1114 * cancelled source 1115 */ testHandle_sourceCancelled()1116 public void testHandle_sourceCancelled() { 1117 for (ExecutionMode m : ExecutionMode.values()) 1118 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1119 for (boolean createIncomplete : new boolean[] { true, false }) 1120 for (Integer v1 : new Integer[] { 1, null }) 1121 { 1122 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1123 final AtomicInteger a = new AtomicInteger(0); 1124 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 1125 final CompletableFuture<Integer> g = m.handle 1126 (f, 1127 (Integer result, Throwable t) -> { 1128 m.checkExecutionMode(); 1129 threadAssertNull(result); 1130 threadAssertTrue(t instanceof CancellationException); 1131 a.getAndIncrement(); 1132 return v1; 1133 }); 1134 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 1135 1136 checkCompletedNormally(g, v1); 1137 checkCancelled(f); 1138 assertEquals(1, a.get()); 1139 }} 1140 1141 /** 1142 * If a "handle action" throws an exception when triggered by 1143 * a normal completion, it completes exceptionally 1144 */ testHandle_sourceCompletedNormallyActionFailed()1145 public void testHandle_sourceCompletedNormallyActionFailed() { 1146 for (ExecutionMode m : ExecutionMode.values()) 1147 for (boolean createIncomplete : new boolean[] { true, false }) 1148 for (Integer v1 : new Integer[] { 1, null }) 1149 { 1150 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1151 final AtomicInteger a = new AtomicInteger(0); 1152 final CFException ex = new CFException(); 1153 if (!createIncomplete) assertTrue(f.complete(v1)); 1154 final CompletableFuture<Integer> g = m.handle 1155 (f, 1156 (Integer result, Throwable t) -> { 1157 m.checkExecutionMode(); 1158 threadAssertSame(result, v1); 1159 threadAssertNull(t); 1160 a.getAndIncrement(); 1161 throw ex; 1162 }); 1163 if (createIncomplete) assertTrue(f.complete(v1)); 1164 1165 checkCompletedWithWrappedException(g, ex); 1166 checkCompletedNormally(f, v1); 1167 assertEquals(1, a.get()); 1168 }} 1169 1170 /** 1171 * If a "handle action" throws an exception when triggered by 1172 * a source completion that also throws an exception, the action 1173 * exception takes precedence (unlike whenComplete) 1174 */ testHandle_sourceFailedActionFailed()1175 public void testHandle_sourceFailedActionFailed() { 1176 for (boolean createIncomplete : new boolean[] { true, false }) 1177 for (ExecutionMode m : ExecutionMode.values()) 1178 { 1179 final AtomicInteger a = new AtomicInteger(0); 1180 final CFException ex1 = new CFException(); 1181 final CFException ex2 = new CFException(); 1182 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1183 1184 if (!createIncomplete) f.completeExceptionally(ex1); 1185 final CompletableFuture<Integer> g = m.handle 1186 (f, 1187 (Integer result, Throwable t) -> { 1188 m.checkExecutionMode(); 1189 threadAssertNull(result); 1190 threadAssertSame(ex1, t); 1191 a.getAndIncrement(); 1192 throw ex2; 1193 }); 1194 if (createIncomplete) f.completeExceptionally(ex1); 1195 1196 checkCompletedWithWrappedException(g, ex2); 1197 checkCompletedExceptionally(f, ex1); 1198 assertEquals(1, a.get()); 1199 }} 1200 1201 /** 1202 * runAsync completes after running Runnable 1203 */ testRunAsync_normalCompletion()1204 public void testRunAsync_normalCompletion() { 1205 ExecutionMode[] executionModes = { 1206 ExecutionMode.ASYNC, 1207 ExecutionMode.EXECUTOR, 1208 }; 1209 for (ExecutionMode m : executionModes) 1210 { 1211 final Noop r = new Noop(m); 1212 final CompletableFuture<Void> f = m.runAsync(r); 1213 assertNull(f.join()); 1214 checkCompletedNormally(f, null); 1215 r.assertInvoked(); 1216 }} 1217 1218 /** 1219 * failing runAsync completes exceptionally after running Runnable 1220 */ testRunAsync_exceptionalCompletion()1221 public void testRunAsync_exceptionalCompletion() { 1222 ExecutionMode[] executionModes = { 1223 ExecutionMode.ASYNC, 1224 ExecutionMode.EXECUTOR, 1225 }; 1226 for (ExecutionMode m : executionModes) 1227 { 1228 final FailingRunnable r = new FailingRunnable(m); 1229 final CompletableFuture<Void> f = m.runAsync(r); 1230 checkCompletedWithWrappedCFException(f); 1231 r.assertInvoked(); 1232 }} 1233 1234 /** 1235 * supplyAsync completes with result of supplier 1236 */ testSupplyAsync_normalCompletion()1237 public void testSupplyAsync_normalCompletion() { 1238 ExecutionMode[] executionModes = { 1239 ExecutionMode.ASYNC, 1240 ExecutionMode.EXECUTOR, 1241 }; 1242 for (ExecutionMode m : executionModes) 1243 for (Integer v1 : new Integer[] { 1, null }) 1244 { 1245 final IntegerSupplier r = new IntegerSupplier(m, v1); 1246 final CompletableFuture<Integer> f = m.supplyAsync(r); 1247 assertSame(v1, f.join()); 1248 checkCompletedNormally(f, v1); 1249 r.assertInvoked(); 1250 }} 1251 1252 /** 1253 * Failing supplyAsync completes exceptionally 1254 */ testSupplyAsync_exceptionalCompletion()1255 public void testSupplyAsync_exceptionalCompletion() { 1256 ExecutionMode[] executionModes = { 1257 ExecutionMode.ASYNC, 1258 ExecutionMode.EXECUTOR, 1259 }; 1260 for (ExecutionMode m : executionModes) 1261 { 1262 FailingSupplier r = new FailingSupplier(m); 1263 CompletableFuture<Integer> f = m.supplyAsync(r); 1264 checkCompletedWithWrappedCFException(f); 1265 r.assertInvoked(); 1266 }} 1267 1268 // seq completion methods 1269 1270 /** 1271 * thenRun result completes normally after normal completion of source 1272 */ testThenRun_normalCompletion()1273 public void testThenRun_normalCompletion() { 1274 for (ExecutionMode m : ExecutionMode.values()) 1275 for (Integer v1 : new Integer[] { 1, null }) 1276 { 1277 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1278 final Noop[] rs = new Noop[6]; 1279 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 1280 1281 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]); 1282 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]); 1283 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]); 1284 checkIncomplete(h0); 1285 checkIncomplete(h1); 1286 checkIncomplete(h2); 1287 assertTrue(f.complete(v1)); 1288 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]); 1289 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]); 1290 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]); 1291 1292 checkCompletedNormally(h0, null); 1293 checkCompletedNormally(h1, null); 1294 checkCompletedNormally(h2, null); 1295 checkCompletedNormally(h3, null); 1296 checkCompletedNormally(h4, null); 1297 checkCompletedNormally(h5, null); 1298 checkCompletedNormally(f, v1); 1299 for (Noop r : rs) r.assertInvoked(); 1300 }} 1301 1302 /** 1303 * thenRun result completes exceptionally after exceptional 1304 * completion of source 1305 */ testThenRun_exceptionalCompletion()1306 public void testThenRun_exceptionalCompletion() { 1307 for (ExecutionMode m : ExecutionMode.values()) 1308 { 1309 final CFException ex = new CFException(); 1310 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1311 final Noop[] rs = new Noop[6]; 1312 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 1313 1314 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]); 1315 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]); 1316 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]); 1317 checkIncomplete(h0); 1318 checkIncomplete(h1); 1319 checkIncomplete(h2); 1320 assertTrue(f.completeExceptionally(ex)); 1321 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]); 1322 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]); 1323 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]); 1324 1325 checkCompletedWithWrappedException(h0, ex); 1326 checkCompletedWithWrappedException(h1, ex); 1327 checkCompletedWithWrappedException(h2, ex); 1328 checkCompletedWithWrappedException(h3, ex); 1329 checkCompletedWithWrappedException(h4, ex); 1330 checkCompletedWithWrappedException(h5, ex); 1331 checkCompletedExceptionally(f, ex); 1332 for (Noop r : rs) r.assertNotInvoked(); 1333 }} 1334 1335 /** 1336 * thenRun result completes exceptionally if source cancelled 1337 */ testThenRun_sourceCancelled()1338 public void testThenRun_sourceCancelled() { 1339 for (ExecutionMode m : ExecutionMode.values()) 1340 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1341 { 1342 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1343 final Noop[] rs = new Noop[6]; 1344 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 1345 1346 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]); 1347 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]); 1348 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]); 1349 checkIncomplete(h0); 1350 checkIncomplete(h1); 1351 checkIncomplete(h2); 1352 assertTrue(f.cancel(mayInterruptIfRunning)); 1353 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]); 1354 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]); 1355 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]); 1356 1357 checkCompletedWithWrappedCancellationException(h0); 1358 checkCompletedWithWrappedCancellationException(h1); 1359 checkCompletedWithWrappedCancellationException(h2); 1360 checkCompletedWithWrappedCancellationException(h3); 1361 checkCompletedWithWrappedCancellationException(h4); 1362 checkCompletedWithWrappedCancellationException(h5); 1363 checkCancelled(f); 1364 for (Noop r : rs) r.assertNotInvoked(); 1365 }} 1366 1367 /** 1368 * thenRun result completes exceptionally if action does 1369 */ testThenRun_actionFailed()1370 public void testThenRun_actionFailed() { 1371 for (ExecutionMode m : ExecutionMode.values()) 1372 for (Integer v1 : new Integer[] { 1, null }) 1373 { 1374 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1375 final FailingRunnable[] rs = new FailingRunnable[6]; 1376 for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m); 1377 1378 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]); 1379 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]); 1380 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]); 1381 assertTrue(f.complete(v1)); 1382 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]); 1383 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]); 1384 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]); 1385 1386 checkCompletedWithWrappedCFException(h0); 1387 checkCompletedWithWrappedCFException(h1); 1388 checkCompletedWithWrappedCFException(h2); 1389 checkCompletedWithWrappedCFException(h3); 1390 checkCompletedWithWrappedCFException(h4); 1391 checkCompletedWithWrappedCFException(h5); 1392 checkCompletedNormally(f, v1); 1393 }} 1394 1395 /** 1396 * thenApply result completes normally after normal completion of source 1397 */ testThenApply_normalCompletion()1398 public void testThenApply_normalCompletion() { 1399 for (ExecutionMode m : ExecutionMode.values()) 1400 for (Integer v1 : new Integer[] { 1, null }) 1401 { 1402 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1403 final IncFunction[] rs = new IncFunction[4]; 1404 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 1405 1406 final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]); 1407 final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]); 1408 checkIncomplete(h0); 1409 checkIncomplete(h1); 1410 assertTrue(f.complete(v1)); 1411 final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]); 1412 final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]); 1413 1414 checkCompletedNormally(h0, inc(v1)); 1415 checkCompletedNormally(h1, inc(v1)); 1416 checkCompletedNormally(h2, inc(v1)); 1417 checkCompletedNormally(h3, inc(v1)); 1418 checkCompletedNormally(f, v1); 1419 for (IncFunction r : rs) r.assertValue(inc(v1)); 1420 }} 1421 1422 /** 1423 * thenApply result completes exceptionally after exceptional 1424 * completion of source 1425 */ testThenApply_exceptionalCompletion()1426 public void testThenApply_exceptionalCompletion() { 1427 for (ExecutionMode m : ExecutionMode.values()) 1428 { 1429 final CFException ex = new CFException(); 1430 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1431 final IncFunction[] rs = new IncFunction[4]; 1432 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 1433 1434 final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]); 1435 final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]); 1436 assertTrue(f.completeExceptionally(ex)); 1437 final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]); 1438 final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]); 1439 1440 checkCompletedWithWrappedException(h0, ex); 1441 checkCompletedWithWrappedException(h1, ex); 1442 checkCompletedWithWrappedException(h2, ex); 1443 checkCompletedWithWrappedException(h3, ex); 1444 checkCompletedExceptionally(f, ex); 1445 for (IncFunction r : rs) r.assertNotInvoked(); 1446 }} 1447 1448 /** 1449 * thenApply result completes exceptionally if source cancelled 1450 */ testThenApply_sourceCancelled()1451 public void testThenApply_sourceCancelled() { 1452 for (ExecutionMode m : ExecutionMode.values()) 1453 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1454 { 1455 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1456 final IncFunction[] rs = new IncFunction[4]; 1457 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 1458 1459 final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]); 1460 final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]); 1461 assertTrue(f.cancel(mayInterruptIfRunning)); 1462 final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]); 1463 final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]); 1464 1465 checkCompletedWithWrappedCancellationException(h0); 1466 checkCompletedWithWrappedCancellationException(h1); 1467 checkCompletedWithWrappedCancellationException(h2); 1468 checkCompletedWithWrappedCancellationException(h3); 1469 checkCancelled(f); 1470 for (IncFunction r : rs) r.assertNotInvoked(); 1471 }} 1472 1473 /** 1474 * thenApply result completes exceptionally if action does 1475 */ testThenApply_actionFailed()1476 public void testThenApply_actionFailed() { 1477 for (ExecutionMode m : ExecutionMode.values()) 1478 for (Integer v1 : new Integer[] { 1, null }) 1479 { 1480 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1481 final FailingFunction[] rs = new FailingFunction[4]; 1482 for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m); 1483 1484 final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]); 1485 final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]); 1486 assertTrue(f.complete(v1)); 1487 final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]); 1488 final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]); 1489 1490 checkCompletedWithWrappedCFException(h0); 1491 checkCompletedWithWrappedCFException(h1); 1492 checkCompletedWithWrappedCFException(h2); 1493 checkCompletedWithWrappedCFException(h3); 1494 checkCompletedNormally(f, v1); 1495 }} 1496 1497 /** 1498 * thenAccept result completes normally after normal completion of source 1499 */ testThenAccept_normalCompletion()1500 public void testThenAccept_normalCompletion() { 1501 for (ExecutionMode m : ExecutionMode.values()) 1502 for (Integer v1 : new Integer[] { 1, null }) 1503 { 1504 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1505 final NoopConsumer[] rs = new NoopConsumer[4]; 1506 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 1507 1508 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]); 1509 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]); 1510 checkIncomplete(h0); 1511 checkIncomplete(h1); 1512 assertTrue(f.complete(v1)); 1513 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]); 1514 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]); 1515 1516 checkCompletedNormally(h0, null); 1517 checkCompletedNormally(h1, null); 1518 checkCompletedNormally(h2, null); 1519 checkCompletedNormally(h3, null); 1520 checkCompletedNormally(f, v1); 1521 for (NoopConsumer r : rs) r.assertValue(v1); 1522 }} 1523 1524 /** 1525 * thenAccept result completes exceptionally after exceptional 1526 * completion of source 1527 */ testThenAccept_exceptionalCompletion()1528 public void testThenAccept_exceptionalCompletion() { 1529 for (ExecutionMode m : ExecutionMode.values()) 1530 { 1531 final CFException ex = new CFException(); 1532 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1533 final NoopConsumer[] rs = new NoopConsumer[4]; 1534 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 1535 1536 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]); 1537 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]); 1538 assertTrue(f.completeExceptionally(ex)); 1539 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]); 1540 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]); 1541 1542 checkCompletedWithWrappedException(h0, ex); 1543 checkCompletedWithWrappedException(h1, ex); 1544 checkCompletedWithWrappedException(h2, ex); 1545 checkCompletedWithWrappedException(h3, ex); 1546 checkCompletedExceptionally(f, ex); 1547 for (NoopConsumer r : rs) r.assertNotInvoked(); 1548 }} 1549 1550 /** 1551 * thenAccept result completes exceptionally if source cancelled 1552 */ testThenAccept_sourceCancelled()1553 public void testThenAccept_sourceCancelled() { 1554 for (ExecutionMode m : ExecutionMode.values()) 1555 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1556 { 1557 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1558 final NoopConsumer[] rs = new NoopConsumer[4]; 1559 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 1560 1561 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]); 1562 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]); 1563 assertTrue(f.cancel(mayInterruptIfRunning)); 1564 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]); 1565 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]); 1566 1567 checkCompletedWithWrappedCancellationException(h0); 1568 checkCompletedWithWrappedCancellationException(h1); 1569 checkCompletedWithWrappedCancellationException(h2); 1570 checkCompletedWithWrappedCancellationException(h3); 1571 checkCancelled(f); 1572 for (NoopConsumer r : rs) r.assertNotInvoked(); 1573 }} 1574 1575 /** 1576 * thenAccept result completes exceptionally if action does 1577 */ testThenAccept_actionFailed()1578 public void testThenAccept_actionFailed() { 1579 for (ExecutionMode m : ExecutionMode.values()) 1580 for (Integer v1 : new Integer[] { 1, null }) 1581 { 1582 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1583 final FailingConsumer[] rs = new FailingConsumer[4]; 1584 for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m); 1585 1586 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]); 1587 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]); 1588 assertTrue(f.complete(v1)); 1589 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]); 1590 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]); 1591 1592 checkCompletedWithWrappedCFException(h0); 1593 checkCompletedWithWrappedCFException(h1); 1594 checkCompletedWithWrappedCFException(h2); 1595 checkCompletedWithWrappedCFException(h3); 1596 checkCompletedNormally(f, v1); 1597 }} 1598 1599 /** 1600 * thenCombine result completes normally after normal completion 1601 * of sources 1602 */ testThenCombine_normalCompletion()1603 public void testThenCombine_normalCompletion() { 1604 for (ExecutionMode m : ExecutionMode.values()) 1605 for (boolean fFirst : new boolean[] { true, false }) 1606 for (Integer v1 : new Integer[] { 1, null }) 1607 for (Integer v2 : new Integer[] { 2, null }) 1608 { 1609 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1610 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1611 final SubtractFunction[] rs = new SubtractFunction[6]; 1612 for (int i = 0; i < rs.length; i++) rs[i] = new SubtractFunction(m); 1613 1614 final CompletableFuture<Integer> fst = fFirst ? f : g; 1615 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1616 final Integer w1 = fFirst ? v1 : v2; 1617 final Integer w2 = !fFirst ? v1 : v2; 1618 1619 final CompletableFuture<Integer> h0 = m.thenCombine(f, g, rs[0]); 1620 final CompletableFuture<Integer> h1 = m.thenCombine(fst, fst, rs[1]); 1621 assertTrue(fst.complete(w1)); 1622 final CompletableFuture<Integer> h2 = m.thenCombine(f, g, rs[2]); 1623 final CompletableFuture<Integer> h3 = m.thenCombine(fst, fst, rs[3]); 1624 checkIncomplete(h0); rs[0].assertNotInvoked(); 1625 checkIncomplete(h2); rs[2].assertNotInvoked(); 1626 checkCompletedNormally(h1, subtract(w1, w1)); 1627 checkCompletedNormally(h3, subtract(w1, w1)); 1628 rs[1].assertValue(subtract(w1, w1)); 1629 rs[3].assertValue(subtract(w1, w1)); 1630 assertTrue(snd.complete(w2)); 1631 final CompletableFuture<Integer> h4 = m.thenCombine(f, g, rs[4]); 1632 1633 checkCompletedNormally(h0, subtract(v1, v2)); 1634 checkCompletedNormally(h2, subtract(v1, v2)); 1635 checkCompletedNormally(h4, subtract(v1, v2)); 1636 rs[0].assertValue(subtract(v1, v2)); 1637 rs[2].assertValue(subtract(v1, v2)); 1638 rs[4].assertValue(subtract(v1, v2)); 1639 1640 checkCompletedNormally(f, v1); 1641 checkCompletedNormally(g, v2); 1642 }} 1643 1644 /** 1645 * thenCombine result completes exceptionally after exceptional 1646 * completion of either source 1647 */ testThenCombine_exceptionalCompletion()1648 public void testThenCombine_exceptionalCompletion() throws Throwable { 1649 for (ExecutionMode m : ExecutionMode.values()) 1650 for (boolean fFirst : new boolean[] { true, false }) 1651 for (boolean failFirst : new boolean[] { true, false }) 1652 for (Integer v1 : new Integer[] { 1, null }) 1653 { 1654 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1655 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1656 final CFException ex = new CFException(); 1657 final SubtractFunction r1 = new SubtractFunction(m); 1658 final SubtractFunction r2 = new SubtractFunction(m); 1659 final SubtractFunction r3 = new SubtractFunction(m); 1660 1661 final CompletableFuture<Integer> fst = fFirst ? f : g; 1662 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1663 final Callable<Boolean> complete1 = failFirst ? 1664 () -> fst.completeExceptionally(ex) : 1665 () -> fst.complete(v1); 1666 final Callable<Boolean> complete2 = failFirst ? 1667 () -> snd.complete(v1) : 1668 () -> snd.completeExceptionally(ex); 1669 1670 final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1); 1671 assertTrue(complete1.call()); 1672 final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2); 1673 checkIncomplete(h1); 1674 checkIncomplete(h2); 1675 assertTrue(complete2.call()); 1676 final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3); 1677 1678 checkCompletedWithWrappedException(h1, ex); 1679 checkCompletedWithWrappedException(h2, ex); 1680 checkCompletedWithWrappedException(h3, ex); 1681 r1.assertNotInvoked(); 1682 r2.assertNotInvoked(); 1683 r3.assertNotInvoked(); 1684 checkCompletedNormally(failFirst ? snd : fst, v1); 1685 checkCompletedExceptionally(failFirst ? fst : snd, ex); 1686 }} 1687 1688 /** 1689 * thenCombine result completes exceptionally if either source cancelled 1690 */ testThenCombine_sourceCancelled()1691 public void testThenCombine_sourceCancelled() throws Throwable { 1692 for (ExecutionMode m : ExecutionMode.values()) 1693 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1694 for (boolean fFirst : new boolean[] { true, false }) 1695 for (boolean failFirst : new boolean[] { true, false }) 1696 for (Integer v1 : new Integer[] { 1, null }) 1697 { 1698 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1699 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1700 final SubtractFunction r1 = new SubtractFunction(m); 1701 final SubtractFunction r2 = new SubtractFunction(m); 1702 final SubtractFunction r3 = new SubtractFunction(m); 1703 1704 final CompletableFuture<Integer> fst = fFirst ? f : g; 1705 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1706 final Callable<Boolean> complete1 = failFirst ? 1707 () -> fst.cancel(mayInterruptIfRunning) : 1708 () -> fst.complete(v1); 1709 final Callable<Boolean> complete2 = failFirst ? 1710 () -> snd.complete(v1) : 1711 () -> snd.cancel(mayInterruptIfRunning); 1712 1713 final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1); 1714 assertTrue(complete1.call()); 1715 final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2); 1716 checkIncomplete(h1); 1717 checkIncomplete(h2); 1718 assertTrue(complete2.call()); 1719 final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3); 1720 1721 checkCompletedWithWrappedCancellationException(h1); 1722 checkCompletedWithWrappedCancellationException(h2); 1723 checkCompletedWithWrappedCancellationException(h3); 1724 r1.assertNotInvoked(); 1725 r2.assertNotInvoked(); 1726 r3.assertNotInvoked(); 1727 checkCompletedNormally(failFirst ? snd : fst, v1); 1728 checkCancelled(failFirst ? fst : snd); 1729 }} 1730 1731 /** 1732 * thenCombine result completes exceptionally if action does 1733 */ testThenCombine_actionFailed()1734 public void testThenCombine_actionFailed() { 1735 for (ExecutionMode m : ExecutionMode.values()) 1736 for (boolean fFirst : new boolean[] { true, false }) 1737 for (Integer v1 : new Integer[] { 1, null }) 1738 for (Integer v2 : new Integer[] { 2, null }) 1739 { 1740 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1741 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1742 final FailingBiFunction r1 = new FailingBiFunction(m); 1743 final FailingBiFunction r2 = new FailingBiFunction(m); 1744 final FailingBiFunction r3 = new FailingBiFunction(m); 1745 1746 final CompletableFuture<Integer> fst = fFirst ? f : g; 1747 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1748 final Integer w1 = fFirst ? v1 : v2; 1749 final Integer w2 = !fFirst ? v1 : v2; 1750 1751 final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1); 1752 assertTrue(fst.complete(w1)); 1753 final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2); 1754 assertTrue(snd.complete(w2)); 1755 final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3); 1756 1757 checkCompletedWithWrappedCFException(h1); 1758 checkCompletedWithWrappedCFException(h2); 1759 checkCompletedWithWrappedCFException(h3); 1760 r1.assertInvoked(); 1761 r2.assertInvoked(); 1762 r3.assertInvoked(); 1763 checkCompletedNormally(f, v1); 1764 checkCompletedNormally(g, v2); 1765 }} 1766 1767 /** 1768 * thenAcceptBoth result completes normally after normal 1769 * completion of sources 1770 */ testThenAcceptBoth_normalCompletion()1771 public void testThenAcceptBoth_normalCompletion() { 1772 for (ExecutionMode m : ExecutionMode.values()) 1773 for (boolean fFirst : new boolean[] { true, false }) 1774 for (Integer v1 : new Integer[] { 1, null }) 1775 for (Integer v2 : new Integer[] { 2, null }) 1776 { 1777 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1778 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1779 final SubtractAction r1 = new SubtractAction(m); 1780 final SubtractAction r2 = new SubtractAction(m); 1781 final SubtractAction r3 = new SubtractAction(m); 1782 1783 final CompletableFuture<Integer> fst = fFirst ? f : g; 1784 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1785 final Integer w1 = fFirst ? v1 : v2; 1786 final Integer w2 = !fFirst ? v1 : v2; 1787 1788 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1); 1789 assertTrue(fst.complete(w1)); 1790 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2); 1791 checkIncomplete(h1); 1792 checkIncomplete(h2); 1793 r1.assertNotInvoked(); 1794 r2.assertNotInvoked(); 1795 assertTrue(snd.complete(w2)); 1796 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3); 1797 1798 checkCompletedNormally(h1, null); 1799 checkCompletedNormally(h2, null); 1800 checkCompletedNormally(h3, null); 1801 r1.assertValue(subtract(v1, v2)); 1802 r2.assertValue(subtract(v1, v2)); 1803 r3.assertValue(subtract(v1, v2)); 1804 checkCompletedNormally(f, v1); 1805 checkCompletedNormally(g, v2); 1806 }} 1807 1808 /** 1809 * thenAcceptBoth result completes exceptionally after exceptional 1810 * completion of either source 1811 */ testThenAcceptBoth_exceptionalCompletion()1812 public void testThenAcceptBoth_exceptionalCompletion() throws Throwable { 1813 for (ExecutionMode m : ExecutionMode.values()) 1814 for (boolean fFirst : new boolean[] { true, false }) 1815 for (boolean failFirst : new boolean[] { true, false }) 1816 for (Integer v1 : new Integer[] { 1, null }) 1817 { 1818 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1819 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1820 final CFException ex = new CFException(); 1821 final SubtractAction r1 = new SubtractAction(m); 1822 final SubtractAction r2 = new SubtractAction(m); 1823 final SubtractAction r3 = new SubtractAction(m); 1824 1825 final CompletableFuture<Integer> fst = fFirst ? f : g; 1826 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1827 final Callable<Boolean> complete1 = failFirst ? 1828 () -> fst.completeExceptionally(ex) : 1829 () -> fst.complete(v1); 1830 final Callable<Boolean> complete2 = failFirst ? 1831 () -> snd.complete(v1) : 1832 () -> snd.completeExceptionally(ex); 1833 1834 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1); 1835 assertTrue(complete1.call()); 1836 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2); 1837 checkIncomplete(h1); 1838 checkIncomplete(h2); 1839 assertTrue(complete2.call()); 1840 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3); 1841 1842 checkCompletedWithWrappedException(h1, ex); 1843 checkCompletedWithWrappedException(h2, ex); 1844 checkCompletedWithWrappedException(h3, ex); 1845 r1.assertNotInvoked(); 1846 r2.assertNotInvoked(); 1847 r3.assertNotInvoked(); 1848 checkCompletedNormally(failFirst ? snd : fst, v1); 1849 checkCompletedExceptionally(failFirst ? fst : snd, ex); 1850 }} 1851 1852 /** 1853 * thenAcceptBoth result completes exceptionally if either source cancelled 1854 */ testThenAcceptBoth_sourceCancelled()1855 public void testThenAcceptBoth_sourceCancelled() throws Throwable { 1856 for (ExecutionMode m : ExecutionMode.values()) 1857 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 1858 for (boolean fFirst : new boolean[] { true, false }) 1859 for (boolean failFirst : new boolean[] { true, false }) 1860 for (Integer v1 : new Integer[] { 1, null }) 1861 { 1862 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1863 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1864 final SubtractAction r1 = new SubtractAction(m); 1865 final SubtractAction r2 = new SubtractAction(m); 1866 final SubtractAction r3 = new SubtractAction(m); 1867 1868 final CompletableFuture<Integer> fst = fFirst ? f : g; 1869 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1870 final Callable<Boolean> complete1 = failFirst ? 1871 () -> fst.cancel(mayInterruptIfRunning) : 1872 () -> fst.complete(v1); 1873 final Callable<Boolean> complete2 = failFirst ? 1874 () -> snd.complete(v1) : 1875 () -> snd.cancel(mayInterruptIfRunning); 1876 1877 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1); 1878 assertTrue(complete1.call()); 1879 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2); 1880 checkIncomplete(h1); 1881 checkIncomplete(h2); 1882 assertTrue(complete2.call()); 1883 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3); 1884 1885 checkCompletedWithWrappedCancellationException(h1); 1886 checkCompletedWithWrappedCancellationException(h2); 1887 checkCompletedWithWrappedCancellationException(h3); 1888 r1.assertNotInvoked(); 1889 r2.assertNotInvoked(); 1890 r3.assertNotInvoked(); 1891 checkCompletedNormally(failFirst ? snd : fst, v1); 1892 checkCancelled(failFirst ? fst : snd); 1893 }} 1894 1895 /** 1896 * thenAcceptBoth result completes exceptionally if action does 1897 */ testThenAcceptBoth_actionFailed()1898 public void testThenAcceptBoth_actionFailed() { 1899 for (ExecutionMode m : ExecutionMode.values()) 1900 for (boolean fFirst : new boolean[] { true, false }) 1901 for (Integer v1 : new Integer[] { 1, null }) 1902 for (Integer v2 : new Integer[] { 2, null }) 1903 { 1904 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1905 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1906 final FailingBiConsumer r1 = new FailingBiConsumer(m); 1907 final FailingBiConsumer r2 = new FailingBiConsumer(m); 1908 final FailingBiConsumer r3 = new FailingBiConsumer(m); 1909 1910 final CompletableFuture<Integer> fst = fFirst ? f : g; 1911 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1912 final Integer w1 = fFirst ? v1 : v2; 1913 final Integer w2 = !fFirst ? v1 : v2; 1914 1915 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1); 1916 assertTrue(fst.complete(w1)); 1917 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2); 1918 assertTrue(snd.complete(w2)); 1919 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3); 1920 1921 checkCompletedWithWrappedCFException(h1); 1922 checkCompletedWithWrappedCFException(h2); 1923 checkCompletedWithWrappedCFException(h3); 1924 r1.assertInvoked(); 1925 r2.assertInvoked(); 1926 r3.assertInvoked(); 1927 checkCompletedNormally(f, v1); 1928 checkCompletedNormally(g, v2); 1929 }} 1930 1931 /** 1932 * runAfterBoth result completes normally after normal 1933 * completion of sources 1934 */ testRunAfterBoth_normalCompletion()1935 public void testRunAfterBoth_normalCompletion() { 1936 for (ExecutionMode m : ExecutionMode.values()) 1937 for (boolean fFirst : new boolean[] { true, false }) 1938 for (Integer v1 : new Integer[] { 1, null }) 1939 for (Integer v2 : new Integer[] { 2, null }) 1940 { 1941 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1942 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1943 final Noop r1 = new Noop(m); 1944 final Noop r2 = new Noop(m); 1945 final Noop r3 = new Noop(m); 1946 1947 final CompletableFuture<Integer> fst = fFirst ? f : g; 1948 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1949 final Integer w1 = fFirst ? v1 : v2; 1950 final Integer w2 = !fFirst ? v1 : v2; 1951 1952 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1); 1953 assertTrue(fst.complete(w1)); 1954 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2); 1955 checkIncomplete(h1); 1956 checkIncomplete(h2); 1957 r1.assertNotInvoked(); 1958 r2.assertNotInvoked(); 1959 assertTrue(snd.complete(w2)); 1960 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3); 1961 1962 checkCompletedNormally(h1, null); 1963 checkCompletedNormally(h2, null); 1964 checkCompletedNormally(h3, null); 1965 r1.assertInvoked(); 1966 r2.assertInvoked(); 1967 r3.assertInvoked(); 1968 checkCompletedNormally(f, v1); 1969 checkCompletedNormally(g, v2); 1970 }} 1971 1972 /** 1973 * runAfterBoth result completes exceptionally after exceptional 1974 * completion of either source 1975 */ testRunAfterBoth_exceptionalCompletion()1976 public void testRunAfterBoth_exceptionalCompletion() throws Throwable { 1977 for (ExecutionMode m : ExecutionMode.values()) 1978 for (boolean fFirst : new boolean[] { true, false }) 1979 for (boolean failFirst : new boolean[] { true, false }) 1980 for (Integer v1 : new Integer[] { 1, null }) 1981 { 1982 final CompletableFuture<Integer> f = new CompletableFuture<>(); 1983 final CompletableFuture<Integer> g = new CompletableFuture<>(); 1984 final CFException ex = new CFException(); 1985 final Noop r1 = new Noop(m); 1986 final Noop r2 = new Noop(m); 1987 final Noop r3 = new Noop(m); 1988 1989 final CompletableFuture<Integer> fst = fFirst ? f : g; 1990 final CompletableFuture<Integer> snd = !fFirst ? f : g; 1991 final Callable<Boolean> complete1 = failFirst ? 1992 () -> fst.completeExceptionally(ex) : 1993 () -> fst.complete(v1); 1994 final Callable<Boolean> complete2 = failFirst ? 1995 () -> snd.complete(v1) : 1996 () -> snd.completeExceptionally(ex); 1997 1998 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1); 1999 assertTrue(complete1.call()); 2000 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2); 2001 checkIncomplete(h1); 2002 checkIncomplete(h2); 2003 assertTrue(complete2.call()); 2004 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3); 2005 2006 checkCompletedWithWrappedException(h1, ex); 2007 checkCompletedWithWrappedException(h2, ex); 2008 checkCompletedWithWrappedException(h3, ex); 2009 r1.assertNotInvoked(); 2010 r2.assertNotInvoked(); 2011 r3.assertNotInvoked(); 2012 checkCompletedNormally(failFirst ? snd : fst, v1); 2013 checkCompletedExceptionally(failFirst ? fst : snd, ex); 2014 }} 2015 2016 /** 2017 * runAfterBoth result completes exceptionally if either source cancelled 2018 */ testRunAfterBoth_sourceCancelled()2019 public void testRunAfterBoth_sourceCancelled() throws Throwable { 2020 for (ExecutionMode m : ExecutionMode.values()) 2021 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2022 for (boolean fFirst : new boolean[] { true, false }) 2023 for (boolean failFirst : new boolean[] { true, false }) 2024 for (Integer v1 : new Integer[] { 1, null }) 2025 { 2026 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2027 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2028 final Noop r1 = new Noop(m); 2029 final Noop r2 = new Noop(m); 2030 final Noop r3 = new Noop(m); 2031 2032 final CompletableFuture<Integer> fst = fFirst ? f : g; 2033 final CompletableFuture<Integer> snd = !fFirst ? f : g; 2034 final Callable<Boolean> complete1 = failFirst ? 2035 () -> fst.cancel(mayInterruptIfRunning) : 2036 () -> fst.complete(v1); 2037 final Callable<Boolean> complete2 = failFirst ? 2038 () -> snd.complete(v1) : 2039 () -> snd.cancel(mayInterruptIfRunning); 2040 2041 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1); 2042 assertTrue(complete1.call()); 2043 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2); 2044 checkIncomplete(h1); 2045 checkIncomplete(h2); 2046 assertTrue(complete2.call()); 2047 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3); 2048 2049 checkCompletedWithWrappedCancellationException(h1); 2050 checkCompletedWithWrappedCancellationException(h2); 2051 checkCompletedWithWrappedCancellationException(h3); 2052 r1.assertNotInvoked(); 2053 r2.assertNotInvoked(); 2054 r3.assertNotInvoked(); 2055 checkCompletedNormally(failFirst ? snd : fst, v1); 2056 checkCancelled(failFirst ? fst : snd); 2057 }} 2058 2059 /** 2060 * runAfterBoth result completes exceptionally if action does 2061 */ testRunAfterBoth_actionFailed()2062 public void testRunAfterBoth_actionFailed() { 2063 for (ExecutionMode m : ExecutionMode.values()) 2064 for (boolean fFirst : new boolean[] { true, false }) 2065 for (Integer v1 : new Integer[] { 1, null }) 2066 for (Integer v2 : new Integer[] { 2, null }) 2067 { 2068 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2069 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2070 final FailingRunnable r1 = new FailingRunnable(m); 2071 final FailingRunnable r2 = new FailingRunnable(m); 2072 final FailingRunnable r3 = new FailingRunnable(m); 2073 2074 final CompletableFuture<Integer> fst = fFirst ? f : g; 2075 final CompletableFuture<Integer> snd = !fFirst ? f : g; 2076 final Integer w1 = fFirst ? v1 : v2; 2077 final Integer w2 = !fFirst ? v1 : v2; 2078 2079 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1); 2080 assertTrue(fst.complete(w1)); 2081 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2); 2082 assertTrue(snd.complete(w2)); 2083 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3); 2084 2085 checkCompletedWithWrappedCFException(h1); 2086 checkCompletedWithWrappedCFException(h2); 2087 checkCompletedWithWrappedCFException(h3); 2088 r1.assertInvoked(); 2089 r2.assertInvoked(); 2090 r3.assertInvoked(); 2091 checkCompletedNormally(f, v1); 2092 checkCompletedNormally(g, v2); 2093 }} 2094 2095 /** 2096 * applyToEither result completes normally after normal completion 2097 * of either source 2098 */ testApplyToEither_normalCompletion()2099 public void testApplyToEither_normalCompletion() { 2100 for (ExecutionMode m : ExecutionMode.values()) 2101 for (Integer v1 : new Integer[] { 1, null }) 2102 for (Integer v2 : new Integer[] { 2, null }) 2103 { 2104 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2105 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2106 final IncFunction[] rs = new IncFunction[6]; 2107 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2108 2109 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]); 2110 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]); 2111 checkIncomplete(h0); 2112 checkIncomplete(h1); 2113 rs[0].assertNotInvoked(); 2114 rs[1].assertNotInvoked(); 2115 f.complete(v1); 2116 checkCompletedNormally(h0, inc(v1)); 2117 checkCompletedNormally(h1, inc(v1)); 2118 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]); 2119 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]); 2120 checkCompletedNormally(h2, inc(v1)); 2121 checkCompletedNormally(h3, inc(v1)); 2122 g.complete(v2); 2123 2124 // unspecified behavior - both source completions available 2125 final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]); 2126 final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]); 2127 rs[4].assertValue(h4.join()); 2128 rs[5].assertValue(h5.join()); 2129 assertTrue(Objects.equals(inc(v1), h4.join()) || 2130 Objects.equals(inc(v2), h4.join())); 2131 assertTrue(Objects.equals(inc(v1), h5.join()) || 2132 Objects.equals(inc(v2), h5.join())); 2133 2134 checkCompletedNormally(f, v1); 2135 checkCompletedNormally(g, v2); 2136 checkCompletedNormally(h0, inc(v1)); 2137 checkCompletedNormally(h1, inc(v1)); 2138 checkCompletedNormally(h2, inc(v1)); 2139 checkCompletedNormally(h3, inc(v1)); 2140 for (int i = 0; i < 4; i++) rs[i].assertValue(inc(v1)); 2141 }} 2142 2143 /** 2144 * applyToEither result completes exceptionally after exceptional 2145 * completion of either source 2146 */ testApplyToEither_exceptionalCompletion()2147 public void testApplyToEither_exceptionalCompletion() { 2148 for (ExecutionMode m : ExecutionMode.values()) 2149 for (Integer v1 : new Integer[] { 1, null }) 2150 { 2151 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2152 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2153 final CFException ex = new CFException(); 2154 final IncFunction[] rs = new IncFunction[6]; 2155 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2156 2157 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]); 2158 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]); 2159 checkIncomplete(h0); 2160 checkIncomplete(h1); 2161 rs[0].assertNotInvoked(); 2162 rs[1].assertNotInvoked(); 2163 f.completeExceptionally(ex); 2164 checkCompletedWithWrappedException(h0, ex); 2165 checkCompletedWithWrappedException(h1, ex); 2166 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]); 2167 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]); 2168 checkCompletedWithWrappedException(h2, ex); 2169 checkCompletedWithWrappedException(h3, ex); 2170 g.complete(v1); 2171 2172 // unspecified behavior - both source completions available 2173 final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]); 2174 final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]); 2175 try { 2176 assertEquals(inc(v1), h4.join()); 2177 rs[4].assertValue(inc(v1)); 2178 } catch (CompletionException ok) { 2179 checkCompletedWithWrappedException(h4, ex); 2180 rs[4].assertNotInvoked(); 2181 } 2182 try { 2183 assertEquals(inc(v1), h5.join()); 2184 rs[5].assertValue(inc(v1)); 2185 } catch (CompletionException ok) { 2186 checkCompletedWithWrappedException(h5, ex); 2187 rs[5].assertNotInvoked(); 2188 } 2189 2190 checkCompletedExceptionally(f, ex); 2191 checkCompletedNormally(g, v1); 2192 checkCompletedWithWrappedException(h0, ex); 2193 checkCompletedWithWrappedException(h1, ex); 2194 checkCompletedWithWrappedException(h2, ex); 2195 checkCompletedWithWrappedException(h3, ex); 2196 checkCompletedWithWrappedException(h4, ex); 2197 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2198 }} 2199 testApplyToEither_exceptionalCompletion2()2200 public void testApplyToEither_exceptionalCompletion2() { 2201 for (ExecutionMode m : ExecutionMode.values()) 2202 for (boolean fFirst : new boolean[] { true, false }) 2203 for (Integer v1 : new Integer[] { 1, null }) 2204 { 2205 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2206 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2207 final CFException ex = new CFException(); 2208 final IncFunction[] rs = new IncFunction[6]; 2209 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2210 2211 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]); 2212 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]); 2213 assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2214 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2215 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]); 2216 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]); 2217 2218 // unspecified behavior - both source completions available 2219 try { 2220 assertEquals(inc(v1), h0.join()); 2221 rs[0].assertValue(inc(v1)); 2222 } catch (CompletionException ok) { 2223 checkCompletedWithWrappedException(h0, ex); 2224 rs[0].assertNotInvoked(); 2225 } 2226 try { 2227 assertEquals(inc(v1), h1.join()); 2228 rs[1].assertValue(inc(v1)); 2229 } catch (CompletionException ok) { 2230 checkCompletedWithWrappedException(h1, ex); 2231 rs[1].assertNotInvoked(); 2232 } 2233 try { 2234 assertEquals(inc(v1), h2.join()); 2235 rs[2].assertValue(inc(v1)); 2236 } catch (CompletionException ok) { 2237 checkCompletedWithWrappedException(h2, ex); 2238 rs[2].assertNotInvoked(); 2239 } 2240 try { 2241 assertEquals(inc(v1), h3.join()); 2242 rs[3].assertValue(inc(v1)); 2243 } catch (CompletionException ok) { 2244 checkCompletedWithWrappedException(h3, ex); 2245 rs[3].assertNotInvoked(); 2246 } 2247 2248 checkCompletedNormally(f, v1); 2249 checkCompletedExceptionally(g, ex); 2250 }} 2251 2252 /** 2253 * applyToEither result completes exceptionally if either source cancelled 2254 */ testApplyToEither_sourceCancelled()2255 public void testApplyToEither_sourceCancelled() { 2256 for (ExecutionMode m : ExecutionMode.values()) 2257 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2258 for (Integer v1 : new Integer[] { 1, null }) 2259 { 2260 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2261 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2262 final IncFunction[] rs = new IncFunction[6]; 2263 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2264 2265 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]); 2266 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]); 2267 checkIncomplete(h0); 2268 checkIncomplete(h1); 2269 rs[0].assertNotInvoked(); 2270 rs[1].assertNotInvoked(); 2271 f.cancel(mayInterruptIfRunning); 2272 checkCompletedWithWrappedCancellationException(h0); 2273 checkCompletedWithWrappedCancellationException(h1); 2274 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]); 2275 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]); 2276 checkCompletedWithWrappedCancellationException(h2); 2277 checkCompletedWithWrappedCancellationException(h3); 2278 g.complete(v1); 2279 2280 // unspecified behavior - both source completions available 2281 final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]); 2282 final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]); 2283 try { 2284 assertEquals(inc(v1), h4.join()); 2285 rs[4].assertValue(inc(v1)); 2286 } catch (CompletionException ok) { 2287 checkCompletedWithWrappedCancellationException(h4); 2288 rs[4].assertNotInvoked(); 2289 } 2290 try { 2291 assertEquals(inc(v1), h5.join()); 2292 rs[5].assertValue(inc(v1)); 2293 } catch (CompletionException ok) { 2294 checkCompletedWithWrappedCancellationException(h5); 2295 rs[5].assertNotInvoked(); 2296 } 2297 2298 checkCancelled(f); 2299 checkCompletedNormally(g, v1); 2300 checkCompletedWithWrappedCancellationException(h0); 2301 checkCompletedWithWrappedCancellationException(h1); 2302 checkCompletedWithWrappedCancellationException(h2); 2303 checkCompletedWithWrappedCancellationException(h3); 2304 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2305 }} 2306 testApplyToEither_sourceCancelled2()2307 public void testApplyToEither_sourceCancelled2() { 2308 for (ExecutionMode m : ExecutionMode.values()) 2309 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2310 for (boolean fFirst : new boolean[] { true, false }) 2311 for (Integer v1 : new Integer[] { 1, null }) 2312 { 2313 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2314 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2315 final IncFunction[] rs = new IncFunction[6]; 2316 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m); 2317 2318 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]); 2319 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]); 2320 assertTrue(fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning)); 2321 assertTrue(!fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning)); 2322 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]); 2323 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]); 2324 2325 // unspecified behavior - both source completions available 2326 try { 2327 assertEquals(inc(v1), h0.join()); 2328 rs[0].assertValue(inc(v1)); 2329 } catch (CompletionException ok) { 2330 checkCompletedWithWrappedCancellationException(h0); 2331 rs[0].assertNotInvoked(); 2332 } 2333 try { 2334 assertEquals(inc(v1), h1.join()); 2335 rs[1].assertValue(inc(v1)); 2336 } catch (CompletionException ok) { 2337 checkCompletedWithWrappedCancellationException(h1); 2338 rs[1].assertNotInvoked(); 2339 } 2340 try { 2341 assertEquals(inc(v1), h2.join()); 2342 rs[2].assertValue(inc(v1)); 2343 } catch (CompletionException ok) { 2344 checkCompletedWithWrappedCancellationException(h2); 2345 rs[2].assertNotInvoked(); 2346 } 2347 try { 2348 assertEquals(inc(v1), h3.join()); 2349 rs[3].assertValue(inc(v1)); 2350 } catch (CompletionException ok) { 2351 checkCompletedWithWrappedCancellationException(h3); 2352 rs[3].assertNotInvoked(); 2353 } 2354 2355 checkCompletedNormally(f, v1); 2356 checkCancelled(g); 2357 }} 2358 2359 /** 2360 * applyToEither result completes exceptionally if action does 2361 */ testApplyToEither_actionFailed()2362 public void testApplyToEither_actionFailed() { 2363 for (ExecutionMode m : ExecutionMode.values()) 2364 for (Integer v1 : new Integer[] { 1, null }) 2365 for (Integer v2 : new Integer[] { 2, null }) 2366 { 2367 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2368 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2369 final FailingFunction[] rs = new FailingFunction[6]; 2370 for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m); 2371 2372 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]); 2373 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]); 2374 f.complete(v1); 2375 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]); 2376 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]); 2377 checkCompletedWithWrappedCFException(h0); 2378 checkCompletedWithWrappedCFException(h1); 2379 checkCompletedWithWrappedCFException(h2); 2380 checkCompletedWithWrappedCFException(h3); 2381 for (int i = 0; i < 4; i++) rs[i].assertValue(v1); 2382 2383 g.complete(v2); 2384 2385 // unspecified behavior - both source completions available 2386 final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]); 2387 final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]); 2388 2389 checkCompletedWithWrappedCFException(h4); 2390 assertTrue(Objects.equals(v1, rs[4].value) || 2391 Objects.equals(v2, rs[4].value)); 2392 checkCompletedWithWrappedCFException(h5); 2393 assertTrue(Objects.equals(v1, rs[5].value) || 2394 Objects.equals(v2, rs[5].value)); 2395 2396 checkCompletedNormally(f, v1); 2397 checkCompletedNormally(g, v2); 2398 }} 2399 2400 /** 2401 * acceptEither result completes normally after normal completion 2402 * of either source 2403 */ testAcceptEither_normalCompletion()2404 public void testAcceptEither_normalCompletion() { 2405 for (ExecutionMode m : ExecutionMode.values()) 2406 for (Integer v1 : new Integer[] { 1, null }) 2407 for (Integer v2 : new Integer[] { 2, null }) 2408 { 2409 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2410 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2411 final NoopConsumer[] rs = new NoopConsumer[6]; 2412 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 2413 2414 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2415 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2416 checkIncomplete(h0); 2417 checkIncomplete(h1); 2418 rs[0].assertNotInvoked(); 2419 rs[1].assertNotInvoked(); 2420 f.complete(v1); 2421 checkCompletedNormally(h0, null); 2422 checkCompletedNormally(h1, null); 2423 rs[0].assertValue(v1); 2424 rs[1].assertValue(v1); 2425 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2426 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2427 checkCompletedNormally(h2, null); 2428 checkCompletedNormally(h3, null); 2429 rs[2].assertValue(v1); 2430 rs[3].assertValue(v1); 2431 g.complete(v2); 2432 2433 // unspecified behavior - both source completions available 2434 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]); 2435 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]); 2436 checkCompletedNormally(h4, null); 2437 checkCompletedNormally(h5, null); 2438 assertTrue(Objects.equals(v1, rs[4].value) || 2439 Objects.equals(v2, rs[4].value)); 2440 assertTrue(Objects.equals(v1, rs[5].value) || 2441 Objects.equals(v2, rs[5].value)); 2442 2443 checkCompletedNormally(f, v1); 2444 checkCompletedNormally(g, v2); 2445 checkCompletedNormally(h0, null); 2446 checkCompletedNormally(h1, null); 2447 checkCompletedNormally(h2, null); 2448 checkCompletedNormally(h3, null); 2449 for (int i = 0; i < 4; i++) rs[i].assertValue(v1); 2450 }} 2451 2452 /** 2453 * acceptEither result completes exceptionally after exceptional 2454 * completion of either source 2455 */ testAcceptEither_exceptionalCompletion()2456 public void testAcceptEither_exceptionalCompletion() { 2457 for (ExecutionMode m : ExecutionMode.values()) 2458 for (Integer v1 : new Integer[] { 1, null }) 2459 { 2460 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2461 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2462 final CFException ex = new CFException(); 2463 final NoopConsumer[] rs = new NoopConsumer[6]; 2464 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 2465 2466 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2467 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2468 checkIncomplete(h0); 2469 checkIncomplete(h1); 2470 rs[0].assertNotInvoked(); 2471 rs[1].assertNotInvoked(); 2472 f.completeExceptionally(ex); 2473 checkCompletedWithWrappedException(h0, ex); 2474 checkCompletedWithWrappedException(h1, ex); 2475 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2476 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2477 checkCompletedWithWrappedException(h2, ex); 2478 checkCompletedWithWrappedException(h3, ex); 2479 2480 g.complete(v1); 2481 2482 // unspecified behavior - both source completions available 2483 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]); 2484 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]); 2485 try { 2486 assertNull(h4.join()); 2487 rs[4].assertValue(v1); 2488 } catch (CompletionException ok) { 2489 checkCompletedWithWrappedException(h4, ex); 2490 rs[4].assertNotInvoked(); 2491 } 2492 try { 2493 assertNull(h5.join()); 2494 rs[5].assertValue(v1); 2495 } catch (CompletionException ok) { 2496 checkCompletedWithWrappedException(h5, ex); 2497 rs[5].assertNotInvoked(); 2498 } 2499 2500 checkCompletedExceptionally(f, ex); 2501 checkCompletedNormally(g, v1); 2502 checkCompletedWithWrappedException(h0, ex); 2503 checkCompletedWithWrappedException(h1, ex); 2504 checkCompletedWithWrappedException(h2, ex); 2505 checkCompletedWithWrappedException(h3, ex); 2506 checkCompletedWithWrappedException(h4, ex); 2507 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2508 }} 2509 testAcceptEither_exceptionalCompletion2()2510 public void testAcceptEither_exceptionalCompletion2() { 2511 for (ExecutionMode m : ExecutionMode.values()) 2512 for (boolean fFirst : new boolean[] { true, false }) 2513 for (Integer v1 : new Integer[] { 1, null }) 2514 { 2515 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2516 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2517 final CFException ex = new CFException(); 2518 final NoopConsumer[] rs = new NoopConsumer[6]; 2519 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 2520 2521 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2522 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2523 assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2524 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2525 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2526 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2527 2528 // unspecified behavior - both source completions available 2529 try { 2530 assertEquals(null, h0.join()); 2531 rs[0].assertValue(v1); 2532 } catch (CompletionException ok) { 2533 checkCompletedWithWrappedException(h0, ex); 2534 rs[0].assertNotInvoked(); 2535 } 2536 try { 2537 assertEquals(null, h1.join()); 2538 rs[1].assertValue(v1); 2539 } catch (CompletionException ok) { 2540 checkCompletedWithWrappedException(h1, ex); 2541 rs[1].assertNotInvoked(); 2542 } 2543 try { 2544 assertEquals(null, h2.join()); 2545 rs[2].assertValue(v1); 2546 } catch (CompletionException ok) { 2547 checkCompletedWithWrappedException(h2, ex); 2548 rs[2].assertNotInvoked(); 2549 } 2550 try { 2551 assertEquals(null, h3.join()); 2552 rs[3].assertValue(v1); 2553 } catch (CompletionException ok) { 2554 checkCompletedWithWrappedException(h3, ex); 2555 rs[3].assertNotInvoked(); 2556 } 2557 2558 checkCompletedNormally(f, v1); 2559 checkCompletedExceptionally(g, ex); 2560 }} 2561 2562 /** 2563 * acceptEither result completes exceptionally if either source cancelled 2564 */ testAcceptEither_sourceCancelled()2565 public void testAcceptEither_sourceCancelled() { 2566 for (ExecutionMode m : ExecutionMode.values()) 2567 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2568 for (Integer v1 : new Integer[] { 1, null }) 2569 { 2570 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2571 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2572 final NoopConsumer[] rs = new NoopConsumer[6]; 2573 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m); 2574 2575 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2576 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2577 checkIncomplete(h0); 2578 checkIncomplete(h1); 2579 rs[0].assertNotInvoked(); 2580 rs[1].assertNotInvoked(); 2581 f.cancel(mayInterruptIfRunning); 2582 checkCompletedWithWrappedCancellationException(h0); 2583 checkCompletedWithWrappedCancellationException(h1); 2584 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2585 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2586 checkCompletedWithWrappedCancellationException(h2); 2587 checkCompletedWithWrappedCancellationException(h3); 2588 2589 g.complete(v1); 2590 2591 // unspecified behavior - both source completions available 2592 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]); 2593 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]); 2594 try { 2595 assertNull(h4.join()); 2596 rs[4].assertValue(v1); 2597 } catch (CompletionException ok) { 2598 checkCompletedWithWrappedCancellationException(h4); 2599 rs[4].assertNotInvoked(); 2600 } 2601 try { 2602 assertNull(h5.join()); 2603 rs[5].assertValue(v1); 2604 } catch (CompletionException ok) { 2605 checkCompletedWithWrappedCancellationException(h5); 2606 rs[5].assertNotInvoked(); 2607 } 2608 2609 checkCancelled(f); 2610 checkCompletedNormally(g, v1); 2611 checkCompletedWithWrappedCancellationException(h0); 2612 checkCompletedWithWrappedCancellationException(h1); 2613 checkCompletedWithWrappedCancellationException(h2); 2614 checkCompletedWithWrappedCancellationException(h3); 2615 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2616 }} 2617 2618 /** 2619 * acceptEither result completes exceptionally if action does 2620 */ testAcceptEither_actionFailed()2621 public void testAcceptEither_actionFailed() { 2622 for (ExecutionMode m : ExecutionMode.values()) 2623 for (Integer v1 : new Integer[] { 1, null }) 2624 for (Integer v2 : new Integer[] { 2, null }) 2625 { 2626 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2627 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2628 final FailingConsumer[] rs = new FailingConsumer[6]; 2629 for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m); 2630 2631 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]); 2632 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]); 2633 f.complete(v1); 2634 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]); 2635 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]); 2636 checkCompletedWithWrappedCFException(h0); 2637 checkCompletedWithWrappedCFException(h1); 2638 checkCompletedWithWrappedCFException(h2); 2639 checkCompletedWithWrappedCFException(h3); 2640 for (int i = 0; i < 4; i++) rs[i].assertValue(v1); 2641 2642 g.complete(v2); 2643 2644 // unspecified behavior - both source completions available 2645 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]); 2646 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]); 2647 2648 checkCompletedWithWrappedCFException(h4); 2649 assertTrue(Objects.equals(v1, rs[4].value) || 2650 Objects.equals(v2, rs[4].value)); 2651 checkCompletedWithWrappedCFException(h5); 2652 assertTrue(Objects.equals(v1, rs[5].value) || 2653 Objects.equals(v2, rs[5].value)); 2654 2655 checkCompletedNormally(f, v1); 2656 checkCompletedNormally(g, v2); 2657 }} 2658 2659 /** 2660 * runAfterEither result completes normally after normal completion 2661 * of either source 2662 */ testRunAfterEither_normalCompletion()2663 public void testRunAfterEither_normalCompletion() { 2664 for (ExecutionMode m : ExecutionMode.values()) 2665 for (Integer v1 : new Integer[] { 1, null }) 2666 for (Integer v2 : new Integer[] { 2, null }) 2667 { 2668 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2669 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2670 final Noop[] rs = new Noop[6]; 2671 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 2672 2673 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 2674 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 2675 checkIncomplete(h0); 2676 checkIncomplete(h1); 2677 rs[0].assertNotInvoked(); 2678 rs[1].assertNotInvoked(); 2679 f.complete(v1); 2680 checkCompletedNormally(h0, null); 2681 checkCompletedNormally(h1, null); 2682 rs[0].assertInvoked(); 2683 rs[1].assertInvoked(); 2684 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 2685 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 2686 checkCompletedNormally(h2, null); 2687 checkCompletedNormally(h3, null); 2688 rs[2].assertInvoked(); 2689 rs[3].assertInvoked(); 2690 2691 g.complete(v2); 2692 2693 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]); 2694 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]); 2695 2696 checkCompletedNormally(f, v1); 2697 checkCompletedNormally(g, v2); 2698 checkCompletedNormally(h0, null); 2699 checkCompletedNormally(h1, null); 2700 checkCompletedNormally(h2, null); 2701 checkCompletedNormally(h3, null); 2702 checkCompletedNormally(h4, null); 2703 checkCompletedNormally(h5, null); 2704 for (int i = 0; i < 6; i++) rs[i].assertInvoked(); 2705 }} 2706 2707 /** 2708 * runAfterEither result completes exceptionally after exceptional 2709 * completion of either source 2710 */ testRunAfterEither_exceptionalCompletion()2711 public void testRunAfterEither_exceptionalCompletion() { 2712 for (ExecutionMode m : ExecutionMode.values()) 2713 for (Integer v1 : new Integer[] { 1, null }) 2714 { 2715 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2716 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2717 final CFException ex = new CFException(); 2718 final Noop[] rs = new Noop[6]; 2719 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 2720 2721 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 2722 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 2723 checkIncomplete(h0); 2724 checkIncomplete(h1); 2725 rs[0].assertNotInvoked(); 2726 rs[1].assertNotInvoked(); 2727 assertTrue(f.completeExceptionally(ex)); 2728 checkCompletedWithWrappedException(h0, ex); 2729 checkCompletedWithWrappedException(h1, ex); 2730 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 2731 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 2732 checkCompletedWithWrappedException(h2, ex); 2733 checkCompletedWithWrappedException(h3, ex); 2734 2735 assertTrue(g.complete(v1)); 2736 2737 // unspecified behavior - both source completions available 2738 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]); 2739 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]); 2740 try { 2741 assertNull(h4.join()); 2742 rs[4].assertInvoked(); 2743 } catch (CompletionException ok) { 2744 checkCompletedWithWrappedException(h4, ex); 2745 rs[4].assertNotInvoked(); 2746 } 2747 try { 2748 assertNull(h5.join()); 2749 rs[5].assertInvoked(); 2750 } catch (CompletionException ok) { 2751 checkCompletedWithWrappedException(h5, ex); 2752 rs[5].assertNotInvoked(); 2753 } 2754 2755 checkCompletedExceptionally(f, ex); 2756 checkCompletedNormally(g, v1); 2757 checkCompletedWithWrappedException(h0, ex); 2758 checkCompletedWithWrappedException(h1, ex); 2759 checkCompletedWithWrappedException(h2, ex); 2760 checkCompletedWithWrappedException(h3, ex); 2761 checkCompletedWithWrappedException(h4, ex); 2762 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2763 }} 2764 testRunAfterEither_exceptionalCompletion2()2765 public void testRunAfterEither_exceptionalCompletion2() { 2766 for (ExecutionMode m : ExecutionMode.values()) 2767 for (boolean fFirst : new boolean[] { true, false }) 2768 for (Integer v1 : new Integer[] { 1, null }) 2769 { 2770 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2771 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2772 final CFException ex = new CFException(); 2773 final Noop[] rs = new Noop[6]; 2774 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 2775 2776 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 2777 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 2778 assertTrue( fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2779 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex)); 2780 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 2781 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 2782 2783 // unspecified behavior - both source completions available 2784 try { 2785 assertEquals(null, h0.join()); 2786 rs[0].assertInvoked(); 2787 } catch (CompletionException ok) { 2788 checkCompletedWithWrappedException(h0, ex); 2789 rs[0].assertNotInvoked(); 2790 } 2791 try { 2792 assertEquals(null, h1.join()); 2793 rs[1].assertInvoked(); 2794 } catch (CompletionException ok) { 2795 checkCompletedWithWrappedException(h1, ex); 2796 rs[1].assertNotInvoked(); 2797 } 2798 try { 2799 assertEquals(null, h2.join()); 2800 rs[2].assertInvoked(); 2801 } catch (CompletionException ok) { 2802 checkCompletedWithWrappedException(h2, ex); 2803 rs[2].assertNotInvoked(); 2804 } 2805 try { 2806 assertEquals(null, h3.join()); 2807 rs[3].assertInvoked(); 2808 } catch (CompletionException ok) { 2809 checkCompletedWithWrappedException(h3, ex); 2810 rs[3].assertNotInvoked(); 2811 } 2812 2813 checkCompletedNormally(f, v1); 2814 checkCompletedExceptionally(g, ex); 2815 }} 2816 2817 /** 2818 * runAfterEither result completes exceptionally if either source cancelled 2819 */ testRunAfterEither_sourceCancelled()2820 public void testRunAfterEither_sourceCancelled() { 2821 for (ExecutionMode m : ExecutionMode.values()) 2822 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2823 for (Integer v1 : new Integer[] { 1, null }) 2824 { 2825 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2826 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2827 final Noop[] rs = new Noop[6]; 2828 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m); 2829 2830 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 2831 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 2832 checkIncomplete(h0); 2833 checkIncomplete(h1); 2834 rs[0].assertNotInvoked(); 2835 rs[1].assertNotInvoked(); 2836 f.cancel(mayInterruptIfRunning); 2837 checkCompletedWithWrappedCancellationException(h0); 2838 checkCompletedWithWrappedCancellationException(h1); 2839 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 2840 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 2841 checkCompletedWithWrappedCancellationException(h2); 2842 checkCompletedWithWrappedCancellationException(h3); 2843 2844 assertTrue(g.complete(v1)); 2845 2846 // unspecified behavior - both source completions available 2847 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]); 2848 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]); 2849 try { 2850 assertNull(h4.join()); 2851 rs[4].assertInvoked(); 2852 } catch (CompletionException ok) { 2853 checkCompletedWithWrappedCancellationException(h4); 2854 rs[4].assertNotInvoked(); 2855 } 2856 try { 2857 assertNull(h5.join()); 2858 rs[5].assertInvoked(); 2859 } catch (CompletionException ok) { 2860 checkCompletedWithWrappedCancellationException(h5); 2861 rs[5].assertNotInvoked(); 2862 } 2863 2864 checkCancelled(f); 2865 checkCompletedNormally(g, v1); 2866 checkCompletedWithWrappedCancellationException(h0); 2867 checkCompletedWithWrappedCancellationException(h1); 2868 checkCompletedWithWrappedCancellationException(h2); 2869 checkCompletedWithWrappedCancellationException(h3); 2870 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked(); 2871 }} 2872 2873 /** 2874 * runAfterEither result completes exceptionally if action does 2875 */ testRunAfterEither_actionFailed()2876 public void testRunAfterEither_actionFailed() { 2877 for (ExecutionMode m : ExecutionMode.values()) 2878 for (Integer v1 : new Integer[] { 1, null }) 2879 for (Integer v2 : new Integer[] { 2, null }) 2880 { 2881 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2882 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2883 final FailingRunnable[] rs = new FailingRunnable[6]; 2884 for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m); 2885 2886 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]); 2887 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]); 2888 assertTrue(f.complete(v1)); 2889 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]); 2890 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]); 2891 checkCompletedWithWrappedCFException(h0); 2892 checkCompletedWithWrappedCFException(h1); 2893 checkCompletedWithWrappedCFException(h2); 2894 checkCompletedWithWrappedCFException(h3); 2895 for (int i = 0; i < 4; i++) rs[i].assertInvoked(); 2896 assertTrue(g.complete(v2)); 2897 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]); 2898 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]); 2899 checkCompletedWithWrappedCFException(h4); 2900 checkCompletedWithWrappedCFException(h5); 2901 2902 checkCompletedNormally(f, v1); 2903 checkCompletedNormally(g, v2); 2904 for (int i = 0; i < 6; i++) rs[i].assertInvoked(); 2905 }} 2906 2907 /** 2908 * thenCompose result completes normally after normal completion of source 2909 */ testThenCompose_normalCompletion()2910 public void testThenCompose_normalCompletion() { 2911 for (ExecutionMode m : ExecutionMode.values()) 2912 for (boolean createIncomplete : new boolean[] { true, false }) 2913 for (Integer v1 : new Integer[] { 1, null }) 2914 { 2915 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2916 final CompletableFutureInc r = new CompletableFutureInc(m); 2917 if (!createIncomplete) assertTrue(f.complete(v1)); 2918 final CompletableFuture<Integer> g = m.thenCompose(f, r); 2919 if (createIncomplete) assertTrue(f.complete(v1)); 2920 2921 checkCompletedNormally(g, inc(v1)); 2922 checkCompletedNormally(f, v1); 2923 r.assertValue(v1); 2924 }} 2925 2926 /** 2927 * thenCompose result completes exceptionally after exceptional 2928 * completion of source 2929 */ testThenCompose_exceptionalCompletion()2930 public void testThenCompose_exceptionalCompletion() { 2931 for (ExecutionMode m : ExecutionMode.values()) 2932 for (boolean createIncomplete : new boolean[] { true, false }) 2933 { 2934 final CFException ex = new CFException(); 2935 final CompletableFutureInc r = new CompletableFutureInc(m); 2936 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2937 if (!createIncomplete) f.completeExceptionally(ex); 2938 final CompletableFuture<Integer> g = m.thenCompose(f, r); 2939 if (createIncomplete) f.completeExceptionally(ex); 2940 2941 checkCompletedWithWrappedException(g, ex); 2942 checkCompletedExceptionally(f, ex); 2943 r.assertNotInvoked(); 2944 }} 2945 2946 /** 2947 * thenCompose result completes exceptionally if action does 2948 */ testThenCompose_actionFailed()2949 public void testThenCompose_actionFailed() { 2950 for (ExecutionMode m : ExecutionMode.values()) 2951 for (boolean createIncomplete : new boolean[] { true, false }) 2952 for (Integer v1 : new Integer[] { 1, null }) 2953 { 2954 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2955 final FailingCompletableFutureFunction r 2956 = new FailingCompletableFutureFunction(m); 2957 if (!createIncomplete) assertTrue(f.complete(v1)); 2958 final CompletableFuture<Integer> g = m.thenCompose(f, r); 2959 if (createIncomplete) assertTrue(f.complete(v1)); 2960 2961 checkCompletedWithWrappedCFException(g); 2962 checkCompletedNormally(f, v1); 2963 }} 2964 2965 /** 2966 * thenCompose result completes exceptionally if source cancelled 2967 */ testThenCompose_sourceCancelled()2968 public void testThenCompose_sourceCancelled() { 2969 for (ExecutionMode m : ExecutionMode.values()) 2970 for (boolean createIncomplete : new boolean[] { true, false }) 2971 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 2972 { 2973 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2974 final CompletableFutureInc r = new CompletableFutureInc(m); 2975 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning)); 2976 final CompletableFuture<Integer> g = m.thenCompose(f, r); 2977 if (createIncomplete) { 2978 checkIncomplete(g); 2979 assertTrue(f.cancel(mayInterruptIfRunning)); 2980 } 2981 2982 checkCompletedWithWrappedCancellationException(g); 2983 checkCancelled(f); 2984 }} 2985 2986 /** 2987 * thenCompose result completes exceptionally if the result of the action does 2988 */ testThenCompose_actionReturnsFailingFuture()2989 public void testThenCompose_actionReturnsFailingFuture() { 2990 for (ExecutionMode m : ExecutionMode.values()) 2991 for (int order = 0; order < 6; order++) 2992 for (Integer v1 : new Integer[] { 1, null }) 2993 { 2994 final CFException ex = new CFException(); 2995 final CompletableFuture<Integer> f = new CompletableFuture<>(); 2996 final CompletableFuture<Integer> g = new CompletableFuture<>(); 2997 final CompletableFuture<Integer> h; 2998 // Test all permutations of orders 2999 switch (order) { 3000 case 0: 3001 assertTrue(f.complete(v1)); 3002 assertTrue(g.completeExceptionally(ex)); 3003 h = m.thenCompose(f, (x -> g)); 3004 break; 3005 case 1: 3006 assertTrue(f.complete(v1)); 3007 h = m.thenCompose(f, (x -> g)); 3008 assertTrue(g.completeExceptionally(ex)); 3009 break; 3010 case 2: 3011 assertTrue(g.completeExceptionally(ex)); 3012 assertTrue(f.complete(v1)); 3013 h = m.thenCompose(f, (x -> g)); 3014 break; 3015 case 3: 3016 assertTrue(g.completeExceptionally(ex)); 3017 h = m.thenCompose(f, (x -> g)); 3018 assertTrue(f.complete(v1)); 3019 break; 3020 case 4: 3021 h = m.thenCompose(f, (x -> g)); 3022 assertTrue(f.complete(v1)); 3023 assertTrue(g.completeExceptionally(ex)); 3024 break; 3025 case 5: 3026 h = m.thenCompose(f, (x -> g)); 3027 assertTrue(f.complete(v1)); 3028 assertTrue(g.completeExceptionally(ex)); 3029 break; 3030 default: throw new AssertionError(); 3031 } 3032 3033 checkCompletedExceptionally(g, ex); 3034 checkCompletedWithWrappedException(h, ex); 3035 checkCompletedNormally(f, v1); 3036 }} 3037 3038 // other static methods 3039 3040 /** 3041 * allOf(no component futures) returns a future completed normally 3042 * with the value null 3043 */ testAllOf_empty()3044 public void testAllOf_empty() throws Exception { 3045 CompletableFuture<Void> f = CompletableFuture.allOf(); 3046 checkCompletedNormally(f, null); 3047 } 3048 3049 /** 3050 * allOf returns a future completed normally with the value null 3051 * when all components complete normally 3052 */ testAllOf_normal()3053 public void testAllOf_normal() throws Exception { 3054 for (int k = 1; k < 10; k++) { 3055 CompletableFuture<Integer>[] fs 3056 = (CompletableFuture<Integer>[]) new CompletableFuture[k]; 3057 for (int i = 0; i < k; i++) 3058 fs[i] = new CompletableFuture<>(); 3059 CompletableFuture<Void> f = CompletableFuture.allOf(fs); 3060 for (int i = 0; i < k; i++) { 3061 checkIncomplete(f); 3062 checkIncomplete(CompletableFuture.allOf(fs)); 3063 fs[i].complete(one); 3064 } 3065 checkCompletedNormally(f, null); 3066 checkCompletedNormally(CompletableFuture.allOf(fs), null); 3067 } 3068 } 3069 testAllOf_backwards()3070 public void testAllOf_backwards() throws Exception { 3071 for (int k = 1; k < 10; k++) { 3072 CompletableFuture<Integer>[] fs 3073 = (CompletableFuture<Integer>[]) new CompletableFuture[k]; 3074 for (int i = 0; i < k; i++) 3075 fs[i] = new CompletableFuture<>(); 3076 CompletableFuture<Void> f = CompletableFuture.allOf(fs); 3077 for (int i = k - 1; i >= 0; i--) { 3078 checkIncomplete(f); 3079 checkIncomplete(CompletableFuture.allOf(fs)); 3080 fs[i].complete(one); 3081 } 3082 checkCompletedNormally(f, null); 3083 checkCompletedNormally(CompletableFuture.allOf(fs), null); 3084 } 3085 } 3086 testAllOf_exceptional()3087 public void testAllOf_exceptional() throws Exception { 3088 for (int k = 1; k < 10; k++) { 3089 CompletableFuture<Integer>[] fs 3090 = (CompletableFuture<Integer>[]) new CompletableFuture[k]; 3091 CFException ex = new CFException(); 3092 for (int i = 0; i < k; i++) 3093 fs[i] = new CompletableFuture<>(); 3094 CompletableFuture<Void> f = CompletableFuture.allOf(fs); 3095 for (int i = 0; i < k; i++) { 3096 checkIncomplete(f); 3097 checkIncomplete(CompletableFuture.allOf(fs)); 3098 if (i != k / 2) { 3099 fs[i].complete(i); 3100 checkCompletedNormally(fs[i], i); 3101 } else { 3102 fs[i].completeExceptionally(ex); 3103 checkCompletedExceptionally(fs[i], ex); 3104 } 3105 } 3106 checkCompletedWithWrappedException(f, ex); 3107 checkCompletedWithWrappedException(CompletableFuture.allOf(fs), ex); 3108 } 3109 } 3110 3111 /** 3112 * anyOf(no component futures) returns an incomplete future 3113 */ testAnyOf_empty()3114 public void testAnyOf_empty() throws Exception { 3115 for (Integer v1 : new Integer[] { 1, null }) 3116 { 3117 CompletableFuture<Object> f = CompletableFuture.anyOf(); 3118 checkIncomplete(f); 3119 3120 f.complete(v1); 3121 checkCompletedNormally(f, v1); 3122 }} 3123 3124 /** 3125 * anyOf returns a future completed normally with a value when 3126 * a component future does 3127 */ testAnyOf_normal()3128 public void testAnyOf_normal() throws Exception { 3129 for (int k = 0; k < 10; k++) { 3130 CompletableFuture[] fs = new CompletableFuture[k]; 3131 for (int i = 0; i < k; i++) 3132 fs[i] = new CompletableFuture<>(); 3133 CompletableFuture<Object> f = CompletableFuture.anyOf(fs); 3134 checkIncomplete(f); 3135 for (int i = 0; i < k; i++) { 3136 fs[i].complete(i); 3137 checkCompletedNormally(f, 0); 3138 int x = (int) CompletableFuture.anyOf(fs).join(); 3139 assertTrue(0 <= x && x <= i); 3140 } 3141 } 3142 } testAnyOf_normal_backwards()3143 public void testAnyOf_normal_backwards() throws Exception { 3144 for (int k = 0; k < 10; k++) { 3145 CompletableFuture[] fs = new CompletableFuture[k]; 3146 for (int i = 0; i < k; i++) 3147 fs[i] = new CompletableFuture<>(); 3148 CompletableFuture<Object> f = CompletableFuture.anyOf(fs); 3149 checkIncomplete(f); 3150 for (int i = k - 1; i >= 0; i--) { 3151 fs[i].complete(i); 3152 checkCompletedNormally(f, k - 1); 3153 int x = (int) CompletableFuture.anyOf(fs).join(); 3154 assertTrue(i <= x && x <= k - 1); 3155 } 3156 } 3157 } 3158 3159 /** 3160 * anyOf result completes exceptionally when any component does. 3161 */ testAnyOf_exceptional()3162 public void testAnyOf_exceptional() throws Exception { 3163 for (int k = 0; k < 10; k++) { 3164 CompletableFuture[] fs = new CompletableFuture[k]; 3165 CFException[] exs = new CFException[k]; 3166 for (int i = 0; i < k; i++) { 3167 fs[i] = new CompletableFuture<>(); 3168 exs[i] = new CFException(); 3169 } 3170 CompletableFuture<Object> f = CompletableFuture.anyOf(fs); 3171 checkIncomplete(f); 3172 for (int i = 0; i < k; i++) { 3173 fs[i].completeExceptionally(exs[i]); 3174 checkCompletedWithWrappedException(f, exs[0]); 3175 checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs)); 3176 } 3177 } 3178 } 3179 testAnyOf_exceptional_backwards()3180 public void testAnyOf_exceptional_backwards() throws Exception { 3181 for (int k = 0; k < 10; k++) { 3182 CompletableFuture[] fs = new CompletableFuture[k]; 3183 CFException[] exs = new CFException[k]; 3184 for (int i = 0; i < k; i++) { 3185 fs[i] = new CompletableFuture<>(); 3186 exs[i] = new CFException(); 3187 } 3188 CompletableFuture<Object> f = CompletableFuture.anyOf(fs); 3189 checkIncomplete(f); 3190 for (int i = k - 1; i >= 0; i--) { 3191 fs[i].completeExceptionally(exs[i]); 3192 checkCompletedWithWrappedException(f, exs[k - 1]); 3193 checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs)); 3194 } 3195 } 3196 } 3197 3198 /** 3199 * Completion methods throw NullPointerException with null arguments 3200 */ testNPE()3201 public void testNPE() { 3202 CompletableFuture<Integer> f = new CompletableFuture<>(); 3203 CompletableFuture<Integer> g = new CompletableFuture<>(); 3204 CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null; 3205 ThreadExecutor exec = new ThreadExecutor(); 3206 3207 Runnable[] throwingActions = { 3208 () -> CompletableFuture.supplyAsync(null), 3209 () -> CompletableFuture.supplyAsync(null, exec), 3210 () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.SYNC, 42), null), 3211 3212 () -> CompletableFuture.runAsync(null), 3213 () -> CompletableFuture.runAsync(null, exec), 3214 () -> CompletableFuture.runAsync(() -> {}, null), 3215 3216 () -> f.completeExceptionally(null), 3217 3218 () -> f.thenApply(null), 3219 () -> f.thenApplyAsync(null), 3220 () -> f.thenApplyAsync((x) -> x, null), 3221 () -> f.thenApplyAsync(null, exec), 3222 3223 () -> f.thenAccept(null), 3224 () -> f.thenAcceptAsync(null), 3225 () -> f.thenAcceptAsync((x) -> {} , null), 3226 () -> f.thenAcceptAsync(null, exec), 3227 3228 () -> f.thenRun(null), 3229 () -> f.thenRunAsync(null), 3230 () -> f.thenRunAsync(() -> {} , null), 3231 () -> f.thenRunAsync(null, exec), 3232 3233 () -> f.thenCombine(g, null), 3234 () -> f.thenCombineAsync(g, null), 3235 () -> f.thenCombineAsync(g, null, exec), 3236 () -> f.thenCombine(nullFuture, (x, y) -> x), 3237 () -> f.thenCombineAsync(nullFuture, (x, y) -> x), 3238 () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec), 3239 () -> f.thenCombineAsync(g, (x, y) -> x, null), 3240 3241 () -> f.thenAcceptBoth(g, null), 3242 () -> f.thenAcceptBothAsync(g, null), 3243 () -> f.thenAcceptBothAsync(g, null, exec), 3244 () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}), 3245 () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}), 3246 () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec), 3247 () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null), 3248 3249 () -> f.runAfterBoth(g, null), 3250 () -> f.runAfterBothAsync(g, null), 3251 () -> f.runAfterBothAsync(g, null, exec), 3252 () -> f.runAfterBoth(nullFuture, () -> {}), 3253 () -> f.runAfterBothAsync(nullFuture, () -> {}), 3254 () -> f.runAfterBothAsync(nullFuture, () -> {}, exec), 3255 () -> f.runAfterBothAsync(g, () -> {}, null), 3256 3257 () -> f.applyToEither(g, null), 3258 () -> f.applyToEitherAsync(g, null), 3259 () -> f.applyToEitherAsync(g, null, exec), 3260 () -> f.applyToEither(nullFuture, (x) -> x), 3261 () -> f.applyToEitherAsync(nullFuture, (x) -> x), 3262 () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec), 3263 () -> f.applyToEitherAsync(g, (x) -> x, null), 3264 3265 () -> f.acceptEither(g, null), 3266 () -> f.acceptEitherAsync(g, null), 3267 () -> f.acceptEitherAsync(g, null, exec), 3268 () -> f.acceptEither(nullFuture, (x) -> {}), 3269 () -> f.acceptEitherAsync(nullFuture, (x) -> {}), 3270 () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec), 3271 () -> f.acceptEitherAsync(g, (x) -> {}, null), 3272 3273 () -> f.runAfterEither(g, null), 3274 () -> f.runAfterEitherAsync(g, null), 3275 () -> f.runAfterEitherAsync(g, null, exec), 3276 () -> f.runAfterEither(nullFuture, () -> {}), 3277 () -> f.runAfterEitherAsync(nullFuture, () -> {}), 3278 () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec), 3279 () -> f.runAfterEitherAsync(g, () -> {}, null), 3280 3281 () -> f.thenCompose(null), 3282 () -> f.thenComposeAsync(null), 3283 () -> f.thenComposeAsync(new CompletableFutureInc(ExecutionMode.EXECUTOR), null), 3284 () -> f.thenComposeAsync(null, exec), 3285 3286 () -> f.exceptionally(null), 3287 3288 () -> f.handle(null), 3289 3290 () -> CompletableFuture.allOf((CompletableFuture<?>)null), 3291 () -> CompletableFuture.allOf((CompletableFuture<?>[])null), 3292 () -> CompletableFuture.allOf(f, null), 3293 () -> CompletableFuture.allOf(null, f), 3294 3295 () -> CompletableFuture.anyOf((CompletableFuture<?>)null), 3296 () -> CompletableFuture.anyOf((CompletableFuture<?>[])null), 3297 () -> CompletableFuture.anyOf(f, null), 3298 () -> CompletableFuture.anyOf(null, f), 3299 3300 () -> f.obtrudeException(null), 3301 3302 () -> CompletableFuture.delayedExecutor(1L, SECONDS, null), 3303 () -> CompletableFuture.delayedExecutor(1L, null, new ThreadExecutor()), 3304 () -> CompletableFuture.delayedExecutor(1L, null), 3305 3306 () -> f.orTimeout(1L, null), 3307 () -> f.completeOnTimeout(42, 1L, null), 3308 3309 () -> CompletableFuture.failedFuture(null), 3310 () -> CompletableFuture.failedStage(null), 3311 }; 3312 3313 assertThrows(NullPointerException.class, throwingActions); 3314 assertEquals(0, exec.count.get()); 3315 } 3316 3317 /** 3318 * toCompletableFuture returns this CompletableFuture. 3319 */ testToCompletableFuture()3320 public void testToCompletableFuture() { 3321 CompletableFuture<Integer> f = new CompletableFuture<>(); 3322 assertSame(f, f.toCompletableFuture()); 3323 } 3324 3325 // jdk9 3326 3327 /** 3328 * newIncompleteFuture returns an incomplete CompletableFuture 3329 */ testNewIncompleteFuture()3330 public void testNewIncompleteFuture() { 3331 for (Integer v1 : new Integer[] { 1, null }) 3332 { 3333 CompletableFuture<Integer> f = new CompletableFuture<>(); 3334 CompletableFuture<Integer> g = f.newIncompleteFuture(); 3335 checkIncomplete(f); 3336 checkIncomplete(g); 3337 f.complete(v1); 3338 checkCompletedNormally(f, v1); 3339 checkIncomplete(g); 3340 g.complete(v1); 3341 checkCompletedNormally(g, v1); 3342 assertSame(g.getClass(), CompletableFuture.class); 3343 }} 3344 3345 /** 3346 * completedStage returns a completed CompletionStage 3347 */ testCompletedStage()3348 public void testCompletedStage() { 3349 AtomicInteger x = new AtomicInteger(0); 3350 AtomicReference<Throwable> r = new AtomicReference<Throwable>(); 3351 CompletionStage<Integer> f = CompletableFuture.completedStage(1); 3352 f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);}); 3353 assertEquals(x.get(), 1); 3354 assertNull(r.get()); 3355 } 3356 3357 /** 3358 * defaultExecutor by default returns the commonPool if 3359 * it supports more than one thread. 3360 */ testDefaultExecutor()3361 public void testDefaultExecutor() { 3362 CompletableFuture<Integer> f = new CompletableFuture<>(); 3363 Executor e = f.defaultExecutor(); 3364 Executor c = ForkJoinPool.commonPool(); 3365 if (ForkJoinPool.getCommonPoolParallelism() > 1) 3366 assertSame(e, c); 3367 else 3368 assertNotSame(e, c); 3369 } 3370 3371 /** 3372 * failedFuture returns a CompletableFuture completed 3373 * exceptionally with the given Exception 3374 */ testFailedFuture()3375 public void testFailedFuture() { 3376 CFException ex = new CFException(); 3377 CompletableFuture<Integer> f = CompletableFuture.failedFuture(ex); 3378 checkCompletedExceptionally(f, ex); 3379 } 3380 3381 /** 3382 * failedFuture(null) throws NPE 3383 */ testFailedFuture_null()3384 public void testFailedFuture_null() { 3385 try { 3386 CompletableFuture<Integer> f = CompletableFuture.failedFuture(null); 3387 shouldThrow(); 3388 } catch (NullPointerException success) {} 3389 } 3390 3391 /** 3392 * copy returns a CompletableFuture that is completed normally, 3393 * with the same value, when source is. 3394 */ testCopy()3395 public void testCopy() { 3396 CompletableFuture<Integer> f = new CompletableFuture<>(); 3397 CompletableFuture<Integer> g = f.copy(); 3398 checkIncomplete(f); 3399 checkIncomplete(g); 3400 f.complete(1); 3401 checkCompletedNormally(f, 1); 3402 checkCompletedNormally(g, 1); 3403 } 3404 3405 /** 3406 * copy returns a CompletableFuture that is completed exceptionally 3407 * when source is. 3408 */ testCopy2()3409 public void testCopy2() { 3410 CompletableFuture<Integer> f = new CompletableFuture<>(); 3411 CompletableFuture<Integer> g = f.copy(); 3412 checkIncomplete(f); 3413 checkIncomplete(g); 3414 CFException ex = new CFException(); 3415 f.completeExceptionally(ex); 3416 checkCompletedExceptionally(f, ex); 3417 checkCompletedWithWrappedException(g, ex); 3418 } 3419 3420 /** 3421 * minimalCompletionStage returns a CompletableFuture that is 3422 * completed normally, with the same value, when source is. 3423 */ testMinimalCompletionStage()3424 public void testMinimalCompletionStage() { 3425 CompletableFuture<Integer> f = new CompletableFuture<>(); 3426 CompletionStage<Integer> g = f.minimalCompletionStage(); 3427 AtomicInteger x = new AtomicInteger(0); 3428 AtomicReference<Throwable> r = new AtomicReference<Throwable>(); 3429 checkIncomplete(f); 3430 g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);}); 3431 f.complete(1); 3432 checkCompletedNormally(f, 1); 3433 assertEquals(x.get(), 1); 3434 assertNull(r.get()); 3435 } 3436 3437 /** 3438 * minimalCompletionStage returns a CompletableFuture that is 3439 * completed exceptionally when source is. 3440 */ testMinimalCompletionStage2()3441 public void testMinimalCompletionStage2() { 3442 CompletableFuture<Integer> f = new CompletableFuture<>(); 3443 CompletionStage<Integer> g = f.minimalCompletionStage(); 3444 AtomicInteger x = new AtomicInteger(0); 3445 AtomicReference<Throwable> r = new AtomicReference<Throwable>(); 3446 g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);}); 3447 checkIncomplete(f); 3448 CFException ex = new CFException(); 3449 f.completeExceptionally(ex); 3450 checkCompletedExceptionally(f, ex); 3451 assertEquals(x.get(), 0); 3452 assertEquals(r.get().getCause(), ex); 3453 } 3454 3455 /** 3456 * failedStage returns a CompletionStage completed 3457 * exceptionally with the given Exception 3458 */ testFailedStage()3459 public void testFailedStage() { 3460 CFException ex = new CFException(); 3461 CompletionStage<Integer> f = CompletableFuture.failedStage(ex); 3462 AtomicInteger x = new AtomicInteger(0); 3463 AtomicReference<Throwable> r = new AtomicReference<Throwable>(); 3464 f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);}); 3465 assertEquals(x.get(), 0); 3466 assertEquals(r.get(), ex); 3467 } 3468 3469 /** 3470 * completeAsync completes with value of given supplier 3471 */ testCompleteAsync()3472 public void testCompleteAsync() { 3473 for (Integer v1 : new Integer[] { 1, null }) 3474 { 3475 CompletableFuture<Integer> f = new CompletableFuture<>(); 3476 f.completeAsync(() -> v1); 3477 f.join(); 3478 checkCompletedNormally(f, v1); 3479 }} 3480 3481 /** 3482 * completeAsync completes exceptionally if given supplier throws 3483 */ testCompleteAsync2()3484 public void testCompleteAsync2() { 3485 CompletableFuture<Integer> f = new CompletableFuture<>(); 3486 CFException ex = new CFException(); 3487 f.completeAsync(() -> {if (true) throw ex; return 1;}); 3488 try { 3489 f.join(); 3490 shouldThrow(); 3491 } catch (CompletionException success) {} 3492 checkCompletedWithWrappedException(f, ex); 3493 } 3494 3495 /** 3496 * completeAsync with given executor completes with value of given supplier 3497 */ testCompleteAsync3()3498 public void testCompleteAsync3() { 3499 for (Integer v1 : new Integer[] { 1, null }) 3500 { 3501 CompletableFuture<Integer> f = new CompletableFuture<>(); 3502 ThreadExecutor executor = new ThreadExecutor(); 3503 f.completeAsync(() -> v1, executor); 3504 assertSame(v1, f.join()); 3505 checkCompletedNormally(f, v1); 3506 assertEquals(1, executor.count.get()); 3507 }} 3508 3509 /** 3510 * completeAsync with given executor completes exceptionally if 3511 * given supplier throws 3512 */ testCompleteAsync4()3513 public void testCompleteAsync4() { 3514 CompletableFuture<Integer> f = new CompletableFuture<>(); 3515 CFException ex = new CFException(); 3516 ThreadExecutor executor = new ThreadExecutor(); 3517 f.completeAsync(() -> {if (true) throw ex; return 1;}, executor); 3518 try { 3519 f.join(); 3520 shouldThrow(); 3521 } catch (CompletionException success) {} 3522 checkCompletedWithWrappedException(f, ex); 3523 assertEquals(1, executor.count.get()); 3524 } 3525 3526 /** 3527 * orTimeout completes with TimeoutException if not complete 3528 */ testOrTimeout_timesOut()3529 public void testOrTimeout_timesOut() { 3530 long timeoutMillis = timeoutMillis(); 3531 CompletableFuture<Integer> f = new CompletableFuture<>(); 3532 long startTime = System.nanoTime(); 3533 f.orTimeout(timeoutMillis, MILLISECONDS); 3534 checkCompletedWithTimeoutException(f); 3535 assertTrue(millisElapsedSince(startTime) >= timeoutMillis); 3536 } 3537 3538 /** 3539 * orTimeout completes normally if completed before timeout 3540 */ testOrTimeout_completed()3541 public void testOrTimeout_completed() { 3542 for (Integer v1 : new Integer[] { 1, null }) 3543 { 3544 CompletableFuture<Integer> f = new CompletableFuture<>(); 3545 CompletableFuture<Integer> g = new CompletableFuture<>(); 3546 long startTime = System.nanoTime(); 3547 f.complete(v1); 3548 f.orTimeout(LONG_DELAY_MS, MILLISECONDS); 3549 g.orTimeout(LONG_DELAY_MS, MILLISECONDS); 3550 g.complete(v1); 3551 checkCompletedNormally(f, v1); 3552 checkCompletedNormally(g, v1); 3553 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); 3554 }} 3555 3556 /** 3557 * completeOnTimeout completes with given value if not complete 3558 */ 3559 public void testCompleteOnTimeout_timesOut() { 3560 testInParallel(() -> testCompleteOnTimeout_timesOut(42), 3561 () -> testCompleteOnTimeout_timesOut(null)); 3562 } 3563 testCompleteOnTimeout_timesOut(Integer v)3564 public void testCompleteOnTimeout_timesOut(Integer v) { 3565 long timeoutMillis = timeoutMillis(); 3566 CompletableFuture<Integer> f = new CompletableFuture<>(); 3567 long startTime = System.nanoTime(); 3568 f.completeOnTimeout(v, timeoutMillis, MILLISECONDS); 3569 assertSame(v, f.join()); 3570 assertTrue(millisElapsedSince(startTime) >= timeoutMillis); 3571 f.complete(99); // should have no effect 3572 checkCompletedNormally(f, v); 3573 } 3574 3575 /** 3576 * completeOnTimeout has no effect if completed within timeout 3577 */ testCompleteOnTimeout_completed()3578 public void testCompleteOnTimeout_completed() { 3579 for (Integer v1 : new Integer[] { 1, null }) 3580 { 3581 CompletableFuture<Integer> f = new CompletableFuture<>(); 3582 CompletableFuture<Integer> g = new CompletableFuture<>(); 3583 long startTime = System.nanoTime(); 3584 f.complete(v1); 3585 f.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS); 3586 g.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS); 3587 g.complete(v1); 3588 checkCompletedNormally(f, v1); 3589 checkCompletedNormally(g, v1); 3590 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); 3591 }} 3592 3593 /** 3594 * delayedExecutor returns an executor that delays submission 3595 */ 3596 public void testDelayedExecutor() { 3597 testInParallel(() -> testDelayedExecutor(null, null), 3598 () -> testDelayedExecutor(null, 1), 3599 () -> testDelayedExecutor(new ThreadExecutor(), 1), 3600 () -> testDelayedExecutor(new ThreadExecutor(), 1)); 3601 } 3602 testDelayedExecutor(Executor executor, Integer v)3603 public void testDelayedExecutor(Executor executor, Integer v) throws Exception { 3604 long timeoutMillis = timeoutMillis(); 3605 // Use an "unreasonably long" long timeout to catch lingering threads 3606 long longTimeoutMillis = 1000 * 60 * 60 * 24; 3607 final Executor delayer, longDelayer; 3608 if (executor == null) { 3609 delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS); 3610 longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS); 3611 } else { 3612 delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS, executor); 3613 longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS, executor); 3614 } 3615 long startTime = System.nanoTime(); 3616 CompletableFuture<Integer> f = 3617 CompletableFuture.supplyAsync(() -> v, delayer); 3618 CompletableFuture<Integer> g = 3619 CompletableFuture.supplyAsync(() -> v, longDelayer); 3620 3621 assertNull(g.getNow(null)); 3622 3623 assertSame(v, f.get(LONG_DELAY_MS, MILLISECONDS)); 3624 long millisElapsed = millisElapsedSince(startTime); 3625 assertTrue(millisElapsed >= timeoutMillis); 3626 assertTrue(millisElapsed < LONG_DELAY_MS / 2); 3627 3628 checkCompletedNormally(f, v); 3629 3630 checkIncomplete(g); 3631 assertTrue(g.cancel(true)); 3632 } 3633 3634 //--- tests of implementation details; not part of official tck --- 3635 3636 Object resultOf(CompletableFuture<?> f) { 3637 try { 3638 java.lang.reflect.Field resultField 3639 = CompletableFuture.class.getDeclaredField("result"); 3640 resultField.setAccessible(true); 3641 return resultField.get(f); 3642 } catch (Throwable t) { throw new AssertionError(t); } 3643 } 3644 3645 public void testExceptionPropagationReusesResultObject() { 3646 if (!testImplementationDetails) return; 3647 for (ExecutionMode m : ExecutionMode.values()) 3648 { 3649 final CFException ex = new CFException(); 3650 final CompletableFuture<Integer> v42 = CompletableFuture.completedFuture(42); 3651 final CompletableFuture<Integer> incomplete = new CompletableFuture<>(); 3652 3653 List<Function<CompletableFuture<Integer>, CompletableFuture<?>>> funs 3654 = new ArrayList<>(); 3655 3656 funs.add((y) -> m.thenRun(y, new Noop(m))); 3657 funs.add((y) -> m.thenAccept(y, new NoopConsumer(m))); 3658 funs.add((y) -> m.thenApply(y, new IncFunction(m))); 3659 3660 funs.add((y) -> m.runAfterEither(y, incomplete, new Noop(m))); 3661 funs.add((y) -> m.acceptEither(y, incomplete, new NoopConsumer(m))); 3662 funs.add((y) -> m.applyToEither(y, incomplete, new IncFunction(m))); 3663 3664 funs.add((y) -> m.runAfterBoth(y, v42, new Noop(m))); 3665 funs.add((y) -> m.thenAcceptBoth(y, v42, new SubtractAction(m))); 3666 funs.add((y) -> m.thenCombine(y, v42, new SubtractFunction(m))); 3667 3668 funs.add((y) -> m.whenComplete(y, (Integer r, Throwable t) -> {})); 3669 3670 funs.add((y) -> m.thenCompose(y, new CompletableFutureInc(m))); 3671 3672 funs.add((y) -> CompletableFuture.allOf(new CompletableFuture<?>[] {y, v42})); 3673 funs.add((y) -> CompletableFuture.anyOf(new CompletableFuture<?>[] {y, incomplete})); 3674 3675 for (Function<CompletableFuture<Integer>, CompletableFuture<?>> 3676 fun : funs) { 3677 CompletableFuture<Integer> f = new CompletableFuture<>(); 3678 f.completeExceptionally(ex); 3679 CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m)); 3680 checkCompletedWithWrappedException(src, ex); 3681 CompletableFuture<?> dep = fun.apply(src); 3682 checkCompletedWithWrappedException(dep, ex); 3683 assertSame(resultOf(src), resultOf(dep)); 3684 } 3685 3686 for (Function<CompletableFuture<Integer>, CompletableFuture<?>> 3687 fun : funs) { 3688 CompletableFuture<Integer> f = new CompletableFuture<>(); 3689 CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m)); 3690 CompletableFuture<?> dep = fun.apply(src); 3691 f.completeExceptionally(ex); 3692 checkCompletedWithWrappedException(src, ex); 3693 checkCompletedWithWrappedException(dep, ex); 3694 assertSame(resultOf(src), resultOf(dep)); 3695 } 3696 3697 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 3698 for (Function<CompletableFuture<Integer>, CompletableFuture<?>> 3699 fun : funs) { 3700 CompletableFuture<Integer> f = new CompletableFuture<>(); 3701 f.cancel(mayInterruptIfRunning); 3702 checkCancelled(f); 3703 CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m)); 3704 checkCompletedWithWrappedCancellationException(src); 3705 CompletableFuture<?> dep = fun.apply(src); 3706 checkCompletedWithWrappedCancellationException(dep); 3707 assertSame(resultOf(src), resultOf(dep)); 3708 } 3709 3710 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) 3711 for (Function<CompletableFuture<Integer>, CompletableFuture<?>> 3712 fun : funs) { 3713 CompletableFuture<Integer> f = new CompletableFuture<>(); 3714 CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m)); 3715 CompletableFuture<?> dep = fun.apply(src); 3716 f.cancel(mayInterruptIfRunning); 3717 checkCancelled(f); 3718 checkCompletedWithWrappedCancellationException(src); 3719 checkCompletedWithWrappedCancellationException(dep); 3720 assertSame(resultOf(src), resultOf(dep)); 3721 } 3722 }} 3723 3724 /** 3725 * Minimal completion stages throw UOE for all non-CompletionStage methods 3726 */ testMinimalCompletionStage_minimality()3727 public void testMinimalCompletionStage_minimality() { 3728 if (!testImplementationDetails) return; 3729 Function<Method, String> toSignature = 3730 (method) -> method.getName() + Arrays.toString(method.getParameterTypes()); 3731 Predicate<Method> isNotStatic = 3732 (method) -> (method.getModifiers() & Modifier.STATIC) == 0; 3733 List<Method> minimalMethods = 3734 Stream.of(Object.class, CompletionStage.class) 3735 .flatMap((klazz) -> Stream.of(klazz.getMethods())) 3736 .filter(isNotStatic) 3737 .collect(Collectors.toList()); 3738 // Methods from CompletableFuture permitted NOT to throw UOE 3739 String[] signatureWhitelist = { 3740 "newIncompleteFuture[]", 3741 "defaultExecutor[]", 3742 "minimalCompletionStage[]", 3743 "copy[]", 3744 }; 3745 Set<String> permittedMethodSignatures = 3746 Stream.concat(minimalMethods.stream().map(toSignature), 3747 Stream.of(signatureWhitelist)) 3748 .collect(Collectors.toSet()); 3749 List<Method> allMethods = Stream.of(CompletableFuture.class.getMethods()) 3750 .filter(isNotStatic) 3751 .filter((method) -> !permittedMethodSignatures.contains(toSignature.apply(method))) 3752 .collect(Collectors.toList()); 3753 3754 CompletionStage<Integer> minimalStage = 3755 new CompletableFuture<Integer>().minimalCompletionStage(); 3756 3757 List<Method> bugs = new ArrayList<>(); 3758 for (Method method : allMethods) { 3759 Class<?>[] parameterTypes = method.getParameterTypes(); 3760 Object[] args = new Object[parameterTypes.length]; 3761 // Manufacture boxed primitives for primitive params 3762 for (int i = 0; i < args.length; i++) { 3763 Class<?> type = parameterTypes[i]; 3764 if (parameterTypes[i] == boolean.class) 3765 args[i] = false; 3766 else if (parameterTypes[i] == int.class) 3767 args[i] = 0; 3768 else if (parameterTypes[i] == long.class) 3769 args[i] = 0L; 3770 } 3771 try { 3772 method.invoke(minimalStage, args); 3773 bugs.add(method); 3774 } 3775 catch (java.lang.reflect.InvocationTargetException expected) { 3776 if (! (expected.getCause() instanceof UnsupportedOperationException)) { 3777 bugs.add(method); 3778 // expected.getCause().printStackTrace(); 3779 } 3780 } 3781 catch (ReflectiveOperationException bad) { throw new Error(bad); } 3782 } 3783 if (!bugs.isEmpty()) 3784 throw new Error("Methods did not throw UOE: " + bugs.toString()); 3785 } 3786 3787 static class Monad { 3788 static class ZeroException extends RuntimeException { ZeroException()3789 public ZeroException() { super("monadic zero"); } 3790 } 3791 // "return", "unit" unit(T value)3792 static <T> CompletableFuture<T> unit(T value) { 3793 return completedFuture(value); 3794 } 3795 // monadic zero ? zero()3796 static <T> CompletableFuture<T> zero() { 3797 return failedFuture(new ZeroException()); 3798 } 3799 // >=> compose(Function<T, CompletableFuture<U>> f, Function<U, CompletableFuture<V>> g)3800 static <T,U,V> Function<T, CompletableFuture<V>> compose 3801 (Function<T, CompletableFuture<U>> f, 3802 Function<U, CompletableFuture<V>> g) { 3803 return (x) -> f.apply(x).thenCompose(g); 3804 } 3805 assertZero(CompletableFuture<?> f)3806 static void assertZero(CompletableFuture<?> f) { 3807 try { 3808 f.getNow(null); 3809 throw new AssertionFailedError("should throw"); 3810 } catch (CompletionException success) { 3811 assertTrue(success.getCause() instanceof ZeroException); 3812 } 3813 } 3814 assertFutureEquals(CompletableFuture<T> f, CompletableFuture<T> g)3815 static <T> void assertFutureEquals(CompletableFuture<T> f, 3816 CompletableFuture<T> g) { 3817 T fval = null, gval = null; 3818 Throwable fex = null, gex = null; 3819 3820 try { fval = f.get(); } 3821 catch (ExecutionException ex) { fex = ex.getCause(); } 3822 catch (Throwable ex) { fex = ex; } 3823 3824 try { gval = g.get(); } 3825 catch (ExecutionException ex) { gex = ex.getCause(); } 3826 catch (Throwable ex) { gex = ex; } 3827 3828 if (fex != null || gex != null) 3829 assertSame(fex.getClass(), gex.getClass()); 3830 else 3831 assertEquals(fval, gval); 3832 } 3833 3834 static class PlusFuture<T> extends CompletableFuture<T> { 3835 AtomicReference<Throwable> firstFailure = new AtomicReference<>(null); 3836 } 3837 3838 /** Implements "monadic plus". */ plus(CompletableFuture<? extends T> f, CompletableFuture<? extends T> g)3839 static <T> CompletableFuture<T> plus(CompletableFuture<? extends T> f, 3840 CompletableFuture<? extends T> g) { 3841 PlusFuture<T> plus = new PlusFuture<T>(); 3842 BiConsumer<T, Throwable> action = (T result, Throwable ex) -> { 3843 try { 3844 if (ex == null) { 3845 if (plus.complete(result)) 3846 if (plus.firstFailure.get() != null) 3847 plus.firstFailure.set(null); 3848 } 3849 else if (plus.firstFailure.compareAndSet(null, ex)) { 3850 if (plus.isDone()) 3851 plus.firstFailure.set(null); 3852 } 3853 else { 3854 // first failure has precedence 3855 Throwable first = plus.firstFailure.getAndSet(null); 3856 3857 // may fail with "Self-suppression not permitted" 3858 try { first.addSuppressed(ex); } 3859 catch (Exception ignored) {} 3860 3861 plus.completeExceptionally(first); 3862 } 3863 } catch (Throwable unexpected) { 3864 plus.completeExceptionally(unexpected); 3865 } 3866 }; 3867 f.whenComplete(action); 3868 g.whenComplete(action); 3869 return plus; 3870 } 3871 } 3872 3873 /** 3874 * CompletableFuture is an additive monad - sort of. 3875 * https://en.wikipedia.org/wiki/Monad_(functional_programming)#Additive_monads 3876 */ testAdditiveMonad()3877 public void testAdditiveMonad() throws Throwable { 3878 Function<Long, CompletableFuture<Long>> unit = Monad::unit; 3879 CompletableFuture<Long> zero = Monad.zero(); 3880 3881 // Some mutually non-commutative functions 3882 Function<Long, CompletableFuture<Long>> triple 3883 = (x) -> Monad.unit(3 * x); 3884 Function<Long, CompletableFuture<Long>> inc 3885 = (x) -> Monad.unit(x + 1); 3886 3887 // unit is a right identity: m >>= unit === m 3888 Monad.assertFutureEquals(inc.apply(5L).thenCompose(unit), 3889 inc.apply(5L)); 3890 // unit is a left identity: (unit x) >>= f === f x 3891 Monad.assertFutureEquals(unit.apply(5L).thenCompose(inc), 3892 inc.apply(5L)); 3893 3894 // associativity: (m >>= f) >>= g === m >>= ( \x -> (f x >>= g) ) 3895 Monad.assertFutureEquals( 3896 unit.apply(5L).thenCompose(inc).thenCompose(triple), 3897 unit.apply(5L).thenCompose((x) -> inc.apply(x).thenCompose(triple))); 3898 3899 // The case for CompletableFuture as an additive monad is weaker... 3900 3901 // zero is a monadic zero 3902 Monad.assertZero(zero); 3903 3904 // left zero: zero >>= f === zero 3905 Monad.assertZero(zero.thenCompose(inc)); 3906 // right zero: f >>= (\x -> zero) === zero 3907 Monad.assertZero(inc.apply(5L).thenCompose((x) -> zero)); 3908 3909 // f plus zero === f 3910 Monad.assertFutureEquals(Monad.unit(5L), 3911 Monad.plus(Monad.unit(5L), zero)); 3912 // zero plus f === f 3913 Monad.assertFutureEquals(Monad.unit(5L), 3914 Monad.plus(zero, Monad.unit(5L))); 3915 // zero plus zero === zero 3916 Monad.assertZero(Monad.plus(zero, zero)); 3917 { 3918 CompletableFuture<Long> f = Monad.plus(Monad.unit(5L), 3919 Monad.unit(8L)); 3920 // non-determinism 3921 assertTrue(f.get() == 5L || f.get() == 8L); 3922 } 3923 3924 CompletableFuture<Long> godot = new CompletableFuture<>(); 3925 // f plus godot === f (doesn't wait for godot) 3926 Monad.assertFutureEquals(Monad.unit(5L), 3927 Monad.plus(Monad.unit(5L), godot)); 3928 // godot plus f === f (doesn't wait for godot) 3929 Monad.assertFutureEquals(Monad.unit(5L), 3930 Monad.plus(godot, Monad.unit(5L))); 3931 } 3932 3933 // static <U> U join(CompletionStage<U> stage) { 3934 // CompletableFuture<U> f = new CompletableFuture<>(); 3935 // stage.whenComplete((v, ex) -> { 3936 // if (ex != null) f.completeExceptionally(ex); else f.complete(v); 3937 // }); 3938 // return f.join(); 3939 // } 3940 3941 // static <U> boolean isDone(CompletionStage<U> stage) { 3942 // CompletableFuture<U> f = new CompletableFuture<>(); 3943 // stage.whenComplete((v, ex) -> { 3944 // if (ex != null) f.completeExceptionally(ex); else f.complete(v); 3945 // }); 3946 // return f.isDone(); 3947 // } 3948 3949 // static <U> U join2(CompletionStage<U> stage) { 3950 // return stage.toCompletableFuture().copy().join(); 3951 // } 3952 3953 // static <U> boolean isDone2(CompletionStage<U> stage) { 3954 // return stage.toCompletableFuture().copy().isDone(); 3955 // } 3956 3957 } 3958