ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CompletableFutureTest.java
(Generate patch)

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.121 by jsr166, Sun Sep 6 21:14:12 2015 UTC vs.
Revision 1.127 by jsr166, Sun Oct 25 02:58:25 2015 UTC

# Line 8 | Line 8
8   import static java.util.concurrent.TimeUnit.MILLISECONDS;
9   import static java.util.concurrent.TimeUnit.SECONDS;
10  
11 + import java.lang.reflect.Method;
12 + import java.lang.reflect.Modifier;
13 +
14 + import java.util.stream.Collectors;
15 + import java.util.stream.Stream;
16 +
17   import java.util.ArrayList;
18 + import java.util.Arrays;
19   import java.util.List;
20   import java.util.Objects;
21 + import java.util.Set;
22   import java.util.concurrent.Callable;
23   import java.util.concurrent.CancellationException;
24   import java.util.concurrent.CompletableFuture;
# Line 28 | Line 36 | import java.util.function.BiConsumer;
36   import java.util.function.BiFunction;
37   import java.util.function.Consumer;
38   import java.util.function.Function;
39 + import java.util.function.Predicate;
40   import java.util.function.Supplier;
41  
42   import junit.framework.Test;
# Line 828 | Line 837 | public class CompletableFutureTest exten
837          if (!createIncomplete) assertTrue(f.complete(v1));
838          final CompletableFuture<Integer> g = f.exceptionally
839              ((Throwable t) -> {
831                // Should not be called
840                  a.getAndIncrement();
841 <                throw new AssertionError();
841 >                threadFail("should not be called");
842 >                return null;            // unreached
843              });
844          if (createIncomplete) assertTrue(f.complete(v1));
845  
# Line 889 | Line 898 | public class CompletableFutureTest exten
898       * whenComplete action executes on normal completion, propagating
899       * source result.
900       */
901 <    public void testWhenComplete_normalCompletion1() {
901 >    public void testWhenComplete_normalCompletion() {
902          for (ExecutionMode m : ExecutionMode.values())
903          for (boolean createIncomplete : new boolean[] { true, false })
904          for (Integer v1 : new Integer[] { 1, null })
# Line 3567 | Line 3576 | public class CompletableFutureTest exten
3576                         () -> testDelayedExecutor(new ThreadExecutor(), 1));
3577      }
3578  
3570    /**
3571     * delayedExecutor returns an executor that delays submission
3572     */
3579      public void testDelayedExecutor(Executor executor, Integer v) throws Exception {
3580          long timeoutMillis = timeoutMillis();
3581          // Use an "unreasonably long" long timeout to catch lingering threads
# Line 3691 | Line 3697 | public class CompletableFutureTest exten
3697          }
3698      }}
3699  
3700 +    /**
3701 +     * Minimal completion stages throw UOE for all non-CompletionStage methods
3702 +     */
3703 +    public void testMinimalCompletionStage_minimality() {
3704 +        if (!testImplementationDetails) return;
3705 +        Function<Method, String> toSignature =
3706 +            (method) -> method.getName() + Arrays.toString(method.getParameterTypes());
3707 +        Predicate<Method> isNotStatic =
3708 +            (method) -> (method.getModifiers() & Modifier.STATIC) == 0;
3709 +        List<Method> minimalMethods =
3710 +            Stream.of(Object.class, CompletionStage.class)
3711 +            .flatMap((klazz) -> Stream.of(klazz.getMethods()))
3712 +            .filter(isNotStatic)
3713 +            .collect(Collectors.toList());
3714 +        // Methods from CompletableFuture permitted NOT to throw UOE
3715 +        String[] signatureWhitelist = {
3716 +            "newIncompleteFuture[]",
3717 +            "defaultExecutor[]",
3718 +            "minimalCompletionStage[]",
3719 +            "copy[]",
3720 +        };
3721 +        Set<String> permittedMethodSignatures =
3722 +            Stream.concat(minimalMethods.stream().map(toSignature),
3723 +                          Stream.of(signatureWhitelist))
3724 +            .collect(Collectors.toSet());
3725 +        List<Method> allMethods = Stream.of(CompletableFuture.class.getMethods())
3726 +            .filter(isNotStatic)
3727 +            .filter((method) -> !permittedMethodSignatures.contains(toSignature.apply(method)))
3728 +            .collect(Collectors.toList());
3729 +
3730 +        CompletionStage<Integer> minimalStage =
3731 +            new CompletableFuture<Integer>().minimalCompletionStage();
3732 +
3733 +        List<Method> bugs = new ArrayList<>();
3734 +        for (Method method : allMethods) {
3735 +            Class<?>[] parameterTypes = method.getParameterTypes();
3736 +            Object[] args = new Object[parameterTypes.length];
3737 +            // Manufacture boxed primitives for primitive params
3738 +            for (int i = 0; i < args.length; i++) {
3739 +                Class<?> type = parameterTypes[i];
3740 +                if (parameterTypes[i] == boolean.class)
3741 +                    args[i] = false;
3742 +                else if (parameterTypes[i] == int.class)
3743 +                    args[i] = 0;
3744 +                else if (parameterTypes[i] == long.class)
3745 +                    args[i] = 0L;
3746 +            }
3747 +            try {
3748 +                method.invoke(minimalStage, args);
3749 +                bugs.add(method);
3750 +            }
3751 +            catch (java.lang.reflect.InvocationTargetException expected) {
3752 +                if (! (expected.getCause() instanceof UnsupportedOperationException)) {
3753 +                    bugs.add(method);
3754 +                    // expected.getCause().printStackTrace();
3755 +                }
3756 +            }
3757 +            catch (ReflectiveOperationException bad) { throw new Error(bad); }
3758 +        }
3759 +        if (!bugs.isEmpty())
3760 +            throw new Error("Methods did not throw UOE: " + bugs.toString());
3761 +    }
3762 +
3763 + //     static <U> U join(CompletionStage<U> stage) {
3764 + //         CompletableFuture<U> f = new CompletableFuture<>();
3765 + //         stage.whenComplete((v, ex) -> {
3766 + //             if (ex != null) f.completeExceptionally(ex); else f.complete(v);
3767 + //         });
3768 + //         return f.join();
3769 + //     }
3770 +
3771 + //     static <U> boolean isDone(CompletionStage<U> stage) {
3772 + //         CompletableFuture<U> f = new CompletableFuture<>();
3773 + //         stage.whenComplete((v, ex) -> {
3774 + //             if (ex != null) f.completeExceptionally(ex); else f.complete(v);
3775 + //         });
3776 + //         return f.isDone();
3777 + //     }
3778 +
3779 + //     static <U> U join2(CompletionStage<U> stage) {
3780 + //         return stage.toCompletableFuture().copy().join();
3781 + //     }
3782 +
3783 + //     static <U> boolean isDone2(CompletionStage<U> stage) {
3784 + //         return stage.toCompletableFuture().copy().isDone();
3785 + //     }
3786 +
3787   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines