test/jdk/java/net/httpclient/websocket/java.net.http/jdk/internal/net/http/websocket/TestSupport.java
branchhttp-client-branch
changeset 56092 fd85b2bf2b0d
parent 56089 42208b2f224e
child 56314 f92e7a8a189f
equal deleted inserted replaced
56091:aedd6133e7a0 56092:fd85b2bf2b0d
       
     1 /*
       
     2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 package jdk.internal.net.http.websocket;
       
    24 
       
    25 import java.nio.ByteBuffer;
       
    26 import java.util.Arrays;
       
    27 import java.util.Collections;
       
    28 import java.util.Iterator;
       
    29 import java.util.LinkedList;
       
    30 import java.util.List;
       
    31 import java.util.NoSuchElementException;
       
    32 import java.util.Stack;
       
    33 import java.util.concurrent.CompletableFuture;
       
    34 import java.util.concurrent.CompletionStage;
       
    35 import java.util.function.Consumer;
       
    36 import java.util.function.Predicate;
       
    37 import java.util.regex.Pattern;
       
    38 
       
    39 import static java.util.List.of;
       
    40 import static java.util.Objects.requireNonNull;
       
    41 
       
    42 /*
       
    43  * Auxiliary test infrastructure
       
    44  */
       
    45 final class TestSupport {
       
    46 
       
    47     private TestSupport() { }
       
    48 
       
    49     static <A, B, R> Iterator<R> cartesianIterator(List<A> a,
       
    50                                                    List<B> b,
       
    51                                                    F2<A, B, R> f2) {
       
    52         @SuppressWarnings("unchecked")
       
    53         F<R> t = p -> f2.apply((A) p[0], (B) p[1]);
       
    54         return cartesianIterator(of(a, b), t);
       
    55     }
       
    56 
       
    57     static <A, B, C, R> Iterator<R> cartesianIterator(List<A> a,
       
    58                                                       List<B> b,
       
    59                                                       List<C> c,
       
    60                                                       F3<A, B, C, R> f3) {
       
    61         @SuppressWarnings("unchecked")
       
    62         F<R> t = p -> f3.apply((A) p[0], (B) p[1], (C) p[2]);
       
    63         return cartesianIterator(of(a, b, c), t);
       
    64     }
       
    65 
       
    66     static <A, B, C, D, R> Iterator<R> cartesianIterator(List<A> a,
       
    67                                                          List<B> b,
       
    68                                                          List<C> c,
       
    69                                                          List<D> d,
       
    70                                                          F4<A, B, C, D, R> f4) {
       
    71         @SuppressWarnings("unchecked")
       
    72         F<R> t = p -> f4.apply((A) p[0], (B) p[1], (C) p[2], (D) p[3]);
       
    73         return cartesianIterator(of(a, b, c, d), t);
       
    74     }
       
    75 
       
    76     static <A, B, C, D, E, R> Iterator<R> cartesianIterator(List<A> a,
       
    77                                                             List<B> b,
       
    78                                                             List<C> c,
       
    79                                                             List<D> d,
       
    80                                                             List<E> e,
       
    81                                                             F5<A, B, C, D, E, R> f5) {
       
    82         @SuppressWarnings("unchecked")
       
    83         F<R> t = p -> f5.apply((A) p[0], (B) p[1], (C) p[2], (D) p[3], (E) p[4]);
       
    84         return cartesianIterator(of(a, b, c, d, e), t);
       
    85     }
       
    86 
       
    87     static <R> Iterator<R> cartesianIterator(List<? extends List<?>> params,
       
    88                                              F<R> function) {
       
    89         if (params.isEmpty()) {
       
    90             return Collections.emptyIterator();
       
    91         }
       
    92         for (List<?> l : params) {
       
    93             if (l.isEmpty()) {
       
    94                 return Collections.emptyIterator();
       
    95             }
       
    96         }
       
    97         // Assertion: if we are still here, there is at least a single element
       
    98         // in the product
       
    99         return new Iterator<>() {
       
   100 
       
   101             private final int arity = params.size();
       
   102             private final int[] coordinates = new int[arity];
       
   103             private boolean hasNext = true;
       
   104 
       
   105             @Override
       
   106             public boolean hasNext() {
       
   107                 return hasNext;
       
   108             }
       
   109 
       
   110             @Override
       
   111             public R next() {
       
   112                 if (!hasNext) {
       
   113                     throw new NoSuchElementException();
       
   114                 }
       
   115                 Object[] array = new Object[arity];
       
   116                 for (int i = 0; i < arity; i++) {
       
   117                     array[i] = params.get(i).get(coordinates[i]);
       
   118                 }
       
   119                 int p = arity - 1;
       
   120                 while (p >= 0 && coordinates[p] == params.get(p).size() - 1) {
       
   121                     p--;
       
   122                 }
       
   123                 if (p < 0) {
       
   124                     hasNext = false;
       
   125                 } else {
       
   126                     coordinates[p]++;
       
   127                     for (int i = p + 1; i < arity; i++) {
       
   128                         coordinates[i] = 0;
       
   129                     }
       
   130                 }
       
   131                 return function.apply(array);
       
   132             }
       
   133         };
       
   134     }
       
   135 
       
   136     @FunctionalInterface
       
   137     public interface F1<A, R> {
       
   138         R apply(A a);
       
   139     }
       
   140 
       
   141     @FunctionalInterface
       
   142     public interface F2<A, B, R> {
       
   143         R apply(A a, B b);
       
   144     }
       
   145 
       
   146     @FunctionalInterface
       
   147     public interface F3<A, B, C, R> {
       
   148         R apply(A a, B b, C c);
       
   149     }
       
   150 
       
   151     @FunctionalInterface
       
   152     public interface F4<A, B, C, D, R> {
       
   153         R apply(A a, B b, C c, D d);
       
   154     }
       
   155 
       
   156     @FunctionalInterface
       
   157     public interface F5<A, B, C, D, E, R> {
       
   158         R apply(A a, B b, C c, D d, E e);
       
   159     }
       
   160 
       
   161     @FunctionalInterface
       
   162     public interface F<R> {
       
   163         R apply(Object[] args);
       
   164     }
       
   165 
       
   166     static <T> Iterator<T> iteratorOf1(T element) {
       
   167         return List.of(element).iterator();
       
   168     }
       
   169 
       
   170     @SafeVarargs
       
   171     static <T> Iterator<T> iteratorOf(T... elements) {
       
   172         return List.of(elements).iterator();
       
   173     }
       
   174 
       
   175     static <T> Iterator<T> limit(int maxElements, Iterator<? extends T> elements) {
       
   176         return new Iterator<>() {
       
   177 
       
   178             int count = maxElements;
       
   179 
       
   180             @Override
       
   181             public boolean hasNext() {
       
   182                 return count > 0 && elements.hasNext();
       
   183             }
       
   184 
       
   185             @Override
       
   186             public T next() {
       
   187                 if (!hasNext()) {
       
   188                     throw new NoSuchElementException();
       
   189                 }
       
   190                 count--;
       
   191                 return elements.next();
       
   192             }
       
   193         };
       
   194     }
       
   195 
       
   196     static ByteBuffer fullCopy(ByteBuffer src) {
       
   197         ByteBuffer copy = ByteBuffer.allocate(src.capacity());
       
   198         int p = src.position();
       
   199         int l = src.limit();
       
   200         src.clear();
       
   201         copy.put(src).position(p).limit(l);
       
   202         src.position(p).limit(l);
       
   203         return copy;
       
   204     }
       
   205 
       
   206     static void forEachBufferPartition(ByteBuffer src,
       
   207                                        Consumer<? super Iterable<? extends ByteBuffer>> action) {
       
   208         forEachPartition(src.remaining(),
       
   209                 (lengths) -> {
       
   210                     int end = src.position();
       
   211                     List<ByteBuffer> buffers = new LinkedList<>();
       
   212                     for (int len : lengths) {
       
   213                         ByteBuffer d = src.duplicate();
       
   214                         d.position(end);
       
   215                         d.limit(end + len);
       
   216                         end += len;
       
   217                         buffers.add(d);
       
   218                     }
       
   219                     action.accept(buffers);
       
   220                 });
       
   221     }
       
   222 
       
   223     private static void forEachPartition(int n,
       
   224                                          Consumer<? super Iterable<Integer>> action) {
       
   225         forEachPartition(n, new Stack<>(), action);
       
   226     }
       
   227 
       
   228     private static void forEachPartition(int n,
       
   229                                          Stack<Integer> path,
       
   230                                          Consumer<? super Iterable<Integer>> action) {
       
   231         if (n == 0) {
       
   232             action.accept(path);
       
   233         } else {
       
   234             for (int i = 1; i <= n; i++) {
       
   235                 path.push(i);
       
   236                 forEachPartition(n - i, path, action);
       
   237                 path.pop();
       
   238             }
       
   239         }
       
   240     }
       
   241 
       
   242     static void forEachPermutation(int n, Consumer<? super int[]> c) {
       
   243         int[] a = new int[n];
       
   244         for (int i = 0; i < n; i++) {
       
   245             a[i] = i;
       
   246         }
       
   247         permutations(0, a, c);
       
   248     }
       
   249 
       
   250     private static void permutations(int i, int[] a, Consumer<? super int[]> c) {
       
   251         if (i == a.length) {
       
   252             c.accept(Arrays.copyOf(a, a.length));
       
   253             return;
       
   254         }
       
   255         for (int j = i; j < a.length; j++) {
       
   256             swap(a, i, j);
       
   257             permutations(i + 1, a, c);
       
   258             swap(a, i, j);
       
   259         }
       
   260     }
       
   261 
       
   262     private static void swap(int[] a, int i, int j) {
       
   263         int x = a[i];
       
   264         a[i] = a[j];
       
   265         a[j] = x;
       
   266     }
       
   267 
       
   268     public static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
       
   269                                                        ThrowingProcedure code) {
       
   270         @SuppressWarnings("unchecked")
       
   271         T t = (T) assertThrows(clazz::isInstance, code);
       
   272         return t;
       
   273     }
       
   274 
       
   275     /*
       
   276      * The rationale behind asking for a regex is to not pollute variable names
       
   277      * space in the scope of assertion: if it's something as simple as checking
       
   278      * a message, we can do it inside
       
   279      */
       
   280     @SuppressWarnings("unchecked")
       
   281     static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
       
   282                                                 String messageRegex,
       
   283                                                 ThrowingProcedure code) {
       
   284         requireNonNull(messageRegex, "messagePattern");
       
   285         Predicate<Throwable> p = e -> clazz.isInstance(e)
       
   286                 && Pattern.matches(messageRegex, e.getMessage());
       
   287         return (T) assertThrows(p, code);
       
   288     }
       
   289 
       
   290     static Throwable assertThrows(Predicate<? super Throwable> predicate,
       
   291                                   ThrowingProcedure code) {
       
   292         requireNonNull(predicate, "predicate");
       
   293         requireNonNull(code, "code");
       
   294         Throwable caught = null;
       
   295         try {
       
   296             code.run();
       
   297         } catch (Throwable t) {
       
   298             caught = t;
       
   299         }
       
   300         if (caught == null) {
       
   301             throw new AssertionFailedException("No exception was thrown");
       
   302         }
       
   303         if (predicate.test(caught)) {
       
   304             System.out.println("Got expected exception: " + caught);
       
   305             return caught;
       
   306         }
       
   307         throw new AssertionFailedException("Caught exception didn't match the predicate", caught);
       
   308     }
       
   309 
       
   310     /*
       
   311      * Blocking assertion, waits for completion
       
   312      */
       
   313     static Throwable assertCompletesExceptionally(Class<? extends Throwable> clazz,
       
   314                                                   CompletionStage<?> stage) {
       
   315         CompletableFuture<?> cf =
       
   316                 CompletableFuture.completedFuture(null).thenCompose(x -> stage);
       
   317         return assertThrows(t -> clazz.isInstance(t.getCause()), cf::get);
       
   318     }
       
   319 
       
   320     interface ThrowingProcedure {
       
   321         void run() throws Throwable;
       
   322     }
       
   323 
       
   324     static final class AssertionFailedException extends RuntimeException {
       
   325 
       
   326         private static final long serialVersionUID = 1L;
       
   327 
       
   328         AssertionFailedException(String message) {
       
   329             super(message);
       
   330         }
       
   331 
       
   332         AssertionFailedException(String message, Throwable cause) {
       
   333             super(message, cause);
       
   334         }
       
   335     }
       
   336 }