























@@ -96,6 +96,11 @@ import {
9696let tempDir: string;
9797let codexAppServerClientFactoryForTest: CodexAppServerClientFactory | undefined;
9898const 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+}>();
99104100105type RunCodexAppServerAttemptOptions = NonNullable<
101106Parameters<typeof runCodexAppServerAttemptImpl>[1]
@@ -150,10 +155,38 @@ function runCodexAppServerAttempt(
150155options: RunCodexAppServerAttemptOptions = {},
151156) {
152157const 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,
155168clientFactory ? { ...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}
158191159192function createParams(sessionFile: string, workspaceDir: string): EmbeddedRunAttemptParams {
@@ -367,15 +400,15 @@ function createAppServerHarness(
367400const waitForServerRequestHandler = async () => {
368401await vi.waitFor(() => expect(handleServerRequest).toBeTypeOf("function"), {
369402interval: 1,
370-timeout: 30_000,
403+timeout: appServerHarnessWait.timeout,
371404});
372405return handleServerRequest!;
373406};
374407375408return {
376409 request,
377410 requests,
378-async waitForMethod(method: string, timeoutMs = 30_000) {
411+async waitForMethod(method: string, timeoutMs = appServerHarnessWait.timeout) {
379412await vi.waitFor(
380413() => {
381414if (!requests.some((entry) => entry.method === method)) {
@@ -837,6 +870,8 @@ describe("runCodexAppServerAttempt", () => {
837870});
838871839872afterEach(async () => {
873+await drainActiveAppServerAttemptsForTest();
874+await closeCodexSandboxExecServersForTests();
840875resetCodexAppServerClientFactoryForTest();
841876testing.resetOpenClawCodingToolsFactoryForTests();
842877resetCodexRateLimitCacheForTests();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。