This is an automated email from the ASF dual-hosted git repository.

jbonofre pushed a commit to branch karaf-4.4.x
in repository https://gitbox.apache.org/repos/asf/karaf.git


The following commit(s) were added to refs/heads/karaf-4.4.x by this push:
     new 9422d7e754 [4.4.x] Fix flaky GraphQLExampleTest (#2975)
9422d7e754 is described below

commit 9422d7e75461b2f2445548f67938066fb3c338e7
Author: JB Onofré <[email protected]>
AuthorDate: Sun Oct 4 17:37:41 2026 +0200

    [4.4.x] Fix flaky GraphQLExampleTest (#2975)
---
 .../karaf/itests/examples/GraphQLExampleTest.java  | 45 +++++++++++++++-------
 .../org/apache/karaf/itests/util/SimpleSocket.java | 11 +++++-
 2 files changed, 41 insertions(+), 15 deletions(-)

diff --git 
a/itests/test/src/test/java/org/apache/karaf/itests/examples/GraphQLExampleTest.java
 
b/itests/test/src/test/java/org/apache/karaf/itests/examples/GraphQLExampleTest.java
index d41d994cc4..c6641554fc 100644
--- 
a/itests/test/src/test/java/org/apache/karaf/itests/examples/GraphQLExampleTest.java
+++ 
b/itests/test/src/test/java/org/apache/karaf/itests/examples/GraphQLExampleTest.java
@@ -17,6 +17,7 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.apache.karaf.itests.BaseTest;
 import org.apache.karaf.itests.util.SimpleSocket;
+import org.awaitility.Awaitility;
 import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
 import org.eclipse.jetty.websocket.client.WebSocketClient;
 import org.junit.Test;
@@ -46,9 +47,19 @@ public class GraphQLExampleTest extends BaseTest {
         installAndAssertFeature("karaf-graphql-example");
     }
 
+    // the HTTP service starts and registers the servlets asynchronously
+    private void awaitServlet(String path) {
+        Awaitility.await("servlet " + path).atMost(30, 
TimeUnit.SECONDS).ignoreExceptions().until(() -> {
+            URL url = new URL("http://localhost:"; + getHttpPort() + path);
+            HttpURLConnection connection = (HttpURLConnection) 
url.openConnection();
+            return connection.getResponseCode() != 
HttpURLConnection.HTTP_NOT_FOUND;
+        });
+    }
+
     @Test
     public void testServlet() throws Exception {
         setUp();
+        awaitServlet("/graphql");
 
         String getBooksQuery = "{ books { name id } }";
         String booksRequestResult = sendGetRequest(getBooksQuery);
@@ -79,23 +90,31 @@ public class GraphQLExampleTest extends BaseTest {
     @Test
     public void testWebSocket() throws Exception {
         setUp();
+        awaitServlet("/graphql");
+        awaitServlet("/graphql-websocket");
 
         WebSocketClient client = new WebSocketClient();
         SimpleSocket socket = new SimpleSocket();
         client.start();
-        URI uri = new URI("ws://localhost:" + getHttpPort() + 
"/graphql-websocket");
-        ClientUpgradeRequest request = new ClientUpgradeRequest();
-        client.connect(socket, uri, request);
-
-        sendPostRequest("mutation { addBook(name:\"Lord of the Rings\" 
pageCount:100) { id name } }");
-
-        socket.awaitClose(10, TimeUnit.SECONDS);
-
-        assertTrue(socket.messages.size() > 0);
-
-        assertContains("Lord of the Rings", socket.messages.get(0));
-
-        client.stop();
+        try {
+            URI uri = new URI("ws://localhost:" + getHttpPort() + 
"/graphql-websocket");
+            ClientUpgradeRequest request = new ClientUpgradeRequest();
+            client.connect(socket, uri, request).get(10, TimeUnit.SECONDS);
+
+            // the server subscribes to the book feed once the websocket is 
opened, and a book added
+            // before that is not published to this client, so add books until 
one is received
+            boolean received = false;
+            for (int i = 0; !received && i < 30; i++) {
+                sendPostRequest("mutation { addBook(name:\"Lord of the Rings\" 
pageCount:100) { id name } }");
+                received = socket.awaitMessage(1, TimeUnit.SECONDS);
+            }
+
+            assertTrue(received);
+
+            assertContains("Lord of the Rings", socket.messages.get(0));
+        } finally {
+            client.stop();
+        }
     }
 
     private String sendGetRequest(String query) throws Exception {
diff --git 
a/itests/test/src/test/java/org/apache/karaf/itests/util/SimpleSocket.java 
b/itests/test/src/test/java/org/apache/karaf/itests/util/SimpleSocket.java
index adc930f657..6af9bcffb4 100644
--- a/itests/test/src/test/java/org/apache/karaf/itests/util/SimpleSocket.java
+++ b/itests/test/src/test/java/org/apache/karaf/itests/util/SimpleSocket.java
@@ -23,8 +23,8 @@ import 
org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
 import org.eclipse.jetty.websocket.api.annotations.WebSocket;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -33,17 +33,23 @@ public class SimpleSocket {
 
     public final List<String> messages;
     private final CountDownLatch closeLatch;
+    private final CountDownLatch messageLatch;
     private Session session;
 
     public SimpleSocket() {
-        this.messages = new ArrayList<>();
+        this.messages = new CopyOnWriteArrayList<>();
         this.closeLatch = new CountDownLatch(1);
+        this.messageLatch = new CountDownLatch(1);
     }
 
     public boolean awaitClose(int duration, TimeUnit unit) throws 
InterruptedException {
         return this.closeLatch.await(duration, unit);
     }
 
+    public boolean awaitMessage(int duration, TimeUnit unit) throws 
InterruptedException {
+        return this.messageLatch.await(duration, unit);
+    }
+
     @OnWebSocketClose
     public void onClose(int statusCode, String reason) {
         System.out.println("Closing websocket client");
@@ -62,5 +68,6 @@ public class SimpleSocket {
     public void onMessage(String msg) {
         System.out.println("Received websocket message: " + msg);
         messages.add(msg);
+        this.messageLatch.countDown();
     }
 }

Reply via email to