From 7991e27f35a207b60a267fa4a12992b03d43924b Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Wed, 16 Sep 2026 16:32:34 +0800 Subject: [PATCH] fix(node): prevent OAuth tests from launching browsers (#4196) OAuth tests set `LANCEDB_OAUTH_BROWSER` inside Jest's sandbox, which does not update the process environment read by Rust. As a result, the native login flow launches a real browser; the [failing macOS main job](https://github.com/lancedb/lancedb/actions/runs/35067074667/job/104699667840) ends by terminating an orphaned Safari process. Set the no-op browser helper while loading Jest configuration, before creating sandboxes and workers, so both local and CI tests inherit it. Check the inherited process environment before OAuth login to catch regressions without opening a browser. Windows uses a no-op command fixture. Test deadlines and worker counts are unchanged. A negative control restoring the sandbox-only assignment fails in the new pre-login check. The full macOS test suite passes with the standard test launcher; the Windows helper has not been executed locally. The [first hosted macOS run](https://github.com/lancedb/lancedb/actions/runs/35071525843/job/104713928139) passes all 843 tests (5 skipped), with no Safari process in the job log. Further normal runs are needed to establish sustained stability. --- nodejs/__test__/fixtures/oauth_browser.cmd | 3 +++ nodejs/__test__/oauth.test.ts | 13 ++++++++++--- nodejs/jest.config.js | 9 +++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 nodejs/__test__/fixtures/oauth_browser.cmd diff --git a/nodejs/__test__/fixtures/oauth_browser.cmd b/nodejs/__test__/fixtures/oauth_browser.cmd new file mode 100644 index 000000000..8e97db307 --- /dev/null +++ b/nodejs/__test__/fixtures/oauth_browser.cmd @@ -0,0 +1,3 @@ +@rem SPDX-License-Identifier: Apache-2.0 +@rem SPDX-FileCopyrightText: Copyright The LanceDB Authors +@exit /b 0 diff --git a/nodejs/__test__/oauth.test.ts b/nodejs/__test__/oauth.test.ts index 0a04bb2aa..627da786f 100644 --- a/nodejs/__test__/oauth.test.ts +++ b/nodejs/__test__/oauth.test.ts @@ -3,6 +3,7 @@ import * as fs from "fs"; import * as http from "http"; +import { execFileSync } from "node:child_process"; import * as os from "os"; import * as path from "path"; import { OAuthConfig, OAuthFlowType, OAuthSession } from "../lancedb/oauth"; @@ -23,9 +24,15 @@ function deviceConfig(issuerUrl: string, cacheDir: string): OAuthConfig { describe("OAuthSession", () => { beforeAll(() => { - // Point the Rust browser helper at a no-op so device-flow logins never - // open a real browser window during tests. - process.env.LANCEDB_OAUTH_BROWSER = "/usr/bin/true"; + // Child processes inherit the real environment, just as Rust reads it. + // Fail before login if the browser override only exists in Jest's sandbox. + const browser = execFileSync( + process.execPath, + ["-p", "process.env.LANCEDB_OAUTH_BROWSER ?? ''"], + { encoding: "utf8" }, + ).trim(); + expect(browser).not.toBe(""); + expect(browser).toBe(process.env.LANCEDB_OAUTH_BROWSER); }); it("reports an absent session and logout is idempotent", async () => { diff --git a/nodejs/jest.config.js b/nodejs/jest.config.js index dc99083a5..c137a4b9e 100644 --- a/nodejs/jest.config.js +++ b/nodejs/jest.config.js @@ -1,3 +1,12 @@ +const path = require("node:path"); + +// Set the real process environment before Jest creates its sandbox and workers. +// Assigning process.env inside a test does not reach Rust's std::env. +process.env.LANCEDB_OAUTH_BROWSER = + process.platform === "win32" + ? path.join(__dirname, "__test__/fixtures/oauth_browser.cmd") + : "/usr/bin/true"; + /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { preset: "ts-jest",