From 0a401143bbb114a6fb3afb5be5f0de4afc02cb65 Mon Sep 17 00:00:00 2001 From: Ed Burns Date: Tue, 19 May 2026 11:43:24 -0700 Subject: [PATCH] Fix macOS-flaky tests: testShouldGetLastSessionId and testShouldGetSessionMetadataById The Copilot CLI persists session state asynchronously, so querying session metadata or the last session ID immediately after sendAndWait() is a race condition. On Linux (CI) and Windows the I/O completes fast enough to mask the issue, but on macOS the tests fail consistently. Align the Java tests with the .NET and Node.js reference implementations: - testShouldGetLastSessionId: close the session before calling getLastSessionId() (matches .NET DisposeAsync-then-query pattern), and poll with a 10-second deadline and 50ms intervals (matches Node.js client_lifecycle.e2e.test.ts polling pattern). - testShouldGetSessionMetadataById: poll getSessionMetadata() with a 10-second deadline and 50ms intervals until it returns non-null (matches .NET WaitForConditionAsync pattern). Signed-off-by: Ed Burns --- .../copilot/sdk/CopilotSessionTest.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/github/copilot/sdk/CopilotSessionTest.java b/src/test/java/com/github/copilot/sdk/CopilotSessionTest.java index fc44880cf8..37daa7a20b 100644 --- a/src/test/java/com/github/copilot/sdk/CopilotSessionTest.java +++ b/src/test/java/com/github/copilot/sdk/CopilotSessionTest.java @@ -760,12 +760,23 @@ void testShouldGetLastSessionId() throws Exception { .createSession(new SessionConfig().setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); session.sendAndWait(new MessageOptions().setPrompt("Say hello")).get(60, TimeUnit.SECONDS); + String sessionId = session.getSessionId(); + session.close(); - String lastId = client.getLastSessionId().get(30, TimeUnit.SECONDS); + // Poll until getLastSessionId returns the expected value. + // Session state is persisted asynchronously; polling keeps fast + // machines fast and slow CI safe (mirrors Node.js/.NET patterns). + String lastId = null; + long deadline = System.currentTimeMillis() + 10_000; + while (System.currentTimeMillis() < deadline) { + lastId = client.getLastSessionId().get(30, TimeUnit.SECONDS); + if (sessionId.equals(lastId)) { + break; + } + Thread.sleep(50); + } assertNotNull(lastId, "Last session ID should not be null"); - assertEquals(session.getSessionId(), lastId, "Last session ID should match the current session ID"); - - session.close(); + assertEquals(sessionId, lastId, "Last session ID should match the current session ID"); } } @@ -840,11 +851,24 @@ void testShouldGetSessionMetadataById() throws Exception { var session = client .createSession(new SessionConfig().setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); + // Send a message to persist the session to disk session.sendAndWait(new MessageOptions().setPrompt("Say hello")).get(60, TimeUnit.SECONDS); - var metadata = client.getSessionMetadata(session.getSessionId()).get(30, TimeUnit.SECONDS); - assertNotNull(metadata, "Metadata should not be null for known session"); - assertEquals(session.getSessionId(), metadata.getSessionId(), "Metadata session ID should match"); + // Poll until metadata becomes available; the CLI persists session + // state asynchronously so it may not be queryable immediately + // (mirrors .NET WaitForConditionAsync pattern). + var sessionId = session.getSessionId(); + com.github.copilot.sdk.json.SessionMetadata metadata = null; + long deadline = System.currentTimeMillis() + 10_000; + while (System.currentTimeMillis() < deadline) { + metadata = client.getSessionMetadata(sessionId).get(30, TimeUnit.SECONDS); + if (metadata != null) { + break; + } + Thread.sleep(50); + } + assertNotNull(metadata, "Timed out waiting for getSessionMetadata() to return the persisted session"); + assertEquals(sessionId, metadata.getSessionId(), "Metadata session ID should match"); // A non-existent session should return null var notFound = client.getSessionMetadata("non-existent-session-id").get(30, TimeUnit.SECONDS);