Files
OmniRoute/tests/unit/compression/llmlingua-model-store.test.ts
Diego Rodrigues de Sa e Souza 3d4f3e4960 test(infra): retry recursive temp-dir removal instead of failing a shard on ENOTEMPTY (#11966) (#11968)
* test(infra): retry recursive temp-dir removal instead of failing a shard on ENOTEMPTY (#11966)

Two shards on release/v3.8.51 went red in one day with the same signature —
"ENOTEMPTY, Directory not empty: /tmp/omniroute-<test>-XXXXXX" — from
combo-same-provider-cascade (Unit Tests fast-path 4/4, on a PR that touches only
.github/) and auth-policy-embeddings-webfetch-7785 (the 20k-test TIA step). Both pass
alone and on re-run: the cleanup races something still writing into the directory
(SQLite WAL/-shm checkpoint, a worker, the backup) and under a loaded hosted runner
the window opens. 1154 test files do their own cleanup with
fs.rmSync(dir, { recursive: true, force: true }); 57 already asked for retries.

One-shot codemod (scripts/ad-hoc/codemod-rm-maxretries.mjs, kept for the record):
every rm / rmSync / rmdirSync option object with `recursive: true` and no
`maxRetries` gains `maxRetries: 5, retryDelay: 100` — Node itself then retries
ENOTEMPTY/EBUSY/EPERM for up to ~0.5 s before giving up. 2243 call sites in 1292
files under tests/, the shared tests/_setup/isolateDataDir.ts exit hook included.
Only the option object changes: no call site, assertion or import is touched.

Validation: prettier and ESLint (with the frozen suppressions) clean on all 1292
files; a random 20-file sample runs green (quota-redis-store hangs identically on
the untouched tree — it needs a Redis on localhost, an environment matter). The
four unit shards on this PR are the full run.

* fix(quality): let check-forgotten-sibling-tests read a 1,000-file diff

The gate shells out to `git diff` through execFileSync with Node's default 1 MB
maxBuffer; the 1,292-file codemod in this PR is the first diff large enough to
overflow it, and the gate died with `spawnSync git ENOBUFS` before comparing
anything. 64 MB is far above any real PR and costs nothing when unused.
2026-08-29 01:17:40 -03:00

132 lines
5.9 KiB
TypeScript

/**
* TDD tests for the llmlingua model registry + model store (Tasks 1-2).
*
* Tests are written RED-first (before the implementation exists).
*
* Coverage:
* 1. Registry shape — tinybert + bert-base present; default points at a valid key.
* 2. Each entry's factory/dtype/subfolder/hfRepo invariants hold.
* 3. resolveLlmlinguaModel() — known id, and the unknown/undefined/empty fallbacks.
* 4. getLlmlinguaModelCacheDir() — path suffix + DATA_DIR honoring.
* 5. configureTransformersEnv() — Hub download default vs local modelPath override.
*/
import { describe, it, after } from "node:test";
import assert from "node:assert/strict";
import os from "node:os";
import path from "node:path";
import fs from "node:fs";
import {
DEFAULT_LLMLINGUA_MODEL,
LLMLINGUA_MODELS,
} from "../../../open-sse/services/compression/engines/llmlingua/constants.ts";
import {
getLlmlinguaModelCacheDir,
resolveLlmlinguaModel,
configureTransformersEnv,
type TransformersEnvLike,
} from "../../../open-sse/services/compression/engines/llmlingua/modelStore.ts";
// ─── tests ────────────────────────────────────────────────────────────────────
describe("llmlingua model registry (constants)", () => {
// ── 1. registry shape ──────────────────────────────────────────────────────
it("LLMLINGUA_MODELS has both proven models and the default is a valid key", () => {
assert.ok(LLMLINGUA_MODELS.tinybert, "tinybert entry must exist");
assert.ok(LLMLINGUA_MODELS["bert-base"], "bert-base entry must exist");
assert.equal(DEFAULT_LLMLINGUA_MODEL, "tinybert");
assert.ok(
Object.prototype.hasOwnProperty.call(LLMLINGUA_MODELS, DEFAULT_LLMLINGUA_MODEL),
"default must be a key of the registry"
);
});
// ── 2. per-entry invariants ─────────────────────────────────────────────────
it("every entry uses WithBERTMultilingual / fp32 / '' subfolder and a sane hfRepo", () => {
for (const [key, entry] of Object.entries(LLMLINGUA_MODELS)) {
assert.equal(entry.factory, "WithBERTMultilingual", `${key}.factory`);
assert.equal(entry.dtype, "fp32", `${key}.dtype`);
assert.equal(entry.subfolder, "", `${key}.subfolder`);
assert.equal(typeof entry.hfRepo, "string", `${key}.hfRepo type`);
assert.ok(entry.hfRepo.length > 0, `${key}.hfRepo non-empty`);
assert.ok(entry.hfRepo.includes("/"), `${key}.hfRepo contains "/"`);
assert.equal(entry.id, key, `${key}.id matches its registry key`);
assert.equal(typeof entry.sizeMB, "number", `${key}.sizeMB type`);
assert.equal(typeof entry.label, "string", `${key}.label type`);
}
});
});
describe("resolveLlmlinguaModel", () => {
// ── 3. resolution + fallback ────────────────────────────────────────────────
it("returns the requested entry for a known id", () => {
const resolved = resolveLlmlinguaModel("bert-base");
assert.equal(resolved.id, "bert-base");
assert.equal(resolved, LLMLINGUA_MODELS["bert-base"]);
});
it("falls back to the default (tinybert) for unknown / undefined / empty ids", () => {
const def = LLMLINGUA_MODELS[DEFAULT_LLMLINGUA_MODEL];
assert.equal(resolveLlmlinguaModel("nonexistent"), def);
assert.equal(resolveLlmlinguaModel(undefined), def);
assert.equal(resolveLlmlinguaModel(null), def);
assert.equal(resolveLlmlinguaModel(""), def);
});
});
describe("getLlmlinguaModelCacheDir", () => {
const originalDataDir = process.env.DATA_DIR;
let tmpDir: string | undefined;
after(() => {
if (originalDataDir === undefined) {
delete process.env.DATA_DIR;
} else {
process.env.DATA_DIR = originalDataDir;
}
if (tmpDir) {
try {
fs.rmSync(tmpDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
} catch {
/* ignore cleanup errors */
}
}
});
// ── 4. path suffix + DATA_DIR honoring ──────────────────────────────────────
it("ends with models/llmlingua and lives under DATA_DIR when set", () => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "llm-"));
process.env.DATA_DIR = tmpDir;
const dir = getLlmlinguaModelCacheDir();
assert.ok(
dir.endsWith(path.join("models", "llmlingua")),
`cache dir should end with models/llmlingua, got: ${dir}`
);
assert.ok(dir.startsWith(tmpDir), `cache dir should be under DATA_DIR, got: ${dir}`);
assert.equal(dir, path.join(tmpDir, "models", "llmlingua"));
});
});
describe("configureTransformersEnv", () => {
// ── 5. Hub default vs local override ────────────────────────────────────────
it("Hub download default: cacheDir set, allowRemoteModels true, no localModelPath", () => {
const env: TransformersEnvLike = {};
configureTransformersEnv(env, {});
assert.equal(typeof env.cacheDir, "string");
assert.ok((env.cacheDir as string).length > 0, "cacheDir must be set");
assert.equal(env.allowRemoteModels, true);
assert.equal(env.localModelPath, undefined);
});
it("local modelPath override: localModelPath set, allowRemoteModels false, cacheDir still set", () => {
const env: TransformersEnvLike = {};
configureTransformersEnv(env, { modelPath: "/some/local/dir" });
assert.equal(env.localModelPath, "/some/local/dir");
assert.equal(env.allowRemoteModels, false);
assert.equal(typeof env.cacheDir, "string");
assert.ok((env.cacheDir as string).length > 0, "cacheDir must still be set");
});
});