Skip to content

Commit a705a9c

Browse files
committed
test: drain Codex app-server attempts
1 parent 05c6e7a commit a705a9c

1 file changed

Lines changed: 40 additions & 5 deletions

File tree

extensions/codex/src/app-server/run-attempt.test.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ import {
9696
let tempDir: string;
9797
let codexAppServerClientFactoryForTest: CodexAppServerClientFactory | undefined;
9898
const fastWait = { interval: 1, timeout: 5_000 } as const;
99+
const appServerHarnessWait = { interval: 1, timeout: 120_000 } as const;
100+
const activeAppServerAttemptsForTest = new Set<{
101+
abortController?: AbortController;
102+
promise: Promise<unknown>;
103+
}>();
99104

100105
type RunCodexAppServerAttemptOptions = NonNullable<
101106
Parameters<typeof runCodexAppServerAttemptImpl>[1]
@@ -150,10 +155,38 @@ function runCodexAppServerAttempt(
150155
options: RunCodexAppServerAttemptOptions = {},
151156
) {
152157
const clientFactory = options.clientFactory ?? codexAppServerClientFactoryForTest;
153-
return runCodexAppServerAttemptImpl(
154-
params,
158+
const abortController = params.abortSignal ? undefined : new AbortController();
159+
const trackedParams = abortController
160+
? ({ ...params, abortSignal: abortController.signal } as EmbeddedRunAttemptParams)
161+
: params;
162+
const entry = {
163+
abortController,
164+
promise: undefined as unknown as Promise<unknown>,
165+
};
166+
const promise = runCodexAppServerAttemptImpl(
167+
trackedParams,
155168
clientFactory ? { ...options, clientFactory } : options,
156-
);
169+
).finally(() => {
170+
activeAppServerAttemptsForTest.delete(entry);
171+
});
172+
entry.promise = promise;
173+
activeAppServerAttemptsForTest.add(entry);
174+
promise.catch(() => undefined);
175+
return promise;
176+
}
177+
178+
async function drainActiveAppServerAttemptsForTest(): Promise<void> {
179+
const attempts = [...activeAppServerAttemptsForTest];
180+
if (attempts.length === 0) {
181+
return;
182+
}
183+
for (const attempt of attempts) {
184+
attempt.abortController?.abort("test_cleanup");
185+
}
186+
await Promise.race([
187+
Promise.allSettled(attempts.map((attempt) => attempt.promise)),
188+
new Promise<void>((resolve) => setTimeout(resolve, 5_000)),
189+
]);
157190
}
158191

159192
function createParams(sessionFile: string, workspaceDir: string): EmbeddedRunAttemptParams {
@@ -367,15 +400,15 @@ function createAppServerHarness(
367400
const waitForServerRequestHandler = async () => {
368401
await vi.waitFor(() => expect(handleServerRequest).toBeTypeOf("function"), {
369402
interval: 1,
370-
timeout: 30_000,
403+
timeout: appServerHarnessWait.timeout,
371404
});
372405
return handleServerRequest!;
373406
};
374407

375408
return {
376409
request,
377410
requests,
378-
async waitForMethod(method: string, timeoutMs = 30_000) {
411+
async waitForMethod(method: string, timeoutMs = appServerHarnessWait.timeout) {
379412
await vi.waitFor(
380413
() => {
381414
if (!requests.some((entry) => entry.method === method)) {
@@ -837,6 +870,8 @@ describe("runCodexAppServerAttempt", () => {
837870
});
838871

839872
afterEach(async () => {
873+
await drainActiveAppServerAttemptsForTest();
874+
await closeCodexSandboxExecServersForTests();
840875
resetCodexAppServerClientFactoryForTest();
841876
testing.resetOpenClawCodingToolsFactoryForTests();
842877
resetCodexRateLimitCacheForTests();

0 commit comments

Comments
 (0)