Files
OmniRoute/tests/unit/sqljs-wasm-resolution-12960.test.ts
Bob.Hou fc3ce839fe fix(db): resolve sql-wasm.wasm across global and hoisted layouts (#12960) (#13035)
Correct root cause chain, and it explains why this only bites global installs: npm 11 skips `optionalDependencies` install scripts, the server child runs with `cwd: <packageRoot>/dist`, and `sql.js` sits at `<packageRoot>/node_modules`. Probing the parent directory is the missing rung.

---

Validated in one consolidated worktree cut from `release/v3.8.51`, boarded with the other 19 PRs of this batch. Two in-batch conflicts, both additive and resolved by keeping each side: the `ENVIRONMENT.md` table (#13035 + #13011) and the `chatHelpers.ts` import block (#12975 on the tip + #13017).

- `typecheck:core` clean; `check:dashboard-typecheck` OK (206 pre-existing, within baseline); `check:changelog-integrity` OK; `check:docs-counts` migrations ✓
- complexity 2816 / baseline 3218 and cognitive-complexity 1271 / baseline 1437 — both under baseline
- 531 of 532 focused assertions green across the batch's 46 test files
- `check-file-size` rebaselined for the batch's real growth (annotation `_rebaseline_2026_09_11_mergebatch_v3851_houminxi`, landed on #13038), attributed per PR

The single red is **not this batch**: `tests/unit/combo/quota-weighted-strategy.test.ts` → "A/B isolation: 7 hard-empty + 2 at 0.5% + 1 at 40%, floor=1" asserts an order between two connections of identical weight and flakes on the pure tip too — 2 failures in 4 runs at `origin/release/v3.8.51` with nothing from this batch applied.

⚠️ base-red inherited: #12732 — `Docs Gates`, `Merge integrity`, `No new ESLint warnings`, `Unit Tests fast-path` and `Fast Quality Gates` reproduce on the pure tip (provider count 356 vs the 358 the modules define, SKILL.md drift, and `open-sse/utils/stream.ts` at 3115 > frozen 3098, untouched here).

Thanks @HouMinXi — the live evidence on these (X500 logs, `storage.sqlite` state, real `/v1/models` probes, the 36-minute outage write-up) is what let a 20-PR batch be reviewed as a unit.
2026-09-11 19:27:52 -03:00

236 lines
8.1 KiB
TypeScript

import { test, describe } from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import os from "node:os";
import { resolveSqlJsWasmPath } from "../../src/lib/db/adapters/sqljsAdapter.ts";
describe("sql.js WASM path resolution (#12960)", () => {
test("resolves an existing sql-wasm.wasm in the current environment", (t) => {
const origEnv = process.env.OMNIROUTE_SQLJS_WASM_PATH;
delete process.env.OMNIROUTE_SQLJS_WASM_PATH;
t.after(() => {
if (origEnv !== undefined) {
process.env.OMNIROUTE_SQLJS_WASM_PATH = origEnv;
}
});
const wasmPath = resolveSqlJsWasmPath();
assert.ok(typeof wasmPath === "string" && wasmPath.length > 0);
assert.ok(fs.existsSync(wasmPath), `Resolved path must exist: ${wasmPath}`);
assert.ok(wasmPath.endsWith("sql-wasm.wasm"));
});
test("honors OMNIROUTE_SQLJS_WASM_PATH when set to a valid file", (t) => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sqljs-override-"));
const fakeWasm = path.join(tmpDir, "custom-sql-wasm.wasm");
fs.writeFileSync(fakeWasm, "mock wasm binary");
const origEnv = process.env.OMNIROUTE_SQLJS_WASM_PATH;
process.env.OMNIROUTE_SQLJS_WASM_PATH = fakeWasm;
t.after(() => {
if (origEnv === undefined) {
delete process.env.OMNIROUTE_SQLJS_WASM_PATH;
} else {
process.env.OMNIROUTE_SQLJS_WASM_PATH = origEnv;
}
fs.rmSync(tmpDir, { recursive: true, force: true });
});
const resolved = resolveSqlJsWasmPath();
assert.equal(resolved, fakeWasm);
});
test("resolves relative OMNIROUTE_SQLJS_WASM_PATH to an absolute path", (t) => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sqljs-rel-override-"));
const fakeWasm = path.join(tmpDir, "rel-sql-wasm.wasm");
fs.writeFileSync(fakeWasm, "mock wasm binary");
const origCwd = process.cwd();
process.chdir(tmpDir);
const origEnv = process.env.OMNIROUTE_SQLJS_WASM_PATH;
process.env.OMNIROUTE_SQLJS_WASM_PATH = "./rel-sql-wasm.wasm";
t.after(() => {
process.chdir(origCwd);
if (origEnv === undefined) {
delete process.env.OMNIROUTE_SQLJS_WASM_PATH;
} else {
process.env.OMNIROUTE_SQLJS_WASM_PATH = origEnv;
}
fs.rmSync(tmpDir, { recursive: true, force: true });
});
const resolved = resolveSqlJsWasmPath();
assert.ok(path.isAbsolute(resolved));
assert.equal(fs.realpathSync(resolved), fs.realpathSync(fakeWasm));
});
test("throws when OMNIROUTE_SQLJS_WASM_PATH points to non-existent file", (t) => {
const nonExistent = path.join(os.tmpdir(), `non-existent-wasm-${Date.now()}.wasm`);
const origEnv = process.env.OMNIROUTE_SQLJS_WASM_PATH;
process.env.OMNIROUTE_SQLJS_WASM_PATH = nonExistent;
t.after(() => {
if (origEnv === undefined) {
delete process.env.OMNIROUTE_SQLJS_WASM_PATH;
} else {
process.env.OMNIROUTE_SQLJS_WASM_PATH = origEnv;
}
});
assert.throws(
() => resolveSqlJsWasmPath(),
/OMNIROUTE_SQLJS_WASM_PATH is set to .* but the file cannot be accessed/
);
});
test("throws when OMNIROUTE_SQLJS_WASM_PATH is set to an empty string", (t) => {
const origEnv = process.env.OMNIROUTE_SQLJS_WASM_PATH;
process.env.OMNIROUTE_SQLJS_WASM_PATH = " ";
t.after(() => {
if (origEnv === undefined) {
delete process.env.OMNIROUTE_SQLJS_WASM_PATH;
} else {
process.env.OMNIROUTE_SQLJS_WASM_PATH = origEnv;
}
});
assert.throws(
() => resolveSqlJsWasmPath(),
/OMNIROUTE_SQLJS_WASM_PATH is set to an empty or whitespace-only string/
);
});
test("throws when OMNIROUTE_SQLJS_WASM_PATH points to a directory", (t) => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sqljs-dir-wasm-"));
const origEnv = process.env.OMNIROUTE_SQLJS_WASM_PATH;
process.env.OMNIROUTE_SQLJS_WASM_PATH = tmpDir;
t.after(() => {
if (origEnv === undefined) {
delete process.env.OMNIROUTE_SQLJS_WASM_PATH;
} else {
process.env.OMNIROUTE_SQLJS_WASM_PATH = origEnv;
}
fs.rmSync(tmpDir, { recursive: true, force: true });
});
assert.throws(() => resolveSqlJsWasmPath(), /points to a directory, not a file/);
});
test("throws when OMNIROUTE_SQLJS_WASM_PATH points to an empty (0-byte) file", (t) => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sqljs-empty-wasm-"));
const emptyWasm = path.join(tmpDir, "empty.wasm");
fs.writeFileSync(emptyWasm, "");
const origEnv = process.env.OMNIROUTE_SQLJS_WASM_PATH;
process.env.OMNIROUTE_SQLJS_WASM_PATH = emptyWasm;
t.after(() => {
if (origEnv === undefined) {
delete process.env.OMNIROUTE_SQLJS_WASM_PATH;
} else {
process.env.OMNIROUTE_SQLJS_WASM_PATH = origEnv;
}
fs.rmSync(tmpDir, { recursive: true, force: true });
});
assert.throws(() => resolveSqlJsWasmPath(), /file is empty \(size=0\)/);
});
test("resolves from parent node_modules when cwd is <pkg>/dist (global install layout)", (t) => {
// Simulate:
// <tmpRoot>/lib/node_modules/omniroute/dist/ <-- cwd
// <tmpRoot>/lib/node_modules/omniroute/node_modules/sql.js/dist/sql-wasm.wasm
const tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), "sqljs-global-layout-"));
const pkgRoot = path.join(tmpBase, "lib", "node_modules", "omniroute");
const distDir = path.join(pkgRoot, "dist");
const sqlJsDist = path.join(pkgRoot, "node_modules", "sql.js", "dist");
fs.mkdirSync(distDir, { recursive: true });
fs.mkdirSync(sqlJsDist, { recursive: true });
const targetWasm = path.join(sqlJsDist, "sql-wasm.wasm");
fs.writeFileSync(targetWasm, "mock wasm");
const origCwd = process.cwd();
process.chdir(distDir);
t.after(() => {
process.chdir(origCwd);
fs.rmSync(tmpBase, { recursive: true, force: true });
});
const resolved = resolveSqlJsWasmPath();
assert.equal(fs.realpathSync(resolved), fs.realpathSync(targetWasm));
});
test("throws an actionable error naming the remedy when WASM cannot be found", (t) => {
const tmpEmpty = fs.mkdtempSync(path.join(os.tmpdir(), "sqljs-empty-"));
const origCwd = process.cwd();
const origArgv1 = process.argv[1];
process.chdir(tmpEmpty);
// Point argv[1] to a non-existent location inside tmpEmpty so require.resolve cannot escape
process.argv[1] = path.join(tmpEmpty, "dummy-server.js");
t.after(() => {
process.chdir(origCwd);
process.argv[1] = origArgv1;
fs.rmSync(tmpEmpty, { recursive: true, force: true });
});
let thrownError: Error | null = null;
try {
resolveSqlJsWasmPath();
} catch (err) {
thrownError = err as Error;
}
assert.ok(thrownError, "Expected resolveSqlJsWasmPath to throw");
const msg = thrownError.message;
// Must name the packaged sql.js problem
assert.match(msg, /\[sqljsAdapter\] Packaged sql\.js runtime is incomplete/);
// Must explain that the fallback WASM runtime could not locate the binary
assert.match(msg, /fallback WASM runtime could not locate sql-wasm\.wasm/);
// Must provide the actionable remedy for global and local installs (#12960)
assert.match(msg, /npm rebuild better-sqlite3/);
assert.match(msg, /docs\/guides\/TROUBLESHOOTING\.md/);
assert.match(msg, /OMNIROUTE_SQLJS_WASM_PATH/);
});
test("rethrows non-MODULE_NOT_FOUND unexpected errors during require resolution", (t) => {
const origCwd = process.cwd();
const origArgv1 = process.argv[1];
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sqljs-rethrow-"));
process.chdir(tmpDir);
process.argv[1] = "\0invalid_null_byte_path";
t.after(() => {
process.chdir(origCwd);
process.argv[1] = origArgv1;
fs.rmSync(tmpDir, { recursive: true, force: true });
});
assert.throws(
() => resolveSqlJsWasmPath(),
(err: unknown) => {
const error = err as Error;
return (
error.name === "TypeError" ||
(error as { code?: string }).code === "ERR_INVALID_ARG_VALUE" ||
error.message.includes("null byte")
);
}
);
});
});