Skip to content

Commit 6627361

Browse files
committed
test(appserver): make fake server concurrency controllable
1 parent 6ad270f commit 6627361

1 file changed

Lines changed: 50 additions & 7 deletions

File tree

‎src/test/java/io/github/easy4j/codex/appserver/FakeCodexAppServer.java‎

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
import java.util.List;
3131
import java.util.Locale;
3232
import java.util.concurrent.CopyOnWriteArrayList;
33+
import java.util.concurrent.CountDownLatch;
34+
import java.util.concurrent.TimeUnit;
35+
import java.util.concurrent.atomic.AtomicInteger;
3336

3437
import com.fasterxml.jackson.databind.JsonNode;
3538
import com.fasterxml.jackson.databind.json.JsonMapper;
@@ -52,7 +55,9 @@ final class FakeCodexAppServer implements AutoCloseable {
5255
private final ServerSocket serverSocket;
5356
private final List<String> receivedFrames = new CopyOnWriteArrayList<>();
5457
private final Thread acceptLoop;
58+
private final AtomicInteger turnStarts = new AtomicInteger();
5559

60+
private volatile CountDownLatch turnCompletionGate = new CountDownLatch(0);
5661
private volatile boolean authorizationSeen;
5762
private volatile boolean closed;
5863

@@ -78,19 +83,48 @@ boolean authorizationSeen() {
7883
return authorizationSeen;
7984
}
8085

86+
void holdTurnCompletions() {
87+
turnCompletionGate = new CountDownLatch(1);
88+
}
89+
90+
void releaseTurnCompletions() {
91+
turnCompletionGate.countDown();
92+
}
93+
94+
int turnStartCount() {
95+
return turnStarts.get();
96+
}
97+
98+
boolean awaitTurnStarts(int expected, long timeoutMillis) throws InterruptedException {
99+
long deadline = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeoutMillis);
100+
while (System.nanoTime() < deadline) {
101+
if (turnStarts.get() >= expected) {
102+
return true;
103+
}
104+
Thread.sleep(10L);
105+
}
106+
return turnStarts.get() >= expected;
107+
}
108+
81109
private void acceptLoop() {
82110
while (!closed) {
83-
try (Socket socket = serverSocket.accept()) {
84-
handleConnection(socket);
111+
try {
112+
Socket socket = serverSocket.accept();
113+
Thread connection = new Thread(() -> {
114+
try (Socket closeable = socket) {
115+
handleConnection(closeable);
116+
} catch (Exception ex) {
117+
if (!closed) {
118+
ex.printStackTrace();
119+
}
120+
}
121+
}, "fake-codex-app-server-connection");
122+
connection.setDaemon(true);
123+
connection.start();
85124
} catch (IOException ex) {
86125
if (!closed) {
87-
// Accept failures on a listening socket mean it was closed; stop quietly.
88126
return;
89127
}
90-
} catch (Exception ex) {
91-
// A runtime failure mid-connection must be visible — a silent
92-
// thread death here looks exactly like a client-side timeout.
93-
ex.printStackTrace();
94128
}
95129
}
96130
}
@@ -163,6 +197,7 @@ private void respondTo(OutputStream out, String frame) throws IOException {
163197
return;
164198
}
165199
if ("turn/start".equals(method)) {
200+
turnStarts.incrementAndGet();
166201
sendText(out, "{\"jsonrpc\":\"2.0\",\"id\":" + id + ",\"result\":{}}");
167202
sendText(out, "{\"method\":\"turn/started\",\"params\":{\"threadId\":\"th_e2e\",\"turnId\":\"turn_1\"}}");
168203
sendText(out, "{\"method\":\"thread/tokenUsage/updated\",\"params\":{\"tokens\":1}}");
@@ -172,6 +207,14 @@ private void respondTo(OutputStream out, String frame) throws IOException {
172207
+ "{\"item\":{\"type\":\"agentMessage\",\"text\":\"你好\"}}}");
173208
sendText(out, "{\"method\":\"item/completed\",\"params\":"
174209
+ "{\"item\":{\"itemType\":\"agent_message\",\"content\":\"世界\"}}}");
210+
try {
211+
if (!turnCompletionGate.await(5, TimeUnit.SECONDS)) {
212+
throw new IOException("Timed out waiting to release fake turn completion");
213+
}
214+
} catch (InterruptedException ex) {
215+
Thread.currentThread().interrupt();
216+
throw new IOException("Interrupted waiting to release fake turn completion", ex);
217+
}
175218
sendText(out, "{\"method\":\"turn/completed\",\"params\":"
176219
+ "{\"threadId\":\"th_e2e\",\"message\":\"fallback-unused\"}}");
177220
return;

0 commit comments

Comments
 (0)