From 52de4de36297bd5b77a6a11fd84b31a52d6a3540 Mon Sep 17 00:00:00 2001 From: George Gastaldi Date: Thu, 27 Jan 2022 10:16:51 -0300 Subject: [PATCH] Add websockets integration tests --- .github/quarkus-bot.yml | 1 + integration-tests/pom.xml | 1 + integration-tests/websockets/pom.xml | 87 +++++++++++++++++++ .../io/quarkus/websockets/ChatServer.java | 57 ++++++++++++ .../java/io/quarkus/websockets/ChatTest.java | 55 ++++++++++++ 5 files changed, 201 insertions(+) create mode 100644 integration-tests/websockets/pom.xml create mode 100644 integration-tests/websockets/src/main/java/io/quarkus/websockets/ChatServer.java create mode 100644 integration-tests/websockets/src/test/java/io/quarkus/websockets/ChatTest.java diff --git a/.github/quarkus-bot.yml b/.github/quarkus-bot.yml index d2a1022004829..5471c4e5232ec 100644 --- a/.github/quarkus-bot.yml +++ b/.github/quarkus-bot.yml @@ -454,6 +454,7 @@ triage: - labels: [area/websockets] directories: - extensions/websockets/ + - integration-tests/websockets/ - labels: [area/swagger-ui] title: "swagger" notify: [phillip-kruger, MikeEdgar] diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 18a59941671eb..c26675671df17 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -188,6 +188,7 @@ vertx-web vertx-web-jackson vertx + websockets spring-di spring-web spring-data-jpa diff --git a/integration-tests/websockets/pom.xml b/integration-tests/websockets/pom.xml new file mode 100644 index 0000000000000..251aa582868cd --- /dev/null +++ b/integration-tests/websockets/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + + quarkus-integration-tests-parent + io.quarkus + 999-SNAPSHOT + + + quarkus-integration-test-websockets + Quarkus - Integration Tests - WebSockets + + + + io.quarkus + quarkus-websockets + + + io.quarkus + quarkus-arc + + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + org.awaitility + awaitility + test + + + + + io.quarkus + quarkus-arc-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-websockets-deployment + ${project.version} + pom + test + + + * + * + + + + + + + + + io.quarkus + quarkus-maven-plugin + + + + build + + + + + + + + \ No newline at end of file diff --git a/integration-tests/websockets/src/main/java/io/quarkus/websockets/ChatServer.java b/integration-tests/websockets/src/main/java/io/quarkus/websockets/ChatServer.java new file mode 100644 index 0000000000000..85f942748f91d --- /dev/null +++ b/integration-tests/websockets/src/main/java/io/quarkus/websockets/ChatServer.java @@ -0,0 +1,57 @@ +package io.quarkus.websockets; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.enterprise.context.ApplicationScoped; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint("/chat/{username}") +@ApplicationScoped +public class ChatServer { + + Map sessions = new ConcurrentHashMap<>(); + + @OnOpen + public void onOpen(Session session, @PathParam("username") String username) { + sessions.put(username, session); + } + + @OnClose + public void onClose(Session session, @PathParam("username") String username) { + sessions.remove(username); + broadcast("User " + username + " left"); + } + + @OnError + public void onError(Session session, @PathParam("username") String username, Throwable throwable) { + sessions.remove(username); + broadcast("User " + username + " left on error: " + throwable); + } + + @OnMessage + public void onMessage(String message, @PathParam("username") String username) { + if (message.equalsIgnoreCase("_ready_")) { + broadcast("User " + username + " joined"); + } else { + broadcast(">> " + username + ": " + message); + } + } + + private void broadcast(String message) { + sessions.values().forEach(s -> { + s.getAsyncRemote().sendObject(message, result -> { + if (result.getException() != null) { + System.out.println("Unable to send message: " + result.getException()); + } + }); + }); + } + +} diff --git a/integration-tests/websockets/src/test/java/io/quarkus/websockets/ChatTest.java b/integration-tests/websockets/src/test/java/io/quarkus/websockets/ChatTest.java new file mode 100644 index 0000000000000..9f81fdc9a52d2 --- /dev/null +++ b/integration-tests/websockets/src/test/java/io/quarkus/websockets/ChatTest.java @@ -0,0 +1,55 @@ +package io.quarkus.websockets; + +import java.net.URI; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; + +import javax.websocket.ClientEndpoint; +import javax.websocket.ContainerProvider; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.common.http.TestHTTPResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class ChatTest { + + private static final LinkedBlockingDeque MESSAGES = new LinkedBlockingDeque<>(); + + @TestHTTPResource("/chat/stu") + URI uri; + + @Test + public void testWebsocketChat() throws Exception { + try (Session session = ContainerProvider.getWebSocketContainer().connectToServer(Client.class, uri)) { + Assertions.assertEquals("CONNECT", MESSAGES.poll(10, TimeUnit.SECONDS)); + Assertions.assertEquals("User stu joined", MESSAGES.poll(10, TimeUnit.SECONDS)); + session.getAsyncRemote().sendText("hello world"); + Assertions.assertEquals(">> stu: hello world", MESSAGES.poll(10, TimeUnit.SECONDS)); + } + } + + @ClientEndpoint + public static class Client { + + @OnOpen + public void open(Session session) { + MESSAGES.add("CONNECT"); + // Send a message to indicate that we are ready, + // as the message handler may not be registered immediately after this callback. + session.getAsyncRemote().sendText("_ready_"); + } + + @OnMessage + void message(String msg) { + MESSAGES.add(msg); + } + + } + +} \ No newline at end of file