public void testRecursiveChains() throws Throwable {
  for (  ExecutionMode m : ExecutionMode.values())   for (  boolean addDeadEnds : new boolean[]{true,false}) {
    final int val=42;
    final int n=expensiveTests ? 1_000 : 2;
    CompletableFuture<Integer> head=new CompletableFuture<>();
    CompletableFuture<Integer> tail=head;
    for (int i=0; i < n; i++) {
      if (addDeadEnds)       m.thenApply(tail,null);
      tail=m.thenApply(tail,null);
      if (addDeadEnds)       m.applyToEither(tail,tail,null);
      tail=m.applyToEither(tail,tail,null);
      if (addDeadEnds)       m.thenCombine(tail,tail,null);
      tail=m.thenCombine(tail,tail,null);
    }
    head.complete(val);
    assertEquals(val + 3 * n,(int)tail.join());
  }
}

public void testRecursiveChains ( ) throws Throwable { for ( ExecutionMode m : ExecutionMode . values ( ) ) for ( boolean addDeadEnds : new boolean [ ] { true , false } ) { final int val = 42 ; final int n = expensiveTests ? 1_000 : 2 ; CompletableFuture < Integer > head = new CompletableFuture < > ( ) ; CompletableFuture < Integer > tail = head ; for ( int i = 0 ; i < n ; i ++ ) { if ( addDeadEnds ) m . thenApply ( tail , null ) ; tail = m . thenApply ( tail , null ) ; if ( addDeadEnds ) m . applyToEither ( tail , tail , null ) ; tail = m . applyToEither ( tail , tail , null ) ; if ( addDeadEnds ) m . thenCombine ( tail , tail , null ) ; tail = m . thenCombine ( tail , tail , null ) ; } head . complete ( val ) ; assertEquals ( val + 3 * n , ( int ) tail . join ( ) ) ; } }
test long recursive chains of completablefutures with cascading completions
