import test from "node:test"; import assert from "node:assert/strict"; import path from "node:path"; import { tmpdir } from "node:os"; import { chmod, mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"; import { probeLocationHealth } from "./storageVolumes"; import { HEALTH_TIMING_DEFAULTS } from "./storageHealthTimings"; import { applyHealthTimings } from "./storageHealth"; // Run with: // pnpm --filter yt-dlp-transcript-common exec tsx --test lib/storageHealthProbe.test.ts // // THE HEALTH PROBE: `stat` on a location's root as a CHILD PROCESS, raced // against a timer. No test stalls a real drive: a stalled `stat` is a fake // binary that never answers (a child blocked in the kernel looks the same from // here — it does not exit), and the case that matters is that the answer // arrives on the timer while the child is still running. async function withDir(fn: (dir: string) => Promise): Promise { const dir = await mkdtemp(path.join(tmpdir(), "ttb-health-")); try { await fn(dir); } finally { await rm(dir, { recursive: true, force: true }); } } // A fake `stat`: sleeps `sleepMs` (a blocking sleep, so it is simply not // answering), then prints `out` and exits `code`. async function fakeStat( dir: string, opts: { sleepMs?: number; out?: string; code?: number }, ): Promise { const bin = path.join(dir, "fake-stat.mjs"); await writeFile( bin, `#!/usr/bin/env node if (${opts.sleepMs ?? 0} > 0) { Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ${opts.sleepMs ?? 0}); } process.stdout.write(${JSON.stringify(opts.out ?? "")} + "\\n"); process.exit(${opts.code ?? 0}); `, ); await chmod(bin, 0o755); return bin; } test("the real stat: a directory is ok, a missing path and a file are absent", async () => { await withDir(async (dir) => { const root = path.join(dir, "media"); await mkdir(root); await writeFile(path.join(dir, "a-file"), "x"); assert.equal(await probeLocationHealth({ root }), "ok"); assert.equal(await probeLocationHealth({ root: path.join(dir, "gone") }), "absent"); assert.equal(await probeLocationHealth({ root: path.join(dir, "a-file") }), "absent"); assert.equal(await probeLocationHealth({ root: " " }), "absent"); }); }); test("a child that never answers is 'stalled' on the timer, without waiting for it", async () => { await withDir(async (dir) => { // Twenty seconds asleep: if the probe waited for the child, this test would // take that long. const statBin = await fakeStat(dir, { sleepMs: 20_000, out: "directory" }); const started = Date.now(); const answer = await probeLocationHealth( { root: dir }, { statBin, timeoutMs: 400 }, ); const took = Date.now() - started; assert.equal(answer, "stalled"); assert.ok(took >= 400, `answered after ${took} ms, before the timer`); assert.ok(took < 3_000, `answered after ${took} ms`); }); }); test("the default budget is 3 s", async () => { assert.equal(HEALTH_TIMING_DEFAULTS.probeTimeoutMs, 3_000); await withDir(async (dir) => { const statBin = await fakeStat(dir, { sleepMs: 20_000, out: "directory" }); const started = Date.now(); assert.equal(await probeLocationHealth({ root: dir }, { statBin }), "stalled"); const took = Date.now() - started; assert.ok(took >= 3_000 && took < 6_000, `answered after ${took} ms`); }); }); test("the budget is storage.health.probeTimeoutMs when the caller names none", async () => { applyHealthTimings({ probeTimeoutMs: 500 }); try { await withDir(async (dir) => { const statBin = await fakeStat(dir, { sleepMs: 20_000, out: "directory" }); const started = Date.now(); assert.equal(await probeLocationHealth({ root: dir }, { statBin }), "stalled"); const took = Date.now() - started; assert.ok(took >= 500 && took < 2_500, `answered after ${took} ms`); }); } finally { applyHealthTimings(); } }); test("an answer inside the budget is taken as given", async () => { await withDir(async (dir) => { const slowDir = await fakeStat(dir, { sleepMs: 100, out: "directory" }); assert.equal( await probeLocationHealth({ root: dir }, { statBin: slowDir, timeoutMs: 2_500 }), "ok", ); const aFile = await fakeStat(dir, { out: "regular file" }); assert.equal(await probeLocationHealth({ root: dir }, { statBin: aFile }), "absent"); const missing = await fakeStat(dir, { code: 1 }); assert.equal(await probeLocationHealth({ root: dir }, { statBin: missing }), "absent"); }); }); test("a stat that cannot be started fails open: ok, never stalled", async () => { await withDir(async (dir) => { assert.equal( await probeLocationHealth( { root: dir }, { statBin: path.join(dir, "no-such-stat") }, ), "ok", ); }); });