From 455cc3d2e23a87c48c32eff9b31ba53b5567fc61 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 16 May 2019 15:43:22 +1000 Subject: [PATCH] improvements to the jetty-websocket configuration testing Signed-off-by: Lachlan Roberts --- .../common/JettyWebSocketFrameHandler.java | 3 +- .../server/JettyWebSocketServletFactory.java | 4 +- .../tests/client/ClientConfigTest.java | 186 +++++------ .../tests/server/ServerConfigTest.java | 301 ++++++++++++++++++ 4 files changed, 385 insertions(+), 109 deletions(-) create mode 100644 jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java index f0143207de5..6a967fb2cd9 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java +++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java @@ -148,8 +148,7 @@ public class JettyWebSocketFrameHandler implements FrameHandler textSink = JettyWebSocketFrameHandlerFactory.createMessageSink(textHandle, textSinkClass, executor, coreSession.getMaxTextMessageSize()); if (binaryHandle != null) - binarySink = JettyWebSocketFrameHandlerFactory - .createMessageSink(binaryHandle, binarySinkClass, executor, coreSession.getMaxBinaryMessageSize()); + binarySink = JettyWebSocketFrameHandlerFactory.createMessageSink(binaryHandle, binarySinkClass, executor, coreSession.getMaxBinaryMessageSize()); if (openHandle != null) openHandle.invoke(); diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java b/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java index 62b882ec29e..0f40a81ec99 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java +++ b/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java @@ -74,7 +74,7 @@ public class JettyWebSocketServletFactory public long getMaxBinaryMessageSize() { - return factory.getMaxFrameSize(); + return factory.getMaxBinaryMessageSize(); } public void setMaxBinaryMessageSize(long bufferSize) @@ -89,7 +89,7 @@ public class JettyWebSocketServletFactory public void setMaxTextMessageSize(long bufferSize) { - factory.setMaxBinaryMessageSize(bufferSize); + factory.setMaxTextMessageSize(bufferSize); } public int getOutputBufferSize() diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java index 7a6dafc7e93..2fab17cfdcf 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java @@ -22,6 +22,7 @@ import java.net.URI; import java.time.Duration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -30,6 +31,7 @@ import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.MessageTooLargeException; import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketTimeoutException; import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.client.WebSocketClient; @@ -42,7 +44,9 @@ import org.eclipse.jetty.websocket.tests.EchoSocket; import org.eclipse.jetty.websocket.tests.EventSocket; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; @@ -54,19 +58,25 @@ public class ClientConfigTest { private Server server; private WebSocketClient client; + private ServerConnector connector; + + private EchoSocket serverSocket = new EchoSocket(); private static String message = "this message is over 20 characters long"; - private final int inputBufferSize = 200; private final int maxMessageSize = 20; private final int idleTimeout = 500; + public static Stream data() + { + return Stream.of("clientConfig", "annotatedConfig", "sessionConfig").map(Arguments::of); + } + @BeforeEach public void start() throws Exception { server = new Server(); - ServerConnector connector = new ServerConnector(server); - connector.setPort(8080); + connector = new ServerConnector(server); server.addConnector(connector); ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); @@ -74,7 +84,7 @@ public class ClientConfigTest server.setHandler(contextHandler); JettyWebSocketServerContainer container = JettyWebSocketServletContainerInitializer.configureContext(contextHandler); - container.addMapping("/", (req, resp)->new EchoSocket()); + container.addMapping("/", (req, resp)->serverSocket); server.start(); client = new WebSocketClient(); @@ -93,13 +103,48 @@ public class ClientConfigTest { } - @Test - public void testInputBufferSize() throws Exception + @WebSocket + public class SessionConfigEndpoint extends EventSocket { - client.setInputBufferSize(inputBufferSize); + @Override + public void onOpen(Session session) + { + session.setIdleTimeout(Duration.ofMillis(idleTimeout)); + session.setMaxTextMessageSize(maxMessageSize); + session.setMaxBinaryMessageSize(maxMessageSize); + session.setInputBufferSize(inputBufferSize); + super.onOpen(session); + } + } - URI uri = URI.create("ws://localhost:8080/"); - EventSocket clientEndpoint = new EventSocket(); + public EventSocket getClientSocket(String param) + { + switch (param) + { + case "clientConfig": + client.setInputBufferSize(inputBufferSize); + client.setMaxBinaryMessageSize(maxMessageSize); + client.setIdleTimeout(Duration.ofMillis(idleTimeout)); + client.setMaxTextMessageSize(maxMessageSize); + return new EventSocket(); + + case "annotatedConfig": + return new AnnotatedConfigEndpoint(); + + case "sessionConfig": + return new SessionConfigEndpoint(); + + default: + throw new IllegalStateException(); + } + } + + @ParameterizedTest + @MethodSource("data") + public void testInputBufferSize(String param) throws Exception + { + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/"); + EventSocket clientEndpoint = getClientSocket(param); CompletableFuture connect = client.connect(clientEndpoint, uri); connect.get(5, TimeUnit.SECONDS); @@ -112,15 +157,17 @@ public class ClientConfigTest clientEndpoint.session.close(); assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); assertNull(clientEndpoint.error); + + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverSocket.statusCode, is(StatusCode.NO_CODE)); } - @Test - public void testMaxBinaryMessageSize() throws Exception + @ParameterizedTest + @MethodSource("data") + public void testMaxBinaryMessageSize(String param) throws Exception { - client.setMaxBinaryMessageSize(maxMessageSize); - - URI uri = URI.create("ws://localhost:8080/"); - EventSocket clientEndpoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/"); + EventSocket clientEndpoint = getClientSocket(param); CompletableFuture connect = client.connect(clientEndpoint, uri); connect.get(5, TimeUnit.SECONDS); @@ -128,15 +175,17 @@ public class ClientConfigTest assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(clientEndpoint.error, instanceOf(MessageTooLargeException.class)); + + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverSocket.statusCode, is(StatusCode.MESSAGE_TOO_LARGE)); } - @Test - public void testMaxIdleTime() throws Exception + @ParameterizedTest + @MethodSource("data") + public void testMaxIdleTime(String param) throws Exception { - client.setIdleTimeout(Duration.ofMillis(idleTimeout)); - - URI uri = URI.create("ws://localhost:8080/"); - EventSocket clientEndpoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/"); + EventSocket clientEndpoint = getClientSocket(param); CompletableFuture connect = client.connect(clientEndpoint, uri); connect.get(5, TimeUnit.SECONDS); @@ -145,15 +194,17 @@ public class ClientConfigTest assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(clientEndpoint.error, instanceOf(WebSocketTimeoutException.class)); + + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverSocket.statusCode, is(StatusCode.SHUTDOWN)); } - @Test - public void testMaxTextMessageSize() throws Exception + @ParameterizedTest + @MethodSource("data") + public void testMaxTextMessageSize(String param) throws Exception { - client.setMaxTextMessageSize(maxMessageSize); - - URI uri = URI.create("ws://localhost:8080/"); - EventSocket clientEndpoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/"); + EventSocket clientEndpoint = getClientSocket(param); CompletableFuture connect = client.connect(clientEndpoint, uri); connect.get(5, TimeUnit.SECONDS); @@ -161,83 +212,8 @@ public class ClientConfigTest assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(clientEndpoint.error, instanceOf(MessageTooLargeException.class)); - } - @Test - public void testInputBufferSizeAnnotation() throws Exception - { - URI uri = URI.create("ws://localhost:8080/"); - AnnotatedConfigEndpoint clientEndpoint = new AnnotatedConfigEndpoint(); - CompletableFuture connect = client.connect(clientEndpoint, uri); - - connect.get(5, TimeUnit.SECONDS); - - WebSocketChannel channel = (WebSocketChannel)((WebSocketSession)clientEndpoint.session).getCoreSession(); - WebSocketConnection connection = channel.getConnection(); - - assertThat(connection.getInputBufferSize(), is(inputBufferSize)); - - clientEndpoint.session.close(); - assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); - assertNull(clientEndpoint.error); - } - - @Test - public void testMaxBinaryMessageSizeAnnotation() throws Exception - { - URI uri = URI.create("ws://localhost:8080/"); - AnnotatedConfigEndpoint clientEndpoint = new AnnotatedConfigEndpoint(); - CompletableFuture connect = client.connect(clientEndpoint, uri); - - connect.get(5, TimeUnit.SECONDS); - clientEndpoint.session.getRemote().sendBytes(BufferUtil.toBuffer(message)); - assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); - - assertThat(clientEndpoint.error, instanceOf(MessageTooLargeException.class)); - } - - @Test - public void testMaxIdleTimeAnnotation() throws Exception - { - URI uri = URI.create("ws://localhost:8080/"); - AnnotatedConfigEndpoint clientEndpoint = new AnnotatedConfigEndpoint(); - CompletableFuture connect = client.connect(clientEndpoint, uri); - - connect.get(5, TimeUnit.SECONDS); - clientEndpoint.session.getRemote().sendString("hello world"); - Thread.sleep(idleTimeout + 500); - - assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); - assertThat(clientEndpoint.error, instanceOf(WebSocketTimeoutException.class)); - } - - @Test - public void testMaxTextMessageSizeAnnotation() throws Exception - { - URI uri = URI.create("ws://localhost:8080/"); - AnnotatedConfigEndpoint clientEndpoint = new AnnotatedConfigEndpoint(); - CompletableFuture connect = client.connect(clientEndpoint, uri); - - connect.get(5, TimeUnit.SECONDS); - clientEndpoint.session.getRemote().sendString(message); - assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); - - assertThat(clientEndpoint.error, instanceOf(MessageTooLargeException.class)); - } - - @Test - public void testBatchModeAnnotation() throws Exception - { - URI uri = URI.create("ws://localhost:8080/"); - AnnotatedConfigEndpoint clientEndpoint = new AnnotatedConfigEndpoint(); - CompletableFuture connect = client.connect(clientEndpoint, uri); - - connect.get(5, TimeUnit.SECONDS); - - assertThat(clientEndpoint.session.getRemote().getBatchMode(), is(BatchMode.ON)); - - clientEndpoint.session.close(); - assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); - assertNull(clientEndpoint.error); + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverSocket.statusCode, is(StatusCode.MESSAGE_TOO_LARGE)); } } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java new file mode 100644 index 00000000000..702572f29ed --- /dev/null +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java @@ -0,0 +1,301 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.tests.server; + +import java.net.URI; +import java.time.Duration; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; + +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.websocket.api.BatchMode; +import org.eclipse.jetty.websocket.api.MessageTooLargeException; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.WebSocketTimeoutException; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.WebSocketSession; +import org.eclipse.jetty.websocket.core.internal.WebSocketChannel; +import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; +import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer; +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; +import org.eclipse.jetty.websocket.tests.EventSocket; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ServerConfigTest +{ + private Server server; + private WebSocketClient client; + private ServerConnector connector; + private ConnectionListener listener = new ConnectionListener(); + + private static String message = "this message is over 20 characters long"; + private final static int inputBufferSize = 200; + private final static int maxMessageSize = 20; + private final static int idleTimeout = 500; + + private EventSocket annotatedEndpoint = new AnnotatedConfigEndpoint(); + private EventSocket sessionConfigEndpoint = new SessionConfigEndpoint(); + private EventSocket standardEndpoint = new EventSocket(); + + private EventSocket getServerEndpoint(String path) + { + switch (path) + { + case "servletConfig": + case "containerConfig": + return standardEndpoint; + case "annotatedConfig": + return annotatedEndpoint; + case "sessionConfig": + return sessionConfigEndpoint; + default: + throw new IllegalStateException(); + } + } + + public static Stream data() + { + return Stream.of("servletConfig", "annotatedConfig", "containerConfig", "sessionConfig").map(Arguments::of); + } + + @WebSocket(maxIdleTime=idleTimeout, maxTextMessageSize=maxMessageSize, maxBinaryMessageSize=maxMessageSize, inputBufferSize=inputBufferSize, batchMode=BatchMode.ON) + public static class AnnotatedConfigEndpoint extends EventSocket + { + } + + @WebSocket + public static class SessionConfigEndpoint extends EventSocket + { + @Override + public void onOpen(Session session) + { + session.setIdleTimeout(Duration.ofMillis(idleTimeout)); + session.setMaxTextMessageSize(maxMessageSize); + session.setMaxBinaryMessageSize(maxMessageSize); + session.setInputBufferSize(inputBufferSize); + super.onOpen(session); + } + } + + public class WebSocketFactoryConfigServlet extends JettyWebSocketServlet + { + @Override + public void configure(JettyWebSocketServletFactory factory) + { + factory.setIdleTimeout(Duration.ofMillis(idleTimeout)); + factory.setMaxTextMessageSize(maxMessageSize); + factory.setMaxBinaryMessageSize(maxMessageSize); + factory.setInputBufferSize(inputBufferSize); + factory.addMapping("/",(req, resp)->standardEndpoint); + } + } + + public class WebSocketAnnotatedConfigServlet extends JettyWebSocketServlet + { + @Override + public void configure(JettyWebSocketServletFactory factory) + { + factory.addMapping("/",(req, resp)->annotatedEndpoint); + } + } + + public class WebSocketSessionConfigServlet extends JettyWebSocketServlet + { + @Override + public void configure(JettyWebSocketServletFactory factory) + { + factory.addMapping("/",(req, resp)->sessionConfigEndpoint); + } + } + + public class ConnectionListener implements Connection.Listener + { + private AtomicInteger opened = new AtomicInteger(0); + private CountDownLatch closed = new CountDownLatch(1); + + @Override + public void onOpened(Connection connection) + { + if (connection instanceof WebSocketConnection) + opened.incrementAndGet(); + } + + @Override + public void onClosed(Connection connection) + { + if (connection instanceof WebSocketConnection) + closed.countDown(); + } + + public void assertClosed() throws Exception + { + assertTrue(closed.await(5, TimeUnit.SECONDS)); + assertThat(opened.get(), is(1)); + } + } + + @BeforeEach + public void start() throws Exception + { + server = new Server(); + connector = new ServerConnector(server); + connector.addBean(listener); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + contextHandler.addServlet(new ServletHolder(new WebSocketFactoryConfigServlet()), "/servletConfig"); + contextHandler.addServlet(new ServletHolder(new WebSocketAnnotatedConfigServlet()), "/annotatedConfig"); + contextHandler.addServlet(new ServletHolder(new WebSocketSessionConfigServlet()), "/sessionConfig"); + server.setHandler(contextHandler); + + JettyWebSocketServerContainer container = JettyWebSocketServletContainerInitializer.configureContext(contextHandler); + container.setIdleTimeout(Duration.ofMillis(idleTimeout)); + container.setMaxTextMessageSize(maxMessageSize); + container.setMaxBinaryMessageSize(maxMessageSize); + container.setInputBufferSize(inputBufferSize); + container.addMapping("/containerConfig", (req, resp)->standardEndpoint); + server.start(); + + client = new WebSocketClient(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + client.stop(); + server.stop(); + } + + + @ParameterizedTest + @MethodSource("data") + public void testInputBufferSize(String path) throws Exception + { + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/" + path); + EventSocket clientEndpoint = new EventSocket(); + EventSocket serverEndpoint = getServerEndpoint(path); + CompletableFuture connect = client.connect(clientEndpoint, uri); + + connect.get(5, TimeUnit.SECONDS); + + WebSocketChannel channel = (WebSocketChannel)((WebSocketSession)serverEndpoint.session).getCoreSession(); + WebSocketConnection connection = channel.getConnection(); + + assertThat(connection.getInputBufferSize(), is(inputBufferSize)); + + serverEndpoint.session.close(); + assertTrue(serverEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertNull(serverEndpoint.error); + + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.statusCode, is(StatusCode.NO_CODE)); + + listener.assertClosed(); + } + + @ParameterizedTest + @MethodSource("data") + public void testMaxBinaryMessageSize(String path) throws Exception + { + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/" + path); + EventSocket clientEndpoint = new EventSocket(); + EventSocket serverEndpoint = getServerEndpoint(path); + CompletableFuture connect = client.connect(clientEndpoint, uri); + + connect.get(5, TimeUnit.SECONDS); + clientEndpoint.session.getRemote().sendBytes(BufferUtil.toBuffer(message)); + assertTrue(serverEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + + assertThat(serverEndpoint.error, instanceOf(MessageTooLargeException.class)); + + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.statusCode, is(StatusCode.MESSAGE_TOO_LARGE)); + + listener.assertClosed(); + } + + @ParameterizedTest + @MethodSource("data") + public void testMaxIdleTime(String path) throws Exception + { + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/" + path); + EventSocket clientEndpoint = new EventSocket(); + EventSocket serverEndpoint = getServerEndpoint(path); + CompletableFuture connect = client.connect(clientEndpoint, uri); + + connect.get(5, TimeUnit.SECONDS); + clientEndpoint.session.getRemote().sendString("hello world"); + String msg = serverEndpoint.messageQueue.poll(500, TimeUnit.MILLISECONDS); + assertThat(msg, is("hello world")); + Thread.sleep(idleTimeout + 500); + + assertTrue(serverEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverEndpoint.error, instanceOf(WebSocketTimeoutException.class)); + + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.statusCode, is(StatusCode.SHUTDOWN)); + + listener.assertClosed(); + } + + @ParameterizedTest + @MethodSource("data") + public void testMaxTextMessageSize(String path) throws Exception + { + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/" + path); + EventSocket clientEndpoint = new EventSocket(); + EventSocket serverEndpoint = getServerEndpoint(path); + CompletableFuture connect = client.connect(clientEndpoint, uri); + + connect.get(5, TimeUnit.SECONDS); + clientEndpoint.session.getRemote().sendString(message); + assertTrue(serverEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + + assertThat(serverEndpoint.error, instanceOf(MessageTooLargeException.class)); + + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.statusCode, is(StatusCode.MESSAGE_TOO_LARGE)); + + listener.assertClosed(); + } +}