--- old/test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MockListener.java 2017-11-30 04:05:37.984706371 -0800 +++ new/test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MockListener.java 2017-11-30 04:05:37.757686530 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,112 +20,353 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package jdk.incubator.http.internal.websocket; -import jdk.incubator.http.internal.websocket.TestSupport.F1; -import jdk.incubator.http.internal.websocket.TestSupport.F2; -import jdk.incubator.http.internal.websocket.TestSupport.F3; -import jdk.incubator.http.internal.websocket.TestSupport.InvocationChecker; -import jdk.incubator.http.internal.websocket.TestSupport.InvocationExpectation; -import jdk.incubator.http.internal.websocket.TestSupport.Mock; import jdk.incubator.http.WebSocket; -import jdk.incubator.http.WebSocket.Listener; import jdk.incubator.http.WebSocket.MessagePart; + import java.nio.ByteBuffer; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; - -final class MockListener implements Listener, Mock { - - private final InvocationChecker checker; - - @Override - public CompletableFuture expectations(long timeout, TimeUnit unit) { - return checker.expectations(timeout, unit); - } - - public static final class Builder { - private final List expectations = new LinkedList<>(); +import static jdk.incubator.http.internal.websocket.TestSupport.fullCopy; - Builder expectOnOpen(F1 predicate) { - InvocationExpectation e = new InvocationExpectation("onOpen", - args -> predicate.apply((WebSocket) args[0])); - expectations.add(e); - return this; - } - - Builder expectOnPing(F2 predicate) { - InvocationExpectation e = new InvocationExpectation("onPing", - args -> predicate.apply((WebSocket) args[0], (ByteBuffer) args[1])); - expectations.add(e); - return this; - } - - Builder expectOnClose(F3 predicate) { - expectations.add(new InvocationExpectation("onClose", - args -> predicate.apply((WebSocket) args[0], (Integer) args[1], (String) args[2]))); - return this; - } - - Builder expectOnError(F2 predicate) { - expectations.add(new InvocationExpectation("onError", - args -> predicate.apply((WebSocket) args[0], (Throwable) args[1]))); - return this; - } +public class MockListener implements WebSocket.Listener { - MockListener build() { - return new MockListener(new LinkedList<>(expectations)); + private final long bufferSize; + private long count; + private final List invocations = new ArrayList<>(); + private final CompletableFuture lastCall = new CompletableFuture<>(); + + /* + * Typical buffer sizes: 1, n, Long.MAX_VALUE + */ + public MockListener(long bufferSize) { + if (bufferSize < 1) { + throw new IllegalArgumentException(); } - } - - private MockListener(List expectations) { - this.checker = new InvocationChecker(expectations); + this.bufferSize = bufferSize; } @Override public void onOpen(WebSocket webSocket) { - checker.checkInvocation("onOpen", webSocket); + System.out.printf("onOpen(%s)%n", webSocket); + invocations.add(new OnOpen(webSocket)); + onOpen0(webSocket); + } + + protected void onOpen0(WebSocket webSocket) { + replenish(webSocket); } @Override - public CompletionStage onText(WebSocket webSocket, CharSequence message, + public CompletionStage onText(WebSocket webSocket, + CharSequence message, MessagePart part) { - checker.checkInvocation("onText", webSocket, message, part); + System.out.printf("onText(%s, %s, %s)%n", webSocket, message, part); + invocations.add(new OnText(webSocket, message.toString(), part)); + return onText0(webSocket, message, part); + } + + protected CompletionStage onText0(WebSocket webSocket, + CharSequence message, + MessagePart part) { + replenish(webSocket); return null; } @Override - public CompletionStage onBinary(WebSocket webSocket, ByteBuffer message, + public CompletionStage onBinary(WebSocket webSocket, + ByteBuffer message, MessagePart part) { - checker.checkInvocation("onBinary", webSocket, message, part); + System.out.printf("onBinary(%s, %s, %s)%n", webSocket, message, part); + invocations.add(new OnBinary(webSocket, fullCopy(message), part)); + return onBinary0(webSocket, message, part); + } + + protected CompletionStage onBinary0(WebSocket webSocket, + ByteBuffer message, + MessagePart part) { + replenish(webSocket); return null; } @Override public CompletionStage onPing(WebSocket webSocket, ByteBuffer message) { - checker.checkInvocation("onPing", webSocket, message); + System.out.printf("onPing(%s, %s)%n", webSocket, message); + invocations.add(new OnPing(webSocket, fullCopy(message))); + return onPing0(webSocket, message); + } + + protected CompletionStage onPing0(WebSocket webSocket, ByteBuffer message) { + replenish(webSocket); return null; } @Override public CompletionStage onPong(WebSocket webSocket, ByteBuffer message) { - checker.checkInvocation("onPong", webSocket, message); + System.out.printf("onPong(%s, %s)%n", webSocket, message); + invocations.add(new OnPong(webSocket, fullCopy(message))); + return onPong0(webSocket, message); + } + + protected CompletionStage onPong0(WebSocket webSocket, ByteBuffer message) { + replenish(webSocket); return null; } @Override - public CompletionStage onClose(WebSocket webSocket, int statusCode, + public CompletionStage onClose(WebSocket webSocket, + int statusCode, String reason) { - checker.checkInvocation("onClose", webSocket, statusCode, reason); + System.out.printf("onClose(%s, %s, %s)%n", webSocket, statusCode, reason); + invocations.add(new OnClose(webSocket, statusCode, reason)); + lastCall.complete(null); return null; } @Override public void onError(WebSocket webSocket, Throwable error) { - checker.checkInvocation("onError", webSocket, error); + System.out.printf("onError(%s, %s)%n", webSocket, error); + invocations.add(new OnError(webSocket, error == null ? null : error.getClass())); + lastCall.complete(null); + } + + public CompletableFuture onCloseOrOnErrorCalled() { + return lastCall.copy(); + } + + protected void replenish(WebSocket webSocket) { + if (--count <= 0) { + count = bufferSize - bufferSize / 2; + } + webSocket.request(count); + } + + public List invocations() { + return new ArrayList<>(invocations); + } + + public abstract static class ListenerInvocation { + + public static OnOpen onOpen(WebSocket webSocket) { + return new OnOpen(webSocket); + } + + public static OnText onText(WebSocket webSocket, + String text, + MessagePart part) { + return new OnText(webSocket, text, part); + } + + public static OnBinary onBinary(WebSocket webSocket, + ByteBuffer data, + MessagePart part) { + return new OnBinary(webSocket, data, part); + } + + public static OnPing onPing(WebSocket webSocket, + ByteBuffer data) { + return new OnPing(webSocket, data); + } + + public static OnPong onPong(WebSocket webSocket, + ByteBuffer data) { + return new OnPong(webSocket, data); + } + + public static OnClose onClose(WebSocket webSocket, + int statusCode, + String reason) { + return new OnClose(webSocket, statusCode, reason); + } + + public static OnError onError(WebSocket webSocket, + Class clazz) { + return new OnError(webSocket, clazz); + } + + final WebSocket webSocket; + + private ListenerInvocation(WebSocket webSocket) { + this.webSocket = webSocket; + } + } + + public static final class OnOpen extends ListenerInvocation { + + public OnOpen(WebSocket webSocket) { + super(webSocket); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ListenerInvocation that = (ListenerInvocation) o; + return Objects.equals(webSocket, that.webSocket); + } + + @Override + public int hashCode() { + return Objects.hashCode(webSocket); + } + } + + public static final class OnText extends ListenerInvocation { + + final String text; + final MessagePart part; + + public OnText(WebSocket webSocket, String text, MessagePart part) { + super(webSocket); + this.text = text; + this.part = part; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OnText onText = (OnText) o; + return Objects.equals(text, onText.text) && + part == onText.part && + Objects.equals(webSocket, onText.webSocket); + } + + @Override + public int hashCode() { + return Objects.hash(text, part, webSocket); + } + } + + public static final class OnBinary extends ListenerInvocation { + + final ByteBuffer data; + final MessagePart part; + + public OnBinary(WebSocket webSocket, ByteBuffer data, MessagePart part) { + super(webSocket); + this.data = data; + this.part = part; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OnBinary onBinary = (OnBinary) o; + return Objects.equals(data, onBinary.data) && + part == onBinary.part && + Objects.equals(webSocket, onBinary.webSocket); + } + + @Override + public int hashCode() { + return Objects.hash(data, part, webSocket); + } + } + + public static final class OnPing extends ListenerInvocation { + + final ByteBuffer data; + + public OnPing(WebSocket webSocket, ByteBuffer data) { + super(webSocket); + this.data = data; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OnPing onPing = (OnPing) o; + return Objects.equals(data, onPing.data) && + Objects.equals(webSocket, onPing.webSocket); + } + + @Override + public int hashCode() { + return Objects.hash(data, webSocket); + } + } + + public static final class OnPong extends ListenerInvocation { + + final ByteBuffer data; + + public OnPong(WebSocket webSocket, ByteBuffer data) { + super(webSocket); + this.data = data; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OnPong onPong = (OnPong) o; + return Objects.equals(data, onPong.data) && + Objects.equals(webSocket, onPong.webSocket); + } + + @Override + public int hashCode() { + return Objects.hash(data, webSocket); + } + } + + public static final class OnClose extends ListenerInvocation { + + final int statusCode; + final String reason; + + public OnClose(WebSocket webSocket, int statusCode, String reason) { + super(webSocket); + this.statusCode = statusCode; + this.reason = reason; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OnClose onClose = (OnClose) o; + return statusCode == onClose.statusCode && + Objects.equals(reason, onClose.reason) && + Objects.equals(webSocket, onClose.webSocket); + } + + @Override + public int hashCode() { + return Objects.hash(statusCode, reason, webSocket); + } + } + + public static final class OnError extends ListenerInvocation { + + final Class clazz; + + public OnError(WebSocket webSocket, Class clazz) { + super(webSocket); + this.clazz = clazz; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OnError onError = (OnError) o; + return Objects.equals(clazz, onError.clazz) && + Objects.equals(webSocket, onError.webSocket); + } + + @Override + public int hashCode() { + return Objects.hash(clazz, webSocket); + } } }