From 30ec68fa7a03ac446c0ea6c898744e418e0f57a1 Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Tue, 21 Jul 2026 06:14:58 +0000 Subject: [PATCH] fix(test): harden findInstalledFtsExtension for cross-OS filesystem quirks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wrap the version-directory scan in try/catch so a transient FS error (permission denial, an AV file lock on Windows, a directory vanishing mid-scan) fails closed to null instead of throwing — matching the original callers' contract, and safer across the Windows/macOS/Linux CI matrix where these error modes differ. Also drop the redundant USERPROFILE/HOME manual chain in extension-binary-real.test.ts in favor of the repo's established os.homedir() convention (already used ~15 other places here), which Node resolves correctly per-OS and already honors env overrides. Co-Authored-By: Claude Sonnet 5 --- gitnexus/test/helpers/fts-availability.ts | 31 ++++++++++++------- .../integration/extension-binary-real.test.ts | 10 ++++-- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/gitnexus/test/helpers/fts-availability.ts b/gitnexus/test/helpers/fts-availability.ts index bc3620662..30ba05b8a 100644 --- a/gitnexus/test/helpers/fts-availability.ts +++ b/gitnexus/test/helpers/fts-availability.ts @@ -18,20 +18,27 @@ const MIN_VALID_FTS_EXTENSION_BYTES = 1024 * 1024; * actually just resolved), or null when nothing is installed. */ export const findInstalledFtsExtension = (extensionRoot: string): string | null => { - if (!existsSync(extensionRoot)) return null; - let best: { path: string; mtimeMs: number } | null = null; - for (const versionEntry of readdirSync(extensionRoot)) { - const versionDir = join(extensionRoot, versionEntry); - if (!statSync(versionDir).isDirectory()) continue; - for (const platformEntry of readdirSync(versionDir)) { - const candidate = join(versionDir, platformEntry, 'fts', 'libfts.lbug_extension'); - if (!existsSync(candidate)) continue; - const stat = statSync(candidate); - if (stat.size < MIN_VALID_FTS_EXTENSION_BYTES) continue; - if (!best || stat.mtimeMs > best.mtimeMs) best = { path: candidate, mtimeMs: stat.mtimeMs }; + // Fail closed on any FS error (permission quirks, AV file locks on Windows, + // a directory vanishing mid-scan) — same contract as the callers this + // replaces: "not found" is a valid outcome, a thrown exception is not. + try { + if (!existsSync(extensionRoot)) return null; + let best: { path: string; mtimeMs: number } | null = null; + for (const versionEntry of readdirSync(extensionRoot)) { + const versionDir = join(extensionRoot, versionEntry); + if (!statSync(versionDir).isDirectory()) continue; + for (const platformEntry of readdirSync(versionDir)) { + const candidate = join(versionDir, platformEntry, 'fts', 'libfts.lbug_extension'); + if (!existsSync(candidate)) continue; + const stat = statSync(candidate); + if (stat.size < MIN_VALID_FTS_EXTENSION_BYTES) continue; + if (!best || stat.mtimeMs > best.mtimeMs) best = { path: candidate, mtimeMs: stat.mtimeMs }; + } } + return best?.path ?? null; + } catch { + return null; } - return best?.path ?? null; }; export const FTS_UNAVAILABLE_NOTE = diff --git a/gitnexus/test/integration/extension-binary-real.test.ts b/gitnexus/test/integration/extension-binary-real.test.ts index a2734d40f..f46958a2b 100644 --- a/gitnexus/test/integration/extension-binary-real.test.ts +++ b/gitnexus/test/integration/extension-binary-real.test.ts @@ -46,10 +46,14 @@ function resolveLbugNative(): string | null { return null; } -/** The actual installed FTS extension binary for the running lbug version. */ +/** + * The actual installed FTS extension binary for the running lbug version. + * `os.homedir()` already honors `$HOME` (POSIX) / `%USERPROFILE%` (Windows) — + * the same resolution LadybugDB's native layer uses — so it stays correct + * under the hermetic-home overrides other tests in this suite set via env vars. + */ function resolveInstalledFtsExtension(): string | null { - const home = process.env.USERPROFILE ?? process.env.HOME ?? homedir(); - return findInstalledFtsExtension(join(home, '.lbdb', 'extension')); + return findInstalledFtsExtension(join(homedir(), '.lbdb', 'extension')); } const lbugNative = resolveLbugNative();