< prev index next >

test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/TestSupport.java

Print this page


   1 /*
   2  * Copyright (c) 2016, 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.incubator.http.internal.websocket;
  24 
  25 import java.nio.ByteBuffer;
  26 import java.util.*;
  27 import java.util.concurrent.*;







  28 import java.util.function.Consumer;
  29 import java.util.function.Predicate;
  30 import java.util.regex.Pattern;
  31 import java.util.stream.Collectors;
  32 import java.util.stream.Stream;
  33 
  34 import static java.util.List.of;
  35 import static java.util.Objects.requireNonNull;
  36 
  37 /*
  38  * Auxiliary test infrastructure
  39  */
  40 final class TestSupport {
  41 
  42     private TestSupport() { }
  43 
  44     static <A, B, R> Iterator<R> cartesianIterator(List<A> a,
  45                                                    List<B> b,
  46                                                    F2<A, B, R> f2) {
  47         @SuppressWarnings("unchecked")
  48         F<R> t = p -> f2.apply((A) p[0], (B) p[1]);
  49         return cartesianIterator(of(a, b), t);
  50     }
  51 
  52     static <A, B, C, R> Iterator<R> cartesianIterator(List<A> a,


 171         return new Iterator<>() {
 172 
 173             int count = maxElements;
 174 
 175             @Override
 176             public boolean hasNext() {
 177                 return count > 0 && elements.hasNext();
 178             }
 179 
 180             @Override
 181             public T next() {
 182                 if (!hasNext()) {
 183                     throw new NoSuchElementException();
 184                 }
 185                 count--;
 186                 return elements.next();
 187             }
 188         };
 189     }
 190 
 191 //    static <T> Iterator<T> filter(Iterator<? extends T> source,
 192 //                                  Predicate<? super T> predicate) {
 193 //        return new Iterator<>() {
 194 //
 195 //            { findNext(); }
 196 //
 197 //            T next;
 198 //            boolean hasNext;
 199 //
 200 //            @Override
 201 //            public boolean hasNext() {
 202 //                return hasNext;
 203 //            }
 204 //
 205 //            @Override
 206 //            public T next() {
 207 //                if (!hasNext) {
 208 //                    throw new NoSuchElementException();
 209 //                }
 210 //                T n = this.next;
 211 //                findNext();
 212 //                return n;
 213 //            }
 214 //
 215 //            void findNext() {
 216 //                while (source.hasNext()) {
 217 //                    T n = source.next();
 218 //                    if (predicate.test(n)) {
 219 //                        hasNext = true;
 220 //                        next = n;
 221 //                        break;
 222 //                    }
 223 //                }
 224 //            }
 225 //        };
 226 //    }
 227 
 228     static ByteBuffer fullCopy(ByteBuffer src) {
 229         ByteBuffer copy = ByteBuffer.allocate(src.capacity());
 230         int p = src.position();
 231         int l = src.limit();
 232         src.clear();
 233         copy.put(src).position(p).limit(l);
 234         src.position(p).limit(l);
 235         return copy;
 236     }
 237 
 238     static void forEachBufferPartition(ByteBuffer src,
 239                                        Consumer<? super Iterable<? extends ByteBuffer>> action) {
 240         forEachPartition(src.remaining(),
 241                 (lengths) -> {
 242                     int end = src.position();
 243                     List<ByteBuffer> buffers = new LinkedList<>();
 244                     for (int len : lengths) {
 245                         ByteBuffer d = src.duplicate();
 246                         d.position(end);
 247                         d.limit(end + len);


 280     }
 281 
 282     private static void permutations(int i, int[] a, Consumer<? super int[]> c) {
 283         if (i == a.length) {
 284             c.accept(Arrays.copyOf(a, a.length));
 285             return;
 286         }
 287         for (int j = i; j < a.length; j++) {
 288             swap(a, i, j);
 289             permutations(i + 1, a, c);
 290             swap(a, i, j);
 291         }
 292     }
 293 
 294     private static void swap(int[] a, int i, int j) {
 295         int x = a[i];
 296         a[i] = a[j];
 297         a[j] = x;
 298     }
 299 
 300     static <T> Iterator<T> concat(Iterator<? extends Iterator<? extends T>> iterators) {
 301         requireNonNull(iterators);
 302         return new Iterator<>() {
 303 
 304             private Iterator<? extends T> current = Collections.emptyIterator();
 305 
 306             @Override
 307             public boolean hasNext() {
 308                 while (!current.hasNext()) {
 309                     if (!iterators.hasNext()) {
 310                         return false;
 311                     } else {
 312                         current = iterators.next();
 313                     }
 314                 }
 315                 return true;
 316             }
 317 
 318             @Override
 319             public T next() {
 320                 if (!hasNext()) {
 321                     throw new NoSuchElementException();
 322                 }
 323                 return current.next();
 324             }
 325         };
 326     }
 327 
 328     interface Mock {
 329 
 330         /*
 331          * Completes exceptionally if there are any expectations that haven't
 332          * been met within the given time period, otherwise completes normally
 333          */
 334         CompletableFuture<Void> expectations(long timeout, TimeUnit unit);
 335     }
 336 
 337     static final class InvocationChecker {
 338 
 339         private final Object lock = new Object();
 340         private final Iterator<InvocationExpectation> expectations;
 341         private final CompletableFuture<Void> expectationsViolation
 342                 = new CompletableFuture<>();
 343 
 344         InvocationChecker(Iterable<InvocationExpectation> expectations) {
 345             this.expectations = requireNonNull(expectations).iterator();
 346         }
 347 
 348         /*
 349          * Completes exceptionally if there are any expectations that haven't
 350          * been met within the given time period, otherwise completes normally
 351          */
 352         CompletableFuture<Void> expectations(long timeout, TimeUnit unit) {
 353             return expectationsViolation
 354                     .orTimeout(timeout, unit)
 355                     .handle((v, t) -> {
 356                         if (t == null) {
 357                             throw new InternalError(
 358                                     "Unexpected normal completion: " + v);
 359                         } else if (t instanceof TimeoutException) {
 360                             synchronized (lock) {
 361                                 if (!expectations.hasNext()) {
 362                                     return null;
 363                                 } else {
 364                                     throw new AssertionFailedException(
 365                                             "More invocations were expected");
 366                                 }
 367                             }
 368                         } else if (t instanceof AssertionFailedException) {
 369                             throw (AssertionFailedException) t;
 370                         } else {
 371                             throw new RuntimeException(t);
 372                         }
 373                     });
 374         }
 375 
 376         void checkInvocation(String name, Object... args) {
 377             synchronized (lock) {
 378                 if (!expectations.hasNext()) {
 379                     expectationsViolation.completeExceptionally(
 380                             new AssertionFailedException(
 381                                     "Less invocations were expected: " + name));
 382                     return;
 383                 }
 384                 InvocationExpectation next = expectations.next();
 385                 if (!next.name.equals(name)) {
 386                     expectationsViolation.completeExceptionally(
 387                             new AssertionFailedException(
 388                                     "A different invocation was expected: " + name)
 389                     );
 390                     return;
 391                 }
 392                 if (!next.predicate.apply(args)) {
 393                     expectationsViolation.completeExceptionally(
 394                             new AssertionFailedException(
 395                                     "Invocation doesn't match the predicate: "
 396                                             + name + ", " + Arrays.toString(args))
 397                     );
 398                 }
 399             }
 400         }
 401     }
 402 
 403     static final class InvocationExpectation {
 404 
 405         final String name;
 406         final F<Boolean> predicate;
 407 
 408         InvocationExpectation(String name, F<Boolean> predicate) {
 409             this.name = requireNonNull(name);
 410             this.predicate = requireNonNull(predicate);
 411         }
 412     }
 413 
 414     static void checkExpectations(Mock... mocks) {
 415         checkExpectations(0, TimeUnit.SECONDS, mocks);
 416     }
 417 
 418     static void checkExpectations(long timeout, TimeUnit unit, Mock... mocks) {
 419         CompletableFuture<?>[] completableFutures = Stream.of(mocks)
 420                 .map(m -> m.expectations(timeout, unit))
 421                 .collect(Collectors.toList()).toArray(new CompletableFuture<?>[0]);
 422         CompletableFuture<Void> cf = CompletableFuture.allOf(completableFutures);
 423         try {
 424             cf.join();
 425         } catch (CompletionException e) {
 426             Throwable cause = e.getCause();
 427             if (cause instanceof AssertionFailedException) {
 428                 throw (AssertionFailedException) cause;
 429             } else {
 430                 throw e;
 431             }
 432         }
 433     }
 434 
 435     public static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
 436                                                        ThrowingProcedure code) {
 437         @SuppressWarnings("unchecked")
 438         T t = (T) assertThrows(clazz::isInstance, code);
 439         return t;
 440     }
 441 
 442     /*
 443      * The rationale behind asking for a regex is to not pollute variable names
 444      * space in the scope of assertion: if it's something as simple as checking
 445      * a message, we can do it inside
 446      */
 447     @SuppressWarnings("unchecked")
 448     static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
 449                                                 String messageRegex,
 450                                                 ThrowingProcedure code) {
 451         requireNonNull(messageRegex, "messagePattern");
 452         Predicate<Throwable> p = e -> clazz.isInstance(e)
 453                 && Pattern.matches(messageRegex, e.getMessage());
 454         return (T) assertThrows(p, code);
 455     }
 456 
 457     static Throwable assertThrows(Predicate<? super Throwable> predicate,
 458                                   ThrowingProcedure code) {
 459         requireNonNull(predicate, "predicate");
 460         requireNonNull(code, "code");
 461         Throwable caught = null;
 462         try {
 463             code.run();
 464         } catch (Throwable t) {
 465             caught = t;
 466         }
 467         if (predicate.test(caught)) {

 468             return caught;
 469         }
 470         if (caught == null) {
 471             throw new AssertionFailedException("No exception was thrown");
 472         }
 473         throw new AssertionFailedException("Caught exception didn't match the predicate", caught);
 474     }
 475 
 476     /*
 477      * Blocking assertion, waits for completion
 478      */
 479     static Throwable assertCompletesExceptionally(Class<? extends Throwable> clazz,
 480                                                   CompletionStage<?> stage) {
 481         CompletableFuture<?> cf =
 482                 CompletableFuture.completedFuture(null).thenCompose(x -> stage);
 483         return assertThrows(t -> clazz.isInstance(t.getCause()), cf::get);
 484     }
 485 
 486     interface ThrowingProcedure {
 487         void run() throws Throwable;
 488     }
 489 
 490     static final class Expectation {
 491 
 492         private final List<Predicate<? super Throwable>> list = new LinkedList<>();
 493 
 494         static Expectation ifExpect(boolean condition,
 495                                     Predicate<? super Throwable> predicate) {
 496             return addPredicate(new Expectation(), condition, predicate);
 497         }
 498 
 499         Expectation orExpect(boolean condition,
 500                              Predicate<? super Throwable> predicate) {
 501             return addPredicate(this, condition, predicate);
 502         }
 503 
 504         static Expectation addPredicate(Expectation e, boolean condition,
 505                                         Predicate<? super Throwable> predicate) {
 506             if (condition) {
 507                 e.list.add(requireNonNull(predicate));
 508             }
 509             return e;
 510         }
 511 
 512         public Throwable assertThrows(ThrowingProcedure code) {
 513             Predicate<Throwable> p;
 514             if (list.isEmpty()) {
 515                 p = Objects::isNull;
 516             } else {
 517                 p = e -> list.stream().anyMatch(x -> x.test(e));
 518             }
 519             return TestSupport.assertThrows(p, code);
 520         }
 521     }
 522 
 523     static final class AssertionFailedException extends RuntimeException {
 524 
 525         private static final long serialVersionUID = 1L;
 526 
 527         AssertionFailedException(String message) {
 528             super(message);
 529         }
 530 
 531         AssertionFailedException(String message, Throwable cause) {
 532             super(message, cause);
 533         }
 534     }
 535 }
   1 /*
   2  * Copyright (c) 2016, 2017, 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.incubator.http.internal.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,


 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);


 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 (predicate.test(caught)) {
 301             System.out.println("Got expected exception: " + caught);
 302             return caught;
 303         }
 304         if (caught == null) {
 305             throw new AssertionFailedException("No exception was thrown");
 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 == t.getCause().getClass(), 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 }
< prev index next >