import { beforeEach, test } from "node:test"; import assert from "node:assert/strict"; import { DriveNotAnsweringError, allLocationHealth, applyHealthTimings, driveCallsInFlight, healthTimings, isDriveNotAnswering, noteLocationDetector, onDrive, onPassIntervalChange, registerLocationHealth, setCounterReader, setDriveCallBudget, locationHealth, notAnsweringText, pruneLocationHealth, recordLocationHealth, resetStorageHealth, sinceText, stalledLocation, stalledLocationForPath, } from "./storageHealth"; import { HEALTH_TIMING_DEFAULTS } from "./storageHealthTimings"; // Run with: // pnpm --filter yt-dlp-transcript-common exec tsx --test lib/storageHealth.test.ts // // The rules the health state keeps (storageHealth.ts's header): one miss stalls // at once, two clean answers in a row clear it, a miss in between starts the // count again, and a new root starts the location over. beforeEach(() => { resetStorageHealth(); applyHealthTimings(); setDriveCallBudget(); setCounterReader(undefined); }); const USB = { id: "usb", label: "USB drive", root: "/mnt/usb/media" }; test("one missed probe marks the location stalled at once", () => { assert.equal(recordLocationHealth(USB, "ok", { now: 1_000 })?.to, "ok"); const t = recordLocationHealth(USB, "stalled", { now: 2_000, cause: "no answer" }); assert.deepEqual(t, { id: "usb", from: "ok", to: "stalled" }); const h = locationHealth("usb"); assert.equal(h?.state, "stalled"); assert.equal(h?.since, 2_000); assert.equal(h?.cause, "no answer"); }); test("a location first seen stalled is stalled", () => { const t = recordLocationHealth(USB, "stalled", { now: 5 }); assert.deepEqual(t, { id: "usb", from: null, to: "stalled" }); assert.equal(stalledLocation(USB)?.since, 5); }); test("one clean probe after a stall does not clear it; two in a row do", () => { assert.equal(HEALTH_TIMING_DEFAULTS.clearAfterCleanPasses, 2); assert.equal(healthTimings().clearAfterCleanPasses, 2); recordLocationHealth(USB, "ok", { now: 0 }); recordLocationHealth(USB, "stalled", { now: 10 }); assert.equal(recordLocationHealth(USB, "ok", { now: 20 }), null); assert.equal(locationHealth("usb")?.state, "stalled"); // `since` stays the stall's start while it lasts. assert.equal(locationHealth("usb")?.since, 10); const t = recordLocationHealth(USB, "ok", { now: 30 }); assert.deepEqual(t, { id: "usb", from: "stalled", to: "ok" }); const h = locationHealth("usb"); assert.equal(h?.state, "ok"); assert.equal(h?.since, 30); assert.equal(h?.cause, undefined); }); test("a miss between two clean probes starts the count again", () => { recordLocationHealth(USB, "stalled", { now: 0 }); recordLocationHealth(USB, "ok", { now: 1 }); assert.equal(recordLocationHealth(USB, "stalled", { now: 2 }), null); // The stall's start is not moved by a second miss. assert.equal(locationHealth("usb")?.since, 0); recordLocationHealth(USB, "ok", { now: 3 }); assert.equal(locationHealth("usb")?.state, "stalled"); recordLocationHealth(USB, "ok", { now: 4 }); assert.equal(locationHealth("usb")?.state, "ok"); }); test("an absent answer is a clean one: an unplugged drive answers at once", () => { recordLocationHealth(USB, "stalled", { now: 0 }); recordLocationHealth(USB, "absent", { now: 1 }); const t = recordLocationHealth(USB, "absent", { now: 2 }); assert.deepEqual(t, { id: "usb", from: "stalled", to: "absent" }); assert.equal(stalledLocation(USB), null); }); test("a re-pointed root starts the location over", () => { recordLocationHealth(USB, "stalled", { now: 0 }); const moved = { ...USB, root: "/mnt/elsewhere/media" }; // The stall belonged to the old root: the new root's lookup is not stalled, // and neither is the old one's (the entry now describes the new root). assert.equal(stalledLocation(moved), null); const t = recordLocationHealth(moved, "ok", { now: 1 }); assert.deepEqual(t, { id: "usb", from: null, to: "ok" }); assert.equal(locationHealth("usb")?.root, "/mnt/elsewhere/media"); assert.equal(stalledLocation(USB), null); }); test("the path gate matches like locationOfDataDir: longest root, strictly under", () => { const parent = { id: "parent", label: "Parent", root: "/mnt/p" }; const child = { id: "child", label: "Child", root: "/mnt/p/archive" }; recordLocationHealth(parent, "stalled", { now: 0 }); recordLocationHealth(child, "ok", { now: 0 }); // A channel on the nested location answers for that location, not its parent. assert.equal(stalledLocationForPath("/mnt/p/archive/chan/data"), null); assert.equal(stalledLocationForPath("/mnt/p/chan/data")?.id, "parent"); // The root itself is not "under" it, and an unrelated path is on nothing. assert.equal(stalledLocationForPath("/mnt/p"), null); assert.equal(stalledLocationForPath("/elsewhere/chan/data"), null); assert.equal(stalledLocationForPath(""), null); }); test("pruning drops locations no longer configured", () => { recordLocationHealth(USB, "stalled", { now: 0 }); recordLocationHealth({ id: "b", label: "B", root: "/b" }, "ok", { now: 0 }); pruneLocationHealth(["b"]); assert.deepEqual(Object.keys(allLocationHealth()), ["b"]); assert.equal(stalledLocationForPath("/mnt/usb/media/x/data"), null); }); test("the state is one map per process, on globalThis", () => { recordLocationHealth(USB, "stalled", { now: 0 }); // A second module copy reads the same object (the house pattern). assert.equal( globalThis.__yttStorageHealth__?.byId.get("usb")?.state, "stalled", ); }); test("the words: since a time today, or a date and time", () => { const now = new Date(2026, 8, 29, 12, 0).getTime(); const today = new Date(2026, 8, 29, 11, 35).getTime(); const yesterday = new Date(2026, 8, 28, 23, 5).getTime(); assert.equal(sinceText(today, now), "since 11:35"); assert.equal(sinceText(yesterday, now), "since 2026-09-28 23:05"); assert.equal(notAnsweringText({ since: today }, now), "not answering since 11:35"); }); // ── the watchdog (`onDrive`) ──────────────────────────────────────────────── // A call that never answers is a promise that never settles: exactly what a // read blocked on a stalled drive looks like from here. No drive is involved. const never = () => new Promise(() => {}); function deferred() { let resolve!: (v: T) => void; let reject!: (e: Error) => void; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve, reject }; } test("a call that answers in time passes through, value or error, and frees its slot", async () => { registerLocationHealth([USB]); assert.equal(await onDrive("/mnt/usb/media/ch/data", async () => 42), 42); await assert.rejects( () => onDrive(USB, async () => { throw new Error("ENOENT"); }), /ENOENT/, ); assert.equal(driveCallsInFlight("usb"), 0); assert.equal(locationHealth("usb")?.state, "ok"); }); test("a call that never answers: stalled on the timer, the location marked at once, the call left to settle", async () => { registerLocationHealth([USB], 0); setDriveCallBudget(80); const late = deferred(); const started = Date.now(); await assert.rejects( () => onDrive("/mnt/usb/media/ch/data", () => late.promise), (err: unknown) => err instanceof DriveNotAnsweringError && isDriveNotAnswering(err) && err.health?.id === "usb" && /^drive not answering \(location "USB drive", since /.test(err.message), ); assert.ok(Date.now() - started < 1_000); const h = locationHealth("usb"); assert.equal(h?.state, "stalled"); assert.ok((h?.since ?? 0) >= started, "since is now, not the entry's first sighting"); assert.match(String(h?.cause), /a read in the editor did not answer within 0.08 s/); // The slot is held until the call really returns. assert.equal(driveCallsInFlight("usb"), 1); late.resolve("finally"); await new Promise((r) => setImmediate(r)); assert.equal(driveCallsInFlight("usb"), 0); }); test("a stalled location is refused without the call being made", async () => { registerLocationHealth([USB]); recordLocationHealth(USB, "stalled"); let made = 0; await assert.rejects( () => onDrive("/mnt/usb/media/ch/data", async () => ++made), DriveNotAnsweringError, ); await assert.rejects(() => onDrive(USB, async () => ++made), DriveNotAnsweringError); assert.equal(made, 0); }); test("at most four calls in flight on a location; the rest wait, and are refused without a call when it stalls", async () => { assert.equal(HEALTH_TIMING_DEFAULTS.inFlightPerLocation, 4); registerLocationHealth([USB]); setDriveCallBudget(80); let made = 0; const calls = Array.from({ length: 7 }, () => onDrive(USB, () => { made += 1; return never(); }).then( () => "answered", (err: Error) => err.name, ), ); await new Promise((r) => setImmediate(r)); assert.equal(made, 4, "four in flight, three waiting"); const outcomes = await Promise.all(calls); assert.deepEqual(outcomes, Array(7).fill("DriveNotAnsweringError")); assert.equal(made, 4, "the three that waited were refused without a call"); assert.equal(locationHealth("usb")?.state, "stalled"); }); test("a waiting call runs when a slot frees, if the location is still answering", async () => { registerLocationHealth([USB]); const gates = Array.from({ length: 4 }, () => deferred()); const first = gates.map((g) => onDrive(USB, () => g.promise)); let fifth = false; const waiting = onDrive(USB, async () => { fifth = true; return 5; }); await new Promise((r) => setImmediate(r)); assert.equal(fifth, false); gates[0].resolve(1); assert.equal(await waiting, 5); for (const g of gates.slice(1)) g.resolve(0); await Promise.all(first); assert.equal(driveCallsInFlight("usb"), 0); }); test("a path on no known location is raced and capped by its root, and names no location", async () => { setDriveCallBudget(80); let made = 0; // Two channels under one hand-typed root share its four slots. const calls = [ ...Array.from({ length: 3 }, () => "/hand/typed/chan-a/data"), ...Array.from({ length: 3 }, () => "/hand/typed/chan-b/data"), ].map((p) => onDrive(p, () => { made += 1; return never(); }).then( () => "answered", (err: DriveNotAnsweringError) => (err.health === null ? "refused" : "marked"), ), ); await new Promise((r) => setImmediate(r)); assert.equal(made, 4, "one root, four slots"); assert.deepEqual(await Promise.all(calls), Array(6).fill("refused")); assert.equal(made, 4); assert.deepEqual(allLocationHealth(), {}); // Every slot is held by a call given up on: the next is refused at once. const started = Date.now(); await assert.rejects(() => onDrive("/hand/typed/chan-c/data", async () => ++made)); assert.ok(Date.now() - started < 50); assert.equal(made, 4); }); test("a probe of another root under a location's id has its own slots and does not rewrite that location", async () => { registerLocationHealth([USB]); setDriveCallBudget(50); // Four candidate probes that never answer: they hold the CANDIDATE root's // four slots, not the location's. for (let i = 0; i < 4; i++) { await assert.rejects( () => onDrive({ ...USB, root: "/mnt/candidate" }, never), DriveNotAnsweringError, ); } assert.equal(locationHealth("usb")?.root, "/mnt/usb/media"); assert.equal(locationHealth("usb")?.state, "ok"); assert.equal(driveCallsInFlight("usb"), 0); // The real location's calls run as if nothing happened. assert.deepEqual( await Promise.all([1, 2, 3, 4, 5].map((n) => onDrive(USB, async () => n))), [1, 2, 3, 4, 5], ); }); test("M1: every slot held by a call given up on — a new call is refused within the budget, after the pass cleared the location", async () => { registerLocationHealth([USB]); setDriveCallBudget(80); const hung = Array.from({ length: 4 }, () => onDrive(USB, never).catch(() => "gave up")); assert.deepEqual(await Promise.all(hung), Array(4).fill("gave up")); assert.equal(locationHealth("usb")?.state, "stalled"); // Two clean answers from the pass (in a reset loop's good moment). recordLocationHealth(USB, "ok"); recordLocationHealth(USB, "ok"); assert.equal(locationHealth("usb")?.state, "ok"); let made = false; const started = Date.now(); await assert.rejects( () => onDrive(USB, async () => { made = true; }), (err: unknown) => err instanceof DriveNotAnsweringError && err.health?.id === "usb", ); assert.ok(Date.now() - started < 80, "refused at once, not after a wait"); assert.equal(made, false); // And the location is marked again: none of the four has returned. assert.equal(locationHealth("usb")?.state, "stalled"); assert.match(String(locationHealth("usb")?.cause), /4 reads on it have not answered/); }); test("M1: every transition to stalled refuses the waiting calls at once, whoever decided it", async () => { registerLocationHealth([USB]); setDriveCallBudget(5_000); const gates = Array.from({ length: 4 }, () => deferred()); const inFlight = gates.map((g) => onDrive(USB, () => g.promise)); const waiting = onDrive(USB, async () => 5).then( () => "ran", (err: Error) => err.name, ); await new Promise((r) => setImmediate(r)); const started = Date.now(); // The pass (not the watchdog) finds the drive stalled. recordLocationHealth(USB, "stalled"); assert.equal(await waiting, "DriveNotAnsweringError"); assert.ok(Date.now() - started < 1_000); for (const g of gates) g.resolve(0); await Promise.all(inFlight); }); test("L6: a call that times out while its disk is still completing requests is slow — refused, the location not marked", async () => { registerLocationHealth([USB]); noteLocationDetector("usb", "counters", "sdz1"); let completed = 100; setCounterReader((device) => { assert.equal(device, "sdz1"); completed += 7; return { completed, inFlight: 2 }; }); setDriveCallBudget(60); // Four slow calls and one waiting behind them. const slow = Array.from({ length: 4 }, () => onDrive(USB, never).then( () => "answered", (err: Error) => err.message, ), ); const waiter = onDrive(USB, async () => 1).then( () => "ran", (err: Error) => err.message, ); const outcomes = await Promise.all(slow); for (const o of outcomes) assert.match(o, /^drive slow/); assert.equal(locationHealth("usb")?.state, "ok", "slow is not stalled"); // Nothing on the drive returns: the waiter's wait runs out — refused, still // without marking. assert.match(await waiter, /nothing on it answered for 0.06 s while a read waited/); assert.equal(locationHealth("usb")?.state, "ok"); // With the counters standing still, the same timeout marks it. setCounterReader(() => ({ completed: 500, inFlight: 2 })); resetStorageHealth(); registerLocationHealth([USB]); noteLocationDetector("usb", "counters", "sdz1"); setCounterReader(() => ({ completed: 500, inFlight: 2 })); await assert.rejects(() => onDrive(USB, never), DriveNotAnsweringError); assert.equal(locationHealth("usb")?.state, "stalled"); }); test("the default budget is 3 s", async () => { assert.equal(HEALTH_TIMING_DEFAULTS.budgetMs, 3_000); assert.equal(healthTimings().budgetMs, 3_000); registerLocationHealth([USB]); const started = Date.now(); await assert.rejects(() => onDrive(USB, never), DriveNotAnsweringError); const took = Date.now() - started; assert.ok(took >= 3_000 && took < 4_500, `answered after ${took} ms`); }); test("registering locations creates entries without an answer, and a moved root starts over", () => { registerLocationHealth([USB], 5); assert.equal(locationHealth("usb")?.state, "ok"); recordLocationHealth(USB, "stalled", { now: 6 }); registerLocationHealth([USB], 7); assert.equal(locationHealth("usb")?.state, "stalled", "registering is not an answer"); registerLocationHealth([{ ...USB, root: "/mnt/new" }], 8); assert.equal(locationHealth("usb")?.state, "ok"); assert.equal(locationHealth("usb")?.root, "/mnt/new"); }); // ── M4: the wait's deadline follows progress ─────────────────────────────── const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); test("M4: a healthy 64-wide walk of units at half the budget — no refusals, nothing marked", async () => { registerLocationHealth([USB]); setDriveCallBudget(100); let answered = 0; const started = Date.now(); const outcomes = await Promise.all( Array.from({ length: 64 }, () => onDrive("/mnt/usb/media/ch/data", async () => { await sleep(50); answered += 1; return "ok"; }).catch((err: Error) => err.message), ), ); // Sixteen rounds of 50 ms: the last call waited about 750 ms, far past the // 100 ms budget, and was not refused — the drive kept answering. assert.ok(Date.now() - started >= 700, `took ${Date.now() - started} ms`); assert.deepEqual(outcomes, Array(64).fill("ok")); assert.equal(answered, 64); assert.equal(locationHealth("usb")?.state, "ok"); assert.equal(driveCallsInFlight("usb"), 0); }); test("M4: the same deep queue on a hand-typed root — no refusals either", async () => { setDriveCallBudget(100); const outcomes = await Promise.all( Array.from({ length: 32 }, () => onDrive("/hand/typed/ch/data", async () => { await sleep(50); return "ok"; }).catch((err: Error) => err.message), ), ); assert.deepEqual(outcomes, Array(32).fill("ok")); }); test("M4: a queue behind four hung calls is still refused within the budget", async () => { setDriveCallBudget(100); // A hand-typed root: nothing marks it, so the refusal is the timeouts'. const hung = Array.from({ length: 4 }, () => onDrive("/hand/typed/ch/data", never).catch(() => "gave up"), ); const started = Date.now(); const waiters = Array.from({ length: 6 }, () => onDrive("/hand/typed/ch/data", async () => "ran").catch((err: Error) => err.name), ); assert.deepEqual(await Promise.all(waiters), Array(6).fill("DriveNotAnsweringError")); assert.ok(Date.now() - started < 400, `refused after ${Date.now() - started} ms`); await Promise.all(hung); // And on a configured location, the timeouts mark it and refuse the queue. registerLocationHealth([USB]); const hungHere = Array.from({ length: 4 }, () => onDrive(USB, never).catch(() => "gave up")); const t0 = Date.now(); const waitersHere = Array.from({ length: 6 }, () => onDrive(USB, async () => "ran").catch((err: Error) => err.name), ); assert.deepEqual(await Promise.all(waitersHere), Array(6).fill("DriveNotAnsweringError")); assert.ok(Date.now() - t0 < 400); assert.equal(locationHealth("usb")?.state, "stalled"); await Promise.all(hungHere); }); test("M4: a call that returns late frees its slot for the calls waiting behind it", async () => { registerLocationHealth([USB]); noteLocationDetector("usb", "counters", "sdz1"); // The counters keep completing, so the late calls are slow, not stalled. let completed = 0; setCounterReader(() => ({ completed: (completed += 5), inFlight: 3 })); setDriveCallBudget(80); // Four calls that take 150 ms: refused as slow at 80 ms, returning at 150. const slow = Array.from({ length: 4 }, () => onDrive(USB, () => sleep(150)).then( () => "answered", (err: Error) => err.message, ), ); // Four more queue at 70 ms, deadline 70 + 80 + 20: the returns at 150 ms // come first and hand them the slots. await sleep(70); const behind = Array.from({ length: 4 }, () => onDrive(USB, async () => "ran").catch((err: Error) => err.message), ); for (const o of await Promise.all(slow)) assert.match(o, /^drive slow/); assert.deepEqual(await Promise.all(behind), Array(4).fill("ran")); assert.equal(locationHealth("usb")?.state, "ok"); // The first return can feed all four waiters; let the other three slow // calls return too, so their releases do not land in the next test's state. await sleep(120); assert.equal(driveCallsInFlight("usb"), 0); }); // ── the overdue refusal: slow or stalled, by the counters ────────────────── test("every slot held by a slow unit on a disk still completing: the next call is refused, nothing marked", async () => { registerLocationHealth([USB]); noteLocationDetector("usb", "counters", "sdz1"); let completed = 0; setCounterReader(() => ({ completed: (completed += 3), inFlight: 4 })); setDriveCallBudget(60); // Four units slower than the budget (they return long after): each is // refused as slow at its timeout, and holds its slot, overdue. const slow = Array.from({ length: 4 }, () => onDrive(USB, never).catch((err: Error) => err.message), ); for (const o of await Promise.all(slow)) assert.match(o, /^drive slow/); let made = false; const started = Date.now(); await assert.rejects( () => onDrive(USB, async () => { made = true; }), (err: unknown) => err instanceof DriveNotAnsweringError && err.health === null && /^drive slow \(4 reads on it are past 0.06 s/.test(err.message), ); assert.ok(Date.now() - started < 60, "refused at once"); assert.equal(made, false); assert.equal(locationHealth("usb")?.state, "ok", "slow, not stalled"); }); test("every slot held by an overdue call on a disk completing nothing: the next call is refused and marks it", async () => { registerLocationHealth([USB]); noteLocationDetector("usb", "counters", "sdz1"); setCounterReader(() => ({ completed: 500, inFlight: 4 })); setDriveCallBudget(60); const hung = Array.from({ length: 4 }, () => onDrive(USB, never).catch(() => "gave up")); await Promise.all(hung); assert.equal(locationHealth("usb")?.state, "stalled"); // The pass clears it; the four have still not returned. recordLocationHealth(USB, "ok"); recordLocationHealth(USB, "ok"); await assert.rejects( () => onDrive(USB, async () => 1), (err: unknown) => err instanceof DriveNotAnsweringError && err.health?.id === "usb", ); assert.equal(locationHealth("usb")?.state, "stalled"); assert.match(String(locationHealth("usb")?.cause), /4 reads on it have not answered/); }); // ── the timings are settings (release 15 slice DT) ───────────────────────── // `applyHealthTimings` takes the stored `settings.storage.health` block, as the // health pass and /storage's save hand it over; `healthTimings()` is what every // number above is read through. test("DT: the applied budget feeds the watchdog — a unit slower than it is refused, and the same unit passes on the default", async () => { registerLocationHealth([USB]); // The settings' floor, 500 ms (a stored 200 clamps to it; storageHealthTimings.test.ts). applyHealthTimings({ budgetMs: 200 }); assert.equal(healthTimings().budgetMs, 500); const unit = () => sleep(700).then(() => "done"); await assert.rejects(() => onDrive(USB, unit), DriveNotAnsweringError); assert.equal(locationHealth("usb")?.state, "stalled"); assert.match(String(locationHealth("usb")?.cause), /did not answer within 0.5 s/); // Back on the defaults (3 s), with the location clear, the same unit answers. await sleep(250); applyHealthTimings(); resetStorageHealth(); registerLocationHealth([USB]); assert.equal(await onDrive(USB, unit), "done"); assert.equal(locationHealth("usb")?.state, "ok"); }); test("DT: the applied cap — with inFlightPerLocation 2, the third call waits for a slot", async () => { registerLocationHealth([USB]); applyHealthTimings({ inFlightPerLocation: 2 }); const gates = Array.from({ length: 2 }, () => deferred()); const first = gates.map((g) => onDrive(USB, () => g.promise)); let third = false; const waiting = onDrive(USB, async () => { third = true; return 3; }); await new Promise((r) => setImmediate(r)); assert.equal(driveCallsInFlight("usb"), 2); assert.equal(third, false, "the third call is queued, not on the drive"); gates[0].resolve(1); assert.equal(await waiting, 3); gates[1].resolve(2); await Promise.all(first); assert.equal(driveCallsInFlight("usb"), 0); }); test("DT: a raised cap admits the calls already waiting; a lowered one is reached as calls return", async () => { registerLocationHealth([USB]); applyHealthTimings({ inFlightPerLocation: 1 }); const gates = Array.from({ length: 3 }, () => deferred()); let made = 0; const calls = gates.map((g) => onDrive(USB, () => { made += 1; return g.promise; }), ); await new Promise((r) => setImmediate(r)); assert.equal(made, 1); // Raised to 3 on a save: the two waiting take the new slots now. applyHealthTimings({ inFlightPerLocation: 3 }); await new Promise((r) => setImmediate(r)); assert.equal(made, 3); assert.equal(driveCallsInFlight("usb"), 3); // Lowered to 1 with three in flight: a fourth call waits, and a return gives // its slot back rather than handing it on while more than one is in flight. applyHealthTimings({ inFlightPerLocation: 1 }); let fourth = false; const late = onDrive(USB, async () => { fourth = true; return 4; }); gates[0].resolve(0); gates[1].resolve(0); await new Promise((r) => setImmediate(r)); assert.equal(fourth, false, "two returns bring three down to one: no slot for the fourth yet"); assert.equal(driveCallsInFlight("usb"), 1); gates[2].resolve(0); assert.equal(await late, 4); await Promise.all(calls); assert.equal(driveCallsInFlight("usb"), 0); }); test("DT: the applied clear count — three clean answers with clearAfterCleanPasses 3, one with 1", () => { applyHealthTimings({ clearAfterCleanPasses: 3 }); recordLocationHealth(USB, "stalled", { now: 0 }); recordLocationHealth(USB, "ok", { now: 1 }); recordLocationHealth(USB, "ok", { now: 2 }); assert.equal(locationHealth("usb")?.state, "stalled", "two are not three"); assert.deepEqual(recordLocationHealth(USB, "ok", { now: 3 }), { id: "usb", from: "stalled", to: "ok", }); applyHealthTimings({ clearAfterCleanPasses: 1 }); recordLocationHealth(USB, "stalled", { now: 4 }); recordLocationHealth(USB, "ok", { now: 5 }); assert.equal(locationHealth("usb")?.state, "ok"); }); test("DT: a changed pass interval is told to the subscribers; the same one, or another timing, is not", () => { const heard: number[] = []; const stop = onPassIntervalChange((ms) => heard.push(ms)); try { applyHealthTimings({ passIntervalMs: 30_000 }); applyHealthTimings({ passIntervalMs: 30_000, budgetMs: 5_000 }); applyHealthTimings(); assert.deepEqual(heard, [30_000, 15_000]); } finally { stop(); } applyHealthTimings({ passIntervalMs: 60_000 }); assert.deepEqual(heard, [30_000, 15_000], "unsubscribed"); }); test("DT: the test seam's budget wins over the applied one, and the timings survive a reset", () => { applyHealthTimings({ budgetMs: 8_000, inFlightPerLocation: 6 }); setDriveCallBudget(80); assert.equal(healthTimings().budgetMs, 80); setDriveCallBudget(); assert.equal(healthTimings().budgetMs, 8_000); resetStorageHealth(); assert.equal(healthTimings().inFlightPerLocation, 6, "configuration, not health"); }); test("DT review L4: a timeout on no known location names the budget the call ran against", async () => { setDriveCallBudget(80); const refused = onDrive("/hand/typed/ch/data", never).then( () => "answered", (err: Error) => err.message, ); // Changed once the call is out (it reads its budget after taking a slot): // its words keep the budget it was given. await new Promise((r) => setImmediate(r)); setDriveCallBudget(5_000); assert.equal(await refused, "drive not answering (a read did not answer within 0.08 s)"); }); test("rootOfUnknownPath strips //media (release 17) and the retired //data", async () => { const { rootOfUnknownPath } = await import("./storageHealth"); assert.equal(rootOfUnknownPath("/mnt/p/chan/media"), "/mnt/p"); assert.equal(rootOfUnknownPath("/mnt/p/chan/media/"), "/mnt/p"); assert.equal(rootOfUnknownPath("/mnt/p/chan/data"), "/mnt/p"); assert.equal(rootOfUnknownPath("/mnt/p/chan/other"), "/mnt/p/chan/other"); });