From 95845cf6ceb85a5793aeb227b5a03056cb508756 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 27 Mar 2026 13:04:34 -0700 Subject: [PATCH] fix: disable plugins in SDK integration tests (#16036) ## Why The TypeScript SDK tests create a fresh `CODEX_HOME` for each Jest case and delete it during teardown. That cleanup has been flaking because the real `codex` binary can still be doing background curated-plugin startup sync under `.tmp/plugins-clone-*`, which races the test harness's recursive delete and leaves `ENOTEMPTY` failures behind. This path is unrelated to what the SDK tests are exercising, so letting plugin startup run during these tests only adds nondeterministic filesystem activity. This showed up recently in the `sdk` CI lane for [#16031](https://github.com/openai/codex/pull/16031). ## What Changed - updated `sdk/typescript/tests/testCodex.ts` to merge test config through a single helper - disabled `features.plugins` unconditionally for SDK integration tests so the CLI does not start curated-plugin sync in the temporary `CODEX_HOME` - preserved other explicit feature overrides from individual tests while forcing `plugins` back to `false` - kept the existing mock-provider override behavior intact for SSE-backed tests ## Verification - `pnpm test --runInBand` - `pnpm lint` --- sdk/typescript/tests/testCodex.ts | 44 +++++++++++++++++++------------ 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/sdk/typescript/tests/testCodex.ts b/sdk/typescript/tests/testCodex.ts index d73b519b6..a4cac8b14 100644 --- a/sdk/typescript/tests/testCodex.ts +++ b/sdk/typescript/tests/testCodex.ts @@ -44,33 +44,43 @@ export function createTestClient(options: CreateTestClientOptions = {}): TestCli codexPathOverride: codexExecPath, baseUrl: options.baseUrl, apiKey: options.apiKey, - config: mergeTestProviderConfig(options.baseUrl, options.config), + config: mergeTestConfig(options.baseUrl, options.config), env, }), }; } -function mergeTestProviderConfig( +function mergeTestConfig( baseUrl: string | undefined, config: CodexConfigObject | undefined, ): CodexConfigObject | undefined { - if (!baseUrl || hasExplicitProviderConfig(config)) { - return config; - } + const mergedConfig: CodexConfigObject | undefined = + !baseUrl || hasExplicitProviderConfig(config) + ? config + : { + ...config, + // Built-in providers are merged before user config, so tests need a + // custom provider entry to force SSE against the local mock server. + model_provider: "mock", + model_providers: { + mock: { + name: "Mock provider for test", + base_url: baseUrl, + wire_api: "responses", + supports_websockets: false, + }, + }, + }; + const featureOverrides = mergedConfig?.features; - // Built-in providers are merged before user config, so tests need a custom - // provider entry to force SSE against the local mock server. return { - ...config, - model_provider: "mock", - model_providers: { - mock: { - name: "Mock provider for test", - base_url: baseUrl, - wire_api: "responses", - supports_websockets: false, - }, - }, + ...mergedConfig, + // Disable plugins in SDK integration tests so background curated-plugin + // sync does not race temp CODEX_HOME cleanup. + features: + featureOverrides && typeof featureOverrides === "object" && !Array.isArray(featureOverrides) + ? { ...featureOverrides, plugins: false } + : { plugins: false }, }; }