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 { probeLocation, type VolumeBins } from "./storageVolumes"; import type { StorageLocation } from "./storageLocations"; // THE FAKE FINDMNT. A real one would need a real disk; this one is a node // script that reads a control file next to itself and answers the three // questions probeLocation asks (`-T `, `-S UUID=`, `--fstab -S UUID=`). // Same idea as the e2e fixtures' fake bins (editor/e2e/fixtures/bin), scoped to // one mkdtemp so nothing leaks between tests. const FAKE = `#!/usr/bin/env node import { readFileSync } from "node:fs"; import path from "node:path"; const control = JSON.parse( readFileSync(path.join(import.meta.dirname, "control.json"), "utf8"), ); const argv = process.argv.slice(2); if (control.sleepMs) { // Busy-wait: a sleeping child that ignores SIGTERM is not what we are // testing, and Atomics.wait is the portable blocking sleep. Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, control.sleepMs); } if (argv.includes("--fstab")) { if (!control.fstab) process.exit(1); process.stdout.write(control.fstab + "\\n"); process.exit(0); } if (argv.includes("-S")) { if (!control.uuidTarget) process.exit(1); process.stdout.write(control.uuidTarget + "\\n"); process.exit(0); } if (control.identity === null) process.exit(1); process.stdout.write( JSON.stringify({ filesystems: [control.identity] }) + "\\n", ); `; type Control = { // What `findmnt -J -T ` answers; null = exit 1. identity?: Record | null; // What `findmnt -rn -S UUID=… -o TARGET` answers; absent = exit 1 (nowhere). uuidTarget?: string; // What `findmnt --fstab -S UUID=…` answers; absent = exit 1 (not in fstab). fstab?: string; sleepMs?: number; }; type Harness = { dir: string; bins: VolumeBins; // Directory standing in for /dev/disk/by-uuid. byUuidDir: string; control: (c: Control) => Promise; }; async function withHarness(fn: (h: Harness) => Promise): Promise { const dir = await mkdtemp(path.join(tmpdir(), "ttb-volumes-")); const bin = path.join(dir, "fake-findmnt.mjs"); await writeFile(bin, FAKE); await chmod(bin, 0o755); const byUuidDir = path.join(dir, "by-uuid"); await mkdir(byUuidDir, { recursive: true }); try { await fn({ dir, byUuidDir, bins: { findmntBin: bin, udisksctlBin: path.join(dir, "no-udisksctl") }, control: (c) => writeFile(path.join(dir, "control.json"), JSON.stringify(c)), }); } finally { await rm(dir, { recursive: true, force: true }); } } const UUID = "11111111-2222-3333-4444-555555555555"; function loc(root: string, withVolume = false): StorageLocation { return { id: "platter", label: "Platter", root, autoRepoint: false, ...(withVolume ? { volume: { uuid: UUID, fstype: "ext4", mountpoint: "/mnt/platter", relPath: "archilyzer-media", }, } : {}), }; } test("available: the root is a directory, with identity and free bytes", async () => { await withHarness(async (h) => { const root = path.join(h.dir, "mnt", "platter", "archilyzer-media"); await mkdir(root, { recursive: true }); await h.control({ identity: { target: path.join(h.dir, "mnt", "platter"), fstype: "ext4", label: "PLATTER", uuid: UUID, }, fstab: `UUID=${UUID}`, }); const p = await probeLocation(loc(root), h.bins, { byUuidDir: h.byUuidDir, }); assert.equal(p.status, "available"); assert.equal(p.identity.known, true); assert.equal(p.identity.known && p.identity.uuid, UUID); assert.equal(p.identity.known && p.identity.label, "PLATTER"); // root === join(mountpoint, relPath), the invariant a re-point relies on. assert.equal(p.identity.known && p.identity.relPath, "archilyzer-media"); // NEVER Infinity. getFreeBytes fails open to it (statfs unsupported, a // permissions error, ENOTDIR) and that value does not survive JSON — it // reaches a client component as `null`. Forcing the fail-open needs a // filesystem this test cannot conjure, so the assertion is on the contract: // a freeBytes that is present is a finite number. assert.ok(Number.isFinite(p.freeBytes)); assert.ok((p.freeBytes ?? 0) > 0); // In fstab and not an automount: nothing to warn about. assert.equal(p.warning, undefined); }); }); test("available: an automounted root warns, and names its fstab line", async () => { await withHarness(async (h) => { const root = path.join(h.dir, "auto"); await mkdir(root, { recursive: true }); await h.control({ // udisks mounts under /run/media//. The mountpoint is what // gives it away; the fstab query is not even made. identity: { target: "/run/media/operator/" + UUID, fstype: "ext4", uuid: UUID }, fstab: `UUID=${UUID}`, }); const p = await probeLocation(loc(root), h.bins, { byUuidDir: h.byUuidDir, }); assert.equal(p.status, "available"); assert.match(p.warning ?? "", /automount/); assert.match(p.warning ?? "", new RegExp(`UUID=${UUID} /mnt/platter ext4`)); }); }); test("available: a mount with no fstab entry warns too", async () => { await withHarness(async (h) => { const root = path.join(h.dir, "hand-mounted"); await mkdir(root, { recursive: true }); await h.control({ identity: { target: root, fstype: "ext4", uuid: UUID }, // No `fstab` key: the fake exits 1, as findmnt --fstab does. }); const p = await probeLocation(loc(root), h.bins, { byUuidDir: h.byUuidDir, }); assert.equal(p.status, "available"); assert.match(p.warning ?? "", /may not be present at boot/); }); }); test("mounted-elsewhere: the recorded uuid is up under another mountpoint", async () => { await withHarness(async (h) => { await h.control({ uuidTarget: "/run/media/operator/" + UUID }); const p = await probeLocation( loc(path.join(h.dir, "gone", "archilyzer-media"), true), h.bins, { byUuidDir: h.byUuidDir }, ); assert.equal(p.status, "mounted-elsewhere"); assert.equal( p.candidateRoot, `/run/media/operator/${UUID}/archilyzer-media`, ); // The sighting is live enough to write back as the location's volume. assert.equal(p.identity.known && p.identity.mountpoint, `/run/media/operator/${UUID}`); assert.equal(p.identity.known && p.identity.fstype, "ext4"); assert.equal(p.freeBytes, undefined); }); }); test("unmounted: the disk is attached but nothing has mounted it", async () => { await withHarness(async (h) => { await h.control({}); await writeFile(path.join(h.byUuidDir, UUID), ""); const p = await probeLocation(loc(path.join(h.dir, "gone"), true), h.bins, { byUuidDir: h.byUuidDir, }); assert.equal(p.status, "unmounted"); assert.equal(p.identity.known, false); }); }); test("absent: the uuid is nowhere on this machine", async () => { await withHarness(async (h) => { await h.control({}); const p = await probeLocation(loc(path.join(h.dir, "gone"), true), h.bins, { byUuidDir: h.byUuidDir, }); assert.equal(p.status, "absent"); }); }); test("missing: no root and no identity to look for", async () => { await withHarness(async (h) => { await h.control({}); const p = await probeLocation(loc(path.join(h.dir, "gone")), h.bins, { byUuidDir: h.byUuidDir, }); assert.equal(p.status, "missing"); assert.equal(p.identity.known, false); }); }); test("a findmnt that hangs times out, and the root stays available", async () => { await withHarness(async (h) => { const root = path.join(h.dir, "slow"); await mkdir(root, { recursive: true }); await h.control({ sleepMs: 2_000, identity: { target: root, fstype: "ext4", uuid: UUID }, }); const p = await probeLocation(loc(root), h.bins, { findmntTimeoutMs: 150, byUuidDir: h.byUuidDir, }); // THE POINT: a wedged automounter costs identity, never availability. assert.equal(p.status, "available"); assert.equal(p.identity.known, false); assert.equal(p.warning, undefined); assert.ok((p.freeBytes ?? 0) > 0); }); }); test("no findmnt at all: identity unknown, status still from stat", async () => { await withHarness(async (h) => { const root = path.join(h.dir, "container-bind-mount"); await mkdir(root, { recursive: true }); await h.control({}); const p = await probeLocation( loc(root), { findmntBin: path.join(h.dir, "definitely-not-installed"), udisksctlBin: "x" }, { byUuidDir: h.byUuidDir }, ); // This is the Docker case: no util-linux view of the volume, a perfectly // healthy bind-mounted root. It must never read as unreachable. assert.equal(p.status, "available"); assert.equal(p.identity.known, false); }); }); test("a root that exists but is a file is not available", async () => { await withHarness(async (h) => { const root = path.join(h.dir, "not-a-dir"); await writeFile(root, ""); await h.control({}); const p = await probeLocation(loc(root), h.bins, { byUuidDir: h.byUuidDir, }); assert.equal(p.status, "missing"); }); });