test: coverage campaign and mutation testing across five packages (#628)

Coverage 83.6 to 87.36% lines, 81.63 to 84.14% branches. Mutation testing across five packages: image-engine 85, media-engine 92, doc-engine 87, shared+enterprise 86, apps/api security and jobs slice. Runs all five lanes weekly. Fixes the silently-broken mutation CI (babel pin), a redact-pdf envelope-shape test bug, an untested enterprise license valid-signature path, and an audit test that only exercised a hand-copied reproduction. Test and config only, no product code changes beyond the babel pin and one test-only oidc export. Full suite: 16,712 pass, 0 fail.
This commit is contained in:
SnapOtter
2026-07-24 17:36:57 +08:00
committed by GitHub
parent eee6f0d470
commit 301e6eb01a
129 changed files with 30900 additions and 276 deletions
@@ -1,8 +1,11 @@
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { existsSync } from "node:fs";
import { mkdir, mkdtemp, rm, unlink, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";
import { env } from "../../../apps/api/src/config.js";
import {
assertLocalCapacity,
computeWorkspaceUsedBytes,
isOverWorkspaceCap,
} from "../../../apps/api/src/lib/object-storage.js";
@@ -43,3 +46,93 @@ describe("computeWorkspaceUsedBytes", () => {
expect(await computeWorkspaceUsedBytes(join(root, "nope"))).toBe(0);
});
});
// assertLocalCapacity wires the aggregate size cap and the free-space floor to
// the real WORKSPACE_PATH. This file never calls putObject, so the module's
// 30s workspace-size cache starts empty; each test picks a base timestamp far
// past any prior one so its first check recomputes rather than reusing a stale
// cached total.
describe("assertLocalCapacity capacity guard", () => {
const originalWorkspace = env.WORKSPACE_PATH;
const originalMaxGb = env.MAX_WORKSPACE_SIZE_GB;
let root = "";
let nowBase = 1_000_000_000_000;
afterEach(async () => {
vi.restoreAllMocks();
(env as { WORKSPACE_PATH: string }).WORKSPACE_PATH = originalWorkspace;
(env as { MAX_WORKSPACE_SIZE_GB: number }).MAX_WORKSPACE_SIZE_GB = originalMaxGb;
if (root) await rm(root, { recursive: true, force: true });
root = "";
// Advance the base well past the 30s cache window for the next test.
nowBase += 10 * 60_000;
});
it("returns without error when the workspace root does not exist yet", async () => {
(env as { WORKSPACE_PATH: string }).WORKSPACE_PATH = join(
tmpdir(),
`snapotter-absent-${process.pid}-${Date.now()}`,
);
(env as { MAX_WORKSPACE_SIZE_GB: number }).MAX_WORKSPACE_SIZE_GB = 0.000001;
await expect(assertLocalCapacity()).resolves.toBeUndefined();
});
it("passes when usage is under the configured aggregate cap", async () => {
root = await mkdtemp(join(tmpdir(), "snapotter-cap-under-"));
await mkdir(join(root, "uploads", "job1"), { recursive: true });
await writeFile(join(root, "uploads", "job1", "a.bin"), Buffer.alloc(4096));
(env as { WORKSPACE_PATH: string }).WORKSPACE_PATH = root;
(env as { MAX_WORKSPACE_SIZE_GB: number }).MAX_WORKSPACE_SIZE_GB = 10;
vi.spyOn(Date, "now").mockReturnValue(nowBase);
await expect(assertLocalCapacity()).resolves.toBeUndefined();
});
it("does not enforce the aggregate cap when MAX_WORKSPACE_SIZE_GB is 0", async () => {
root = await mkdtemp(join(tmpdir(), "snapotter-cap-off-"));
await mkdir(join(root, "outputs", "job1"), { recursive: true });
await writeFile(join(root, "outputs", "job1", "big.bin"), Buffer.alloc(2 * 1024 * 1024));
(env as { WORKSPACE_PATH: string }).WORKSPACE_PATH = root;
(env as { MAX_WORKSPACE_SIZE_GB: number }).MAX_WORKSPACE_SIZE_GB = 0;
vi.spyOn(Date, "now").mockReturnValue(nowBase);
// Cap disabled: even a tiny disk must not 503 on the cap path. statfs on a
// real temp dir reports the (ample) host free space, so the floor passes too.
await expect(assertLocalCapacity()).resolves.toBeUndefined();
});
it("throws a 503 when aggregate usage exceeds the cap", async () => {
root = await mkdtemp(join(tmpdir(), "snapotter-cap-over-"));
await mkdir(join(root, "outputs", "job1"), { recursive: true });
// 2 MiB of files; cap of 0.001 GB (~1 MiB) is exceeded.
await writeFile(join(root, "outputs", "job1", "big.bin"), Buffer.alloc(2 * 1024 * 1024));
(env as { WORKSPACE_PATH: string }).WORKSPACE_PATH = root;
(env as { MAX_WORKSPACE_SIZE_GB: number }).MAX_WORKSPACE_SIZE_GB = 0.001;
vi.spyOn(Date, "now").mockReturnValue(nowBase);
await expect(assertLocalCapacity()).rejects.toMatchObject({
statusCode: 503,
message: expect.stringMatching(/storage limit/i),
});
});
it("reuses the cached workspace total within the cache window", async () => {
root = await mkdtemp(join(tmpdir(), "snapotter-cap-cache-"));
await mkdir(join(root, "outputs", "job1"), { recursive: true });
const big = join(root, "outputs", "job1", "big.bin");
await writeFile(big, Buffer.alloc(2 * 1024 * 1024));
(env as { WORKSPACE_PATH: string }).WORKSPACE_PATH = root;
(env as { MAX_WORKSPACE_SIZE_GB: number }).MAX_WORKSPACE_SIZE_GB = 0.001;
// Freeze time so both calls fall inside the 30s window.
vi.spyOn(Date, "now").mockReturnValue(nowBase);
// First call computes the real total (2 MiB) and trips the cap.
await expect(assertLocalCapacity()).rejects.toMatchObject({ statusCode: 503 });
// Delete every file so a fresh recompute would report 0 bytes and pass. The
// second call still trips the cap, proving it read the cached total, not disk.
await unlink(big);
expect(existsSync(big)).toBe(false);
await expect(assertLocalCapacity()).rejects.toMatchObject({ statusCode: 503 });
});
});